Ethereal-dev: [Ethereal-dev] [patch] small speed improvement
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: didier <dgautheron@xxxxxxxx>
Date: Fri, 11 Mar 2005 21:39:07 +0000
Hireassemble.diff : for the common case when packets are in order shortcut a loop. It matters a least for AFP where 200 frames read/write PDU aren't uncommon.
I'll try to do the same for LINK_FRAG.packet.diff: move if (pinfo->in_error_pkt) case in its own function, TRY allocates a lot of space on the stack and call_dissector_work is a recursive function.
Remove all but one volatile.Anyone knows why there's so many volatile declarations? Other than too much copy and paste?
Didier
Index: epan/reassemble.c =================================================================== --- epan/reassemble.c (revision 13695) +++ epan/reassemble.c (working copy) @@ -204,6 +204,21 @@ return TRUE; } +/* ------------------------- */ +static fragment_data *new_head(guint32 flags) +{ + fragment_data *fd_head; + /* head/first structure in list only holds no other data than + * 'datalen' then we don't have to change the head of the list + * even if we want to keep it sorted + */ + fd_head=g_mem_chunk_alloc(fragment_data_chunk); + memset(fd_head, 0, sizeof(fragment_data)); + + fd_head->flags=flags; + return fd_head; +} + /* * For a reassembled-packet hash table entry, free the fragment data * to which the value refers. @@ -580,6 +595,8 @@ fd->next = NULL; fd->flags = 0; fd->frame = pinfo->fd->num; + if (fd->frame > fd_head->frame) + fd_head->frame = fd->frame; fd->offset = frag_offset; fd->len = frag_data_len; fd->data = NULL; @@ -678,6 +695,7 @@ /* check if we have received the entire fragment * this is easy since the list is sorted and the head is faked. + * common case the whole list is scanned. */ max = 0; for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) { @@ -785,9 +803,11 @@ * to anything, and because it doesn't count in any case. */ if (!already_added && check_already_added && fd_head != NULL) { - for(fd_item=fd_head->next;fd_item;fd_item=fd_item->next){ - if(pinfo->fd->num==fd_item->frame){ - already_added=TRUE; + if (pinfo->fd->num <= fd_head->frame) { + for(fd_item=fd_head->next;fd_item;fd_item=fd_item->next){ + if(pinfo->fd->num==fd_item->frame){ + already_added=TRUE; + } } } } @@ -804,20 +824,8 @@ /* not found, this must be the first snooped fragment for this * packet. Create list-head. */ - fd_head=g_mem_chunk_alloc(fragment_data_chunk); + fd_head= new_head(0); - /* head/first structure in list only holds no other data than - * 'datalen' then we don't have to change the head of the list - * even if we want to keep it sorted - */ - fd_head->next=NULL; - fd_head->datalen=0; - fd_head->offset=0; - fd_head->len=0; - fd_head->flags=0; - fd_head->data=NULL; - fd_head->reassembled_in=0; - /* * We're going to use the key to insert the fragment, * so allocate a structure for it, and copy the @@ -899,20 +907,8 @@ /* not found, this must be the first snooped fragment for this * packet. Create list-head. */ - fd_head=g_mem_chunk_alloc(fragment_data_chunk); + fd_head= new_head(0); - /* head/first structure in list only holds no other data than - * 'datalen' then we don't have to change the head of the list - * even if we want to keep it sorted - */ - fd_head->next=NULL; - fd_head->datalen=0; - fd_head->offset=0; - fd_head->len=0; - fd_head->flags=0; - fd_head->data=NULL; - fd_head->reassembled_in=0; - /* * We're going to use the key to insert the fragment, * so allocate a structure for it, and copy the @@ -1248,20 +1244,8 @@ /* not found, this must be the first snooped fragment for this * packet. Create list-head. */ - fd_head=g_mem_chunk_alloc(fragment_data_chunk); - - /* head/first structure in list only holds no other data than - * 'datalen' then we don't have to change the head of the list - * even if we want to keep it sorted - */ - fd_head->next=NULL; - fd_head->datalen=0; - fd_head->offset=0; - fd_head->len=0; - fd_head->flags=FD_BLOCKSEQUENCE; - fd_head->data=NULL; - fd_head->reassembled_in=0; - + fd_head= new_head(FD_BLOCKSEQUENCE); + /* * We're going to use the key to insert the fragment, * so allocate a structure for it, and copy the @@ -1320,20 +1304,8 @@ /* not found, this must be the first snooped fragment for this * packet. Create list-head. */ - fd_head=g_mem_chunk_alloc(fragment_data_chunk); - - /* head/first structure in list only holds no other data than - * 'datalen' then we don't have to change the head of the list - * even if we want to keep it sorted - */ - fd_head->next=NULL; - fd_head->datalen=0; - fd_head->offset=0; - fd_head->len=0; - fd_head->flags=FD_BLOCKSEQUENCE; - fd_head->data=NULL; - fd_head->reassembled_in=0; - + fd_head= new_head(FD_BLOCKSEQUENCE); + /* * We're going to use the key to insert the fragment, * so allocate a structure for it, and copy the @@ -1436,20 +1408,8 @@ /* not found, this must be the first snooped fragment for this * packet. Create list-head. */ - fd_head=g_mem_chunk_alloc(fragment_data_chunk); + fd_head= new_head(FD_BLOCKSEQUENCE); - /* head/first structure in list only holds no other data than - * 'datalen' then we don't have to change the head of the list - * even if we want to keep it sorted - */ - fd_head->next=NULL; - fd_head->datalen=0; - fd_head->offset=0; - fd_head->len=0; - fd_head->flags=FD_BLOCKSEQUENCE; - fd_head->data=NULL; - fd_head->reassembled_in=0; - if ((no_frag_number || frag_802_11_hack) && !more_frags) { /* * This is the last fragment for this packet, and
Index: epan/packet.c =================================================================== --- epan/packet.c (revision 13695) +++ epan/packet.c (working copy) @@ -393,21 +393,18 @@ * the length of the tvbuff pointed to by the argument. */ static int +call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree); + +static int call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo_arg, proto_tree *tree) { - packet_info *volatile pinfo = pinfo_arg; + packet_info *pinfo = pinfo_arg; const char *saved_proto; guint16 saved_can_desegment; - volatile int ret; - gboolean save_writable; - volatile address save_dl_src; - volatile address save_dl_dst; - volatile address save_net_src; - volatile address save_net_dst; - volatile address save_src; - volatile address save_dst; - volatile gint saved_layer_names_len = 0; + int ret; + gint saved_layer_names_len = 0; if (handle->protocol != NULL && !proto_is_protocol_enabled(handle->protocol)) { @@ -453,83 +450,84 @@ } if (pinfo->in_error_pkt) { + ret = call_dissector_work_error(handle, tvb, pinfo, tree); + } else { /* - * This isn't a packet being transported inside - * the protocol whose dissector is calling us, - * it's a copy of a packet that caused an error - * in some protocol included in a packet that - * reports the error (e.g., an ICMP Unreachable - * packet). + * Just call the subdissector. */ + ret = call_dissector_through_handle(handle, tvb, pinfo, tree); + } + if (ret == 0) { /* - * Save the current state of the writability of - * the columns, and restore them after the - * dissector returns, so that the columns - * don't reflect the packet that got the error, - * they reflect the packet that reported the - * error. + * That dissector didn't accept the packet, so + * remove its protocol's name from the list + * of protocols. */ - save_writable = col_get_writable(pinfo->cinfo); - col_set_writable(pinfo->cinfo, FALSE); - save_dl_src = pinfo->dl_src; - save_dl_dst = pinfo->dl_dst; - save_net_src = pinfo->net_src; - save_net_dst = pinfo->net_dst; - save_src = pinfo->src; - save_dst = pinfo->dst; - - /* Dissect the contained packet. */ - TRY { - ret = call_dissector_through_handle(handle, tvb, - pinfo, tree); + if (pinfo->layer_names != NULL) { + g_string_truncate(pinfo->layer_names, + saved_layer_names_len); } - CATCH(BoundsError) { - /* - * Restore the column writability and addresses. - */ - col_set_writable(pinfo->cinfo, save_writable); - pinfo->dl_src = save_dl_src; - pinfo->dl_dst = save_dl_dst; - pinfo->net_src = save_net_src; - pinfo->net_dst = save_net_dst; - pinfo->src = save_src; - pinfo->dst = save_dst; + } + pinfo->current_proto = saved_proto; + pinfo->can_desegment = saved_can_desegment; + return ret; +} - /* - * Restore the current protocol, so any - * "Short Frame" indication reflects that - * protocol, not the protocol for the - * packet that got the error. - */ - pinfo->current_proto = saved_proto; +static int +call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb, + packet_info *pinfo_arg, proto_tree *tree) +{ + packet_info *pinfo = pinfo_arg; + const char *saved_proto; + guint16 saved_can_desegment; + volatile int ret; + gboolean save_writable; + address save_dl_src; + address save_dl_dst; + address save_net_src; + address save_net_dst; + address save_src; + address save_dst; - /* - * Restore the desegmentability state. - */ - pinfo->can_desegment = saved_can_desegment; + saved_proto = pinfo->current_proto; + saved_can_desegment = pinfo->can_desegment; - /* - * Rethrow the exception, so this will be - * reported as a short frame. - */ - RETHROW; - } - CATCH(ReportedBoundsError) { - /* - * "ret" wasn't set because an exception was thrown - * before "call_dissector_through_handle()" returned. - * As it called something, at least one dissector - * accepted the packet, and, as an exception was - * thrown, not only was all the tvbuff dissected, - * a dissector tried dissecting past the end of - * the data in some tvbuff, so we'll assume that - * the entire tvbuff was dissected. - */ - ret = tvb_length(tvb); - } - ENDTRY; + /* + * This isn't a packet being transported inside + * the protocol whose dissector is calling us, + * it's a copy of a packet that caused an error + * in some protocol included in a packet that + * reports the error (e.g., an ICMP Unreachable + * packet). + */ + /* + * Save the current state of the writability of + * the columns, and restore them after the + * dissector returns, so that the columns + * don't reflect the packet that got the error, + * they reflect the packet that reported the + * error. + */ + save_writable = col_get_writable(pinfo->cinfo); + col_set_writable(pinfo->cinfo, FALSE); + save_dl_src = pinfo->dl_src; + save_dl_dst = pinfo->dl_dst; + save_net_src = pinfo->net_src; + save_net_dst = pinfo->net_dst; + save_src = pinfo->src; + save_dst = pinfo->dst; + + /* Dissect the contained packet. */ + TRY { + ret = call_dissector_through_handle(handle, tvb, + pinfo, tree); + } + CATCH(BoundsError) { + /* + * Restore the column writability and addresses. + */ col_set_writable(pinfo->cinfo, save_writable); pinfo->dl_src = save_dl_src; pinfo->dl_dst = save_dl_dst; @@ -537,27 +535,48 @@ pinfo->net_dst = save_net_dst; pinfo->src = save_src; pinfo->dst = save_dst; - pinfo->want_pdu_tracking = 0; - } else { /* - * Just call the subdissector. + * Restore the current protocol, so any + * "Short Frame" indication reflects that + * protocol, not the protocol for the + * packet that got the error. */ - ret = call_dissector_through_handle(handle, tvb, pinfo, tree); - } + pinfo->current_proto = saved_proto; - if (ret == 0) { /* - * That dissector didn't accept the packet, so - * remove its protocol's name from the list - * of protocols. + * Restore the desegmentability state. */ - if (pinfo->layer_names != NULL) { - g_string_truncate(pinfo->layer_names, - saved_layer_names_len); - } + pinfo->can_desegment = saved_can_desegment; + + /* + * Rethrow the exception, so this will be + * reported as a short frame. + */ + RETHROW; } - pinfo->current_proto = saved_proto; - pinfo->can_desegment = saved_can_desegment; + CATCH(ReportedBoundsError) { + /* + * "ret" wasn't set because an exception was thrown + * before "call_dissector_through_handle()" returned. + * As it called something, at least one dissector + * accepted the packet, and, as an exception was + * thrown, not only was all the tvbuff dissected, + * a dissector tried dissecting past the end of + * the data in some tvbuff, so we'll assume that + * the entire tvbuff was dissected. + */ + ret = tvb_length(tvb); + } + ENDTRY; + + col_set_writable(pinfo->cinfo, save_writable); + pinfo->dl_src = save_dl_src; + pinfo->dl_dst = save_dl_dst; + pinfo->net_src = save_net_src; + pinfo->net_dst = save_net_dst; + pinfo->src = save_src; + pinfo->dst = save_dst; + pinfo->want_pdu_tracking = 0; return ret; }
- Prev by Date: [Ethereal-dev] Bug ugly protocol graph
- Next by Date: Re: [Ethereal-dev] Bug ugly protocol graph
- Previous by thread: Re: [Ethereal-dev] Bug ugly protocol graph
- Next by thread: [Ethereal-dev] Better randpkt testing
- Index(es):