소스 검색

- tmcb onsend callbacks update (they get also the request or the reply if they
are known when the callback is called)
- added unlikely() when checking if an onsend callback has to be called
(so that the branch will be predicted as untaken)

Andrei Pelinescu-Onciul 18 년 전
부모
커밋
6aa46ec4aa
7개의 변경된 파일99개의 추가작업 그리고 65개의 파일을 삭제
  1. 1 1
      modules/tm/t_cancel.c
  2. 3 2
      modules/tm/t_fwd.c
  3. 8 24
      modules/tm/t_hooks.c
  4. 24 7
      modules/tm/t_hooks.h
  5. 55 28
      modules/tm/t_reply.c
  6. 4 1
      modules/tm/timer.c
  7. 4 2
      modules/tm/uac.c

+ 1 - 1
modules/tm/t_cancel.c

@@ -193,7 +193,7 @@ int cancel_branch( struct cell *t, int branch, int flags )
 	DBG("DEBUG: cancel_branch: sending cancel...\n");
 #ifdef TMCB_ONSEND
 	if (SEND_BUFFER( crb )>=0)
-		run_onsend_callbacks(TMCB_REQUEST_SENT, crb, TMCB_LOCAL_F);
+		run_onsend_callbacks(TMCB_REQUEST_SENT, crb, 0, 0, TMCB_LOCAL_F);
 #else
 	SEND_BUFFER( crb );
 #endif

+ 3 - 2
modules/tm/t_fwd.c

@@ -520,7 +520,7 @@ void e2e_cancel( struct sip_msg *cancel_msg,
 					if (unlikely(has_tran_tmcbs(t_cancel, TMCB_REQUEST_SENT)))
 						run_onsend_callbacks(TMCB_REQUEST_SENT, 
 												&t_cancel->uac[i].request,
-												TMCB_LOCAL_F);
+												cancel_msg, 0, TMCB_LOCAL_F);
 				}
 #endif
 				if (start_retr( &t_cancel->uac[i].request )!=0)
