[SSI] openssi/kernel/cluster/ssi/token tokseq.c,1.11,1.12
Roger Tsang <[email protected]> Tue, 25 Jan 2011 06:04:21 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv24579/cluster/ssi/token
Modified Files:
Tag: OPENSSI-FC
tokseq.c
Log Message:
- insert_queue: always inline.
- tokseq_accept: indicate to compiler unlikely branch direction.
- tokseq_accept: access tqentry structure outside critical section. reduce contention over ts_lock in tokseq structure.
- tokseq_accept: reduce stack usage in local scope.
- tokseq_accept: immediately process items with seqnum 0 which could be items created while TSF_DOWN flag was set. we would see these items if we lost the race with tokseq_cleanup(). fix items stuck in queue.
Index: tokseq.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/tokseq.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- tokseq.c 25 Jan 2011 05:51:26 -0000 1.11
+++ tokseq.c 25 Jan 2011 06:04:19 -0000 1.12
@@ -104,7 +104,7 @@
int tokseq_qlen_found = FALSE;
#endif
-STATIC void
+static inline void
insert_queue(tqentry_t **tqpp, tqentry_t *newtqp, tokseqnum_t base_seq)
{
/* Find insertion point */
@@ -154,16 +154,18 @@
UNLOCK_COND_LOCK(&tsp->ts_lock);
}
-/* Called w. tcb locked (via whatever means).
- * Could be a macro for speed.
+/**
+ * tokseq_accept - process or queue sequenced item
+ *
+ * Process item now if the item is in sequence. Otherwise queue the item.
+ *
+ * Not called with tcb locked. serverfunc() may acquire tcb lock.
*/
-/* SSI_XXX: Not called with tcb locked. serverfunc() may acquire tcb lock. */
void
tokseq_accept(tokseq_t *tsp, int agent, tokseqnum_t recvd,
void (*serverfunc)(void *), void *args, int argsize,
void *(*dupfunc)(void *), void (*freefunc)(void *))
{
- void *save;
tqentry_t *tqp;
SSI_ASSERT(agent > 0 && agent <= tsp->ts_num_conns);
@@ -173,54 +175,58 @@
#endif
LOCK_COND_LOCK(&tsp->ts_lock);
- if (tsp->ts_conns[agent].tsp_flags & TSF_DOWN) {
+ if (unlikely(tsp->ts_conns[agent].tsp_flags & TSF_DOWN)) {
UNLOCK_COND_LOCK(&tsp->ts_lock);
return;
}
- if (recvd != tsp->ts_conns[agent].tsp_expect) {
-
+ /* Special case: all items have seqnum 0 when TSF_DOWN flag was set
+ * during tokseq_getseq() and we lost the race with tokseq_cleanup().
+ * Process those with recvd = 0 immediately.
+ */
+ if (recvd && recvd != tsp->ts_conns[agent].tsp_expect) {
UNLOCK_COND_LOCK(&tsp->ts_lock);
+
+ tqp = KMEM_SLEEP_ALLOC(sizeof(tqentry_t));
+ tqp->tsq_seq = recvd;
+ tqp->tsq_serverfunc = serverfunc;
+ tqp->tsq_freefunc = freefunc;
+ tqp->tsq_argsize = argsize;
if (dupfunc)
- save = (*dupfunc)(args);
+ tqp->tsq_args = (*dupfunc)(args);
else {
/* Queue up this arg */
- save = KMEM_SLEEP_ALLOC(argsize);
- bcopy(args, save, argsize);
+ tqp->tsq_args = KMEM_SLEEP_ALLOC(argsize);
+ bcopy(args, tqp->tsq_args, argsize);
}
- tqp = KMEM_SLEEP_ALLOC(sizeof(tqentry_t));
+
LOCK_COND_LOCK(&tsp->ts_lock);
/* Make sure that node is still up */
- if (tsp->ts_conns[agent].tsp_flags & TSF_DOWN) {
+ if (unlikely(tsp->ts_conns[agent].tsp_flags & TSF_DOWN)) {
UNLOCK_COND_LOCK(&tsp->ts_lock);
- /* free memory */
- KMEM_SLEEP_FREE(tqp, sizeof(tqentry_t));
if (freefunc)
- (*freefunc)(save);
+ (*freefunc)(tqp->tsq_args);
else
- KMEM_SLEEP_FREE(save, argsize);
+ KMEM_SLEEP_FREE(tqp->tsq_args, argsize);
+ KMEM_SLEEP_FREE(tqp, sizeof(tqentry_t));
return;
}
/* If we are now in sequence, since memory allocation,
* free memory and run the server.
*/
if (recvd == tsp->ts_conns[agent].tsp_expect) {
- KMEM_SLEEP_FREE(tqp, sizeof(tqentry_t));
+ UNLOCK_COND_LOCK(&tsp->ts_lock);
if (freefunc)
- (*freefunc)(save);
+ (*freefunc)(tqp->tsq_args);
else
- KMEM_SLEEP_FREE(save, argsize);
+ KMEM_SLEEP_FREE(tqp->tsq_args, argsize);
+ KMEM_SLEEP_FREE(tqp, sizeof(tqentry_t));
goto no_queue;
}
- tqp->tsq_seq = recvd;
- tqp->tsq_args = save;
- tqp->tsq_argsize = argsize;
- tqp->tsq_serverfunc = serverfunc;
- tqp->tsq_freefunc = freefunc;
-
/* Insert operation in sequence order */
- insert_queue(&tsp->ts_conns[agent].tsp_queue, tqp, tsp->ts_conns[agent].tsp_expect);
+ insert_queue(&tsp->ts_conns[agent].tsp_queue, tqp,
+ tsp->ts_conns[agent].tsp_expect);
tsp->ts_conns[agent].tsp_qlen++;
#ifdef DEBUG
tokseq_queue++;
@@ -242,9 +248,8 @@
UNLOCK_COND_LOCK(&tsp->ts_lock);
return;
}
-
-no_queue:
UNLOCK_COND_LOCK(&tsp->ts_lock);
+no_queue:
/* We are in sequence, so just run the server code */
(*serverfunc)(args);
@@ -267,23 +272,12 @@
}
/* Queue not empty and front of queue in sequence */
- while (tsp->ts_conns[agent].tsp_queue &&
- (tsp->ts_conns[agent].tsp_queue->tsq_seq ==
- tsp->ts_conns[agent].tsp_expect)) {
- int curseq;
-
- tqp = tsp->ts_conns[agent].tsp_queue;
-
- curseq = tqp->tsq_seq;
- serverfunc = tqp->tsq_serverfunc;
- args = tqp->tsq_args;
- argsize = tqp->tsq_argsize;
- freefunc = tqp->tsq_freefunc;
-
+ while ((tqp = tsp->ts_conns[agent].tsp_queue)) {
+ if (tqp->tsq_seq != tsp->ts_conns[agent].tsp_expect)
+ break;
/* Remove front of list */
tsp->ts_conns[agent].tsp_queue = tqp->tsq_next;
tsp->ts_conns[agent].tsp_qlen--;
-
UNLOCK_COND_LOCK(&tsp->ts_lock);
#ifdef DEBUG
@@ -293,6 +287,11 @@
(int)tsp, agent);
}
#endif
+ recvd = tqp->tsq_seq;
+ serverfunc = tqp->tsq_serverfunc;
+ freefunc = tqp->tsq_freefunc;
+ args = tqp->tsq_args;
+ argsize = tqp->tsq_argsize;
/* We are in sequence, so just run the server code */
(*serverfunc)(args);
@@ -306,12 +305,12 @@
#ifdef DEBUG
if (tokseq_log)
nsc_log(tsp->ts_logcookie, TOKSEQ_LOG_COMPLETE,
- (int)tsp, (int)agent, (int)curseq,
+ (int)tsp, (int)agent, (int)recvd,
(int)serverfunc, (int)args, (int)argsize, 0);
#endif
LOCK_COND_LOCK(&tsp->ts_lock);
/* Bump sequence number if calling routine didn't already do it */
- if (curseq == tsp->ts_conns[agent].tsp_expect)
+ if (recvd == tsp->ts_conns[agent].tsp_expect)
tsp->ts_conns[agent].tsp_expect++;
}
------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d