@@ -702,7 +702,8 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
 		return -2;
 	} else {
 #ifdef TMCB_ONSEND
-		run_onsend_callbacks(TMCB_REQUEST_SENT, &uac->request, 0);
+		if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT)))
+			run_onsend_callbacks(TMCB_REQUEST_SENT, &uac->request, p_msg, 0,0);
 #endif
 		/* start retr. only if the send succeeded */
 		if (start_retr( &uac->request )!=0){

+ 8 - 24
modules/tm/t_hooks.c

@@ -271,7 +271,8 @@ void run_trans_callbacks( int type , struct cell *trans,
 
 
 #ifdef TMCB_ONSEND
-void run_onsend_callbacks(int type, struct retr_buf* rbuf, short flags)
+void run_onsend_callbacks(int type, struct retr_buf* rbuf,
+					struct sip_msg* req, struct sip_msg* repl, short flags)
 {
 	struct tmcb_params params;
 	struct cell * trans;
@@ -280,40 +281,23 @@ void run_onsend_callbacks(int type, struct retr_buf* rbuf, short flags)
 	if ( trans==0 || trans->tmcb_hl.first==0 || 
 			((trans->tmcb_hl.reg_types)&type)==0 )
 		return;
-	memset (&params, 0, sizeof(params));
-	params.send_buf.s=rbuf->buffer;
-	params.send_buf.len=rbuf->buffer_len;
-	params.dst=&rbuf->dst;
-	params.flags=flags;
-	params.branch=rbuf->branch;
-	params.t_rbuf=rbuf;
-	params.code=rbuf->activ_type;
+	INIT_TMCB_ONSEND_PARAMS(params, req, repl, rbuf, &rbuf->dst, rbuf->buffer,
+					rbuf->buffer_len, flags, rbuf->branch, rbuf->activ_type);
 	/* req, rpl */
 	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 
-void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
-							int buf_len, struct dest_info* dst, int code,
-							short flags)
+void run_onsend_callbacks2(int type , struct tmcb_params* p)
 {
-	struct tmcb_params params;
 	struct cell * trans;
 
-	trans=rbuf->my_T;
+	if (p->t_rbuf==0) return;
+	trans=p->t_rbuf->my_T;
 	if ( trans==0 || trans->tmcb_hl.first==0 || 
 			((trans->tmcb_hl.reg_types)&type)==0 )
 		return;
-	memset (&params, 0, sizeof(params));
-	params.send_buf.s=buf;
-	params.send_buf.len=buf_len;
-	params.dst=dst;
-	params.flags=flags;
-	params.branch=rbuf->branch;
-	params.t_rbuf=rbuf;
-	params.code=code;
-	/* req, rpl */
-	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, p);
 }
 
 #endif

+ 24 - 7
modules/tm/t_hooks.h

@@ -219,9 +219,8 @@ struct cell;
  *   quasi-simultaneously if multiple ACK copies arrive in parallel or if
  *   ACKs with different (never seen before) to-tags are received.
  *
- *  TMCB_E2ECANCEL_IN -- called when a CANCEL belonging to a proxied
- *  INVITE arrived. Note that if the CANCEL arrives before the INVITE
- *  (out of order) this callback won't be called.
+ *  TMCB_E2ECANCEL_IN -- called when a CANCEL for the INVITE transaction
+ *  for which the callback was registered arrives.
  *   The transaction parameter will point to the invite transaction (and 
  *   not the cancel) and the request parameter to the CANCEL sip msg.
  *
@@ -350,6 +349,24 @@ struct tmcb_params {
 	int code;
 };
 
+#define INIT_TMCB_PARAMS(tmcb, request, reply, r_code)\
+do{\
+	memset(&(tmcb), 0, sizeof((tmcb))); \
+	(tmcb).req=(request); (tmcb).rpl=(reply);  \
+	(tmcb).code=(r_code); \
+}while(0)
+
+#ifdef TMCB_ONSEND
+#define INIT_TMCB_ONSEND_PARAMS(tmcb, req, repl, rbuf, dest, buf, buf_len, \
+								onsend_flags, t_branch, code) \
+do{ \
+	INIT_TMCB_PARAMS(tmcb, req, repl, code); \
+	tmcb.t_rbuf=(rbuf); tmcb.dst=(dest); \
+	tmcb.send_buf.s=(buf); tmcb.send_buf.len=(buf_len); \
+	tmcb.flags=(onsend_flags); tmcb.branch=(t_branch); \
+}while(0)
+#endif
+
 /* callback function prototype */
 typedef void (transaction_cb) (struct cell* t, int type, struct tmcb_params*);
 /* register callback function prototype */
@@ -409,10 +426,10 @@ void run_local_reqin_callbacks( struct cell *trans, struct sip_msg *req,
 		int code );
 
 #ifdef TMCB_ONSEND
-void run_onsend_callbacks(int type, struct retr_buf* rbuf, short flags);
-void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
-							int buf_len, struct dest_info* dst, int code,
-							short flags);
+
+void run_onsend_callbacks(int type, struct retr_buf* rbuf, struct sip_msg* req,
+									struct sip_msg* repl, short flags);
+void run_onsend_callbacks2(int type, struct tmcb_params* p);
 #endif
 
 #endif

+ 55 - 28
modules/tm/t_reply.c

@@ -81,7 +81,7 @@
  * 2007-03-08  membar_write() used in update_totag_set(...)(andrei)
  * 2007-03-15  build_local_ack: removed next_hop and replaced with dst to 
  *              avoid resolving next_hop twice
-*              added TMCB_ONSEND callbacks support for replies & ACKs (andrei)
+ *              added TMCB_ONSEND callbacks support for replies & ACKs (andrei)
  *
  */
 
@@ -102,6 +102,7 @@
 #include "../../data_lump_rpl.h"
 #include "../../usr_avp.h"
 #include "../../atomic_ops.h" /* membar_write() */
+#include "../../compiler_opt.h"
 
 #include "defs.h"
 #include "h_table.h"
@@ -412,6 +413,9 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 	struct retr_buf *rb;
 	unsigned int buf_len;
 	branch_bm_t cancel_bitmap;
+#ifdef TMCB_ONSEND
+	struct tmcb_params onsend_params;
+#endif
 
 	if (!buf)
 	{
@@ -463,11 +467,11 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 	if (code>=200) {
 		if ( is_local(trans) ) {
 			DBG("DEBUG: local transaction completed from _reply\n");
-			if ( has_tran_tmcbs(trans, TMCB_LOCAL_COMPLETED) )
+			if ( unlikely(has_tran_tmcbs(trans, TMCB_LOCAL_COMPLETED)) )
 				run_trans_callbacks( TMCB_LOCAL_COMPLETED, trans,
 					0, FAKED_REPLY, code);
 		} else {
-			if ( has_tran_tmcbs(trans, TMCB_RESPONSE_OUT) )
+			if ( unlikely(has_tran_tmcbs(trans, TMCB_RESPONSE_OUT)) )
 				run_trans_callbacks( TMCB_RESPONSE_OUT, trans,
 					trans->uas.request, FAKED_REPLY, code);
 		}
@@ -494,8 +498,11 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 	} else {
 #ifdef TMCB_ONSEND
 		if (SEND_PR_BUFFER( rb, buf, len )>=0)
-			run_onsend_callbacks2(TMCB_RESPONSE_SENT, rb, buf, len, &rb->dst,
-									code, TMCB_LOCAL_F);
+			if (unlikely(has_tran_tmcbs(trans, TMCB_RESPONSE_SENT))){
+				INIT_TMCB_ONSEND_PARAMS(onsend_params, 0, 0, rb, &rb->dst, 
+								buf, buf_len, TMCB_LOCAL_F, rb->branch, code);
+				run_onsend_callbacks2(TMCB_RESPONSE_SENT, &onsend_params);
+			}
 #else
 		SEND_PR_BUFFER( rb, buf, len );
 #endif
@@ -735,7 +742,7 @@ int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
 	faked_env( t, &faked_req);
 	/* DONE with faking ;-) -> run the failure handlers */
 
-	if ( has_tran_tmcbs( t, TMCB_ON_FAILURE) ) {
+	if (unlikely(has_tran_tmcbs( t, TMCB_ON_FAILURE)) ) {
 		run_trans_callbacks( TMCB_ON_FAILURE, t, &faked_req, rpl, code);
 	}
 	if (t->on_negative) {
@@ -1079,7 +1086,8 @@ int t_retransmit_reply( struct cell *t )
 #ifdef TMCB_ONSEND
 	/* we don't know if it's a retransmission of a local reply or a forwarded
 	 * reply */
-	run_onsend_callbacks(TMCB_RESPONSE_SENT, &t->uas.response, TMCB_RETR_F);
+	run_onsend_callbacks(TMCB_RESPONSE_SENT, &t->uas.response, 0, 0,
+							TMCB_RETR_F);
 #endif
 	DBG("DEBUG: reply retransmitted. buf=%p: %.9s..., shmem=%p: %.9s\n",
 		b, b, t->uas.response.buffer, t->uas.response.buffer );
@@ -1273,6 +1281,9 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 	/* retransmission structure of outbound reply and request */
 	struct retr_buf *uas_rb;
 	str* to_tag;
+#ifdef TMCB_ONSEND
+	struct tmcb_params onsend_params;
+#endif
 
 	/* keep compiler warnings about use of uninit vars silent */
 	res_len=0;
@@ -1306,8 +1317,8 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 		 * be called on; we do not evoke this callback on messages
 		 * stored in shmem -- they are fixed and one cannot change them
 		 * anyway */
-		if (msg_status<300 && branch==relay
-		&& has_tran_tmcbs(t,TMCB_RESPONSE_FWDED) ) {
+		if (unlikely(msg_status<300 && branch==relay
+		&& has_tran_tmcbs(t,TMCB_RESPONSE_FWDED)) ) {
 			run_trans_callbacks( TMCB_RESPONSE_FWDED, t, t->uas.request,
 				p_msg, msg_status );
 		}
@@ -1425,9 +1436,9 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 		t->uas.status = relayed_code;
 		t->relayed_reply_branch = relay;
 
-		if (is_invite(t) && relayed_msg!=FAKED_REPLY
+		if ( unlikely(is_invite(t) && relayed_msg!=FAKED_REPLY
 		&& relayed_code>=200 && relayed_code < 300
-		&& has_tran_tmcbs( t, TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) ) {
+		&& has_tran_tmcbs( t, TMCB_RESPONSE_OUT|TMCB_E2EACK_IN))) {
 			totag_retr=update_totag_set(t, relayed_msg);
 		}
 	}; /* if relay ... */
@@ -1444,14 +1455,19 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 	/* send it now (from the private buffer) */
 	if (relay >= 0) {
 		if (SEND_PR_BUFFER( uas_rb, buf, res_len )>=0){
-			if (!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) ) {
+			if (unlikely(!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT))){
 				run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
 					relayed_msg, relayed_code);
 			}
 #ifdef TMCB_ONSEND
-			run_onsend_callbacks2(TMCB_RESPONSE_SENT, uas_rb, buf, res_len,
-									&uas_rb->dst, relayed_code, 
-									(relayed_msg==FAKED_REPLY)?TMCB_LOCAL_F:0);
+			if (unlikely(has_tran_tmcbs(t, TMCB_RESPONSE_SENT))){
+				INIT_TMCB_ONSEND_PARAMS(onsend_params, t->uas.request,
+									relayed_msg, uas_rb, &uas_rb->dst, buf,
+									res_len,
+									(relayed_msg==FAKED_REPLY)?TMCB_LOCAL_F:0,
+									uas_rb->branch, relayed_code);
+				run_onsend_callbacks2(TMCB_RESPONSE_SENT, &onsend_params);
+			}
 #endif
 		}
 		pkg_free( buf );
@@ -1521,17 +1537,17 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 		}
 		t->uas.status = winning_code;
 		update_reply_stats( winning_code );
-		if (is_invite(t) && winning_msg!=FAKED_REPLY
+		if (unlikely(is_invite(t) && winning_msg!=FAKED_REPLY
 		&& winning_code>=200 && winning_code <300
-		&& has_tran_tmcbs(t,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )  {
+		&& has_tran_tmcbs(t,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) ))  {
 			totag_retr=update_totag_set(t, winning_msg);
 		}
 	}
 	UNLOCK_REPLIES(t);
  
         if (local_winner >= 0 && pass_provisional_replies && winning_code < 200) {
-                if (!totag_retr && has_tran_tmcbs(t, TMCB_LOCAL_RESPONSE_OUT) ) {
-                        DBG("DEBUG: Passing provisional reply %d to FIFO application\n", winning_code);
+			if (unlikely(!totag_retr && 
+							has_tran_tmcbs(t, TMCB_LOCAL_RESPONSE_OUT) )) {
                         run_trans_callbacks( TMCB_LOCAL_RESPONSE_OUT, t, 0,
                                 winning_msg, winning_code);
                 }
@@ -1540,7 +1556,7 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 	if (local_winner>=0 && winning_code>=200 ) {
 		DBG("DEBUG: local transaction completed\n");
 		if (!totag_retr) {
-			if ( has_tran_tmcbs(t,TMCB_LOCAL_COMPLETED) )
+			if (unlikely(has_tran_tmcbs(t,TMCB_LOCAL_COMPLETED) ))
 				run_trans_callbacks( TMCB_LOCAL_COMPLETED, t, 0,
 					winning_msg, winning_code );
 		}
@@ -1588,6 +1604,9 @@ int reply_received( struct sip_msg  *p_msg )
 	int branch_ret;
 	int prev_branch;
 #endif
+#ifdef TMCB_ONSEND
+	struct tmcb_params onsend_params;
+#endif
 
 	/* make sure we know the associated transaction ... */
 	if (t_check( p_msg  , &branch )==-1)
@@ -1633,10 +1652,14 @@ int reply_received( struct sip_msg  *p_msg )
 				if (ack) {
 #ifdef	TMCB_ONSEND
 					if (SEND_PR_BUFFER(&uac->request, ack, ack_len)>=0)
-						run_onsend_callbacks2(TMCB_REQUEST_SENT,
-									&uac->request, ack, ack_len, 
-									&uac->request.dst,
-									TYPE_LOCAL_ACK, TMCB_LOCAL_F);
+						if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT))){ 
+							INIT_TMCB_ONSEND_PARAMS(onsend_params, 
+									t->uas.request, p_msg, &uac->request,
+									&uac->request.dst, ack, ack_len,
+									TMCB_LOCAL_F, branch, TYPE_LOCAL_ACK);
+							run_onsend_callbacks2(TMCB_REQUEST_SENT,
+													&onsend_params);
+						}
 #else
 					SEND_PR_BUFFER(&uac->request, ack, ack_len);
 #endif
@@ -1648,10 +1671,14 @@ int reply_received( struct sip_msg  *p_msg )
 					if (msg_send(&lack_dst, ack, ack_len)<0)
 						LOG(L_ERR, "Error while sending local ACK\n");
 #ifdef	TMCB_ONSEND
-					else
-						run_onsend_callbacks2(TMCB_REQUEST_SENT,
-									&uac->request, ack, ack_len, &lack_dst,
-									TYPE_LOCAL_ACK, TMCB_LOCAL_F);
+					else if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT))){
+							INIT_TMCB_ONSEND_PARAMS(onsend_params, 
+									t->uas.request, p_msg, &uac->request,
+									&lack_dst, ack, ack_len, TMCB_LOCAL_F,
+									branch, TYPE_LOCAL_ACK);
+							run_onsend_callbacks2(TMCB_REQUEST_SENT,
+													&onsend_params);
+					}
 #endif
 					shm_free(ack);
 				}

+ 4 - 1
modules/tm/timer.c

@@ -127,6 +127,7 @@
 #include "../../parser/parser_f.h"
 #include "../../ut.h"
 #include "../../timer_ticks.h"
+#include "../../compiler_opt.h"
 #include "t_funcs.h"
 #include "t_reply.h"
 #include "t_cancel.h"
@@ -308,7 +309,9 @@ inline static ticks_t retransmission_handler( struct retr_buf *r_buf )
 				return (ticks_t)-1;
 			}
 #ifdef TMCB_ONSEND
-			run_onsend_callbacks(TMCB_REQUEST_SENT, r_buf, TMCB_RETR_F);
+			if (unlikely(has_tran_tmcbs(r_buf->my_T, TMCB_REQUEST_SENT))) 
+				run_onsend_callbacks(TMCB_REQUEST_SENT, r_buf, 
+										0, 0, TMCB_RETR_F);
 #endif
 	} else {
 #ifdef EXTRA_DEBUG

+ 4 - 2
modules/tm/uac.c

@@ -66,6 +66,7 @@
 #include "../../crc.h"
 #include "../../ip_addr.h"
 #include "../../socket_info.h"
+#include "../../compiler_opt.h"
 #include "ut.h"
 #include "h_table.h"
 #include "t_hooks.h"
@@ -353,9 +354,10 @@ static inline void send_prepared_request_impl(struct retr_buf *request, int retr
 		LOG(L_ERR, "t_uac: Attempt to send to precreated request failed\n");
 	}
 #ifdef TMCB_ONSEND
-	else
+	else if (unlikely(has_tran_tmcbs(request->my_T, TMCB_REQUEST_SENT)))
 		/* we don't know the method here */
-		run_onsend_callbacks(TMCB_REQUEST_SENT, request, TMCB_LOCAL_F);
+			run_onsend_callbacks(TMCB_REQUEST_SENT, request, 0, 0,
+									TMCB_LOCAL_F);
 #endif
 	
 	if (retransmit && (start_retr(request)!=0))