Patch for inode SLIST conversion

Michael Neumann mneumann at ntecs.de
Wed Jan 23 05:05:55 PST 2008


Matthew Dillon wrote:
    I think the concept is a perfectly good programming abstraction, though
    I have to again caution that it can result in fairly fragile code.  It's
    definitely not needed for UFS's inode hash because the chain lengths
    are so short.
    Going back to your token patch... lets simplify it.  Get rid of
    lwkt_staleref() and lwkt_initstale() entirely.  Build the semantics
    SOLELY out of lwkt_is_stale().  The definition of lwkt_is_stale() would
    be:
    * Returns 0 if the token in question had not been temporarily acquired
      while we were blocked since our last lwkt_gettoken(), lwkt_gettokref(),
      or lwkt_is_stale() call.
    * Returns non-zero if it was.

    How do you detect the situation?  Really simple I think.  Augment
    the lwkt_token structure with a pointer to the last lwkt_tokref that
    acquired it.  Get rid of the 64 bit generation counter, it isn't needed.
    lwkt_token {
	...
	struct lwkt_tokref *lastref;
    }
    Whenever a token is acquired (_lwkt_gettokref()) is called lastref is
    set to the tokref.  Whenever a token is released lastref is set to NULL.
    The special case of the thread scheduler reacquiring the token with
    lwkt_getalltokens() would NULL the field out if lastref != tokref,
    and otherwise leave the field intact.
    What do you think?
That's the perfect solution!

Patch appended. _lwkt_trytokref needs the same change, as it might 
acquire the token as well. I think setting lastref = NULL in 
lwkt_reltoken is also not absolutely neccessary, but it's not wrong
either, so I did it.

Regards,

  Michael
Index: kern/lwkt_token.c
===================================================================
RCS file: /home/dcvs/src/sys/kern/lwkt_token.c,v
retrieving revision 1.29
diff -u -r1.29 lwkt_token.c
--- kern/lwkt_token.c	27 Dec 2006 06:51:47 -0000	1.29
+++ kern/lwkt_token.c	23 Jan 2008 12:52:51 -0000
@@ -169,6 +169,12 @@
 	}
 	++tok->t_count;
 	refs->tr_state = 1;
+	/*
+	 * Detect the situation where the token was acquired by 
+	 * a different thread while the token was released from
+	 * the current thread due to a blocking condition.  
+ 	 */
+	if (tok->t_lastref != refs) tok->t_lastref = NULL; 
     }
     return (TRUE);
 }
@@ -258,6 +264,7 @@
     /* NOTE: 'td' invalid after loop */
     ++tok->t_globalcount;
 #endif
+    tok->t_lastref = ref;
     ref->tr_state = 1;
 }
 
@@ -313,7 +320,9 @@
     /* NOTE: 'td' invalid after loop */
     ++tok->t_globalcount;
 #endif
+    tok->t_lastref = ref;
     ref->tr_state = 1;
+
     return (TRUE);
 }
 
@@ -351,7 +360,7 @@
  * Release a serializing token
  */
 void
-lwkt_reltoken(lwkt_tokref *ref)
+lwkt_reltoken(lwkt_tokref_t ref)
 {
     struct lwkt_tokref **scanp;
     lwkt_token_t tok;
@@ -371,6 +380,7 @@
     *scanp = ref->tr_next;
     ref->tr_state = 0;
 
+    tok->t_lastref = NULL;
 #ifdef SMP
     if (--tok->t_count == 0) {
 	tok->t_owner = NULL;
@@ -421,6 +431,7 @@
 #else
     tok->t_globalcount = 0;
 #endif
+    tok->t_lastref = NULL;
 }
 
 void
@@ -428,3 +439,19 @@
 {
     /* empty */
 }
+
+int
+lwkt_is_stale(lwkt_tokref_t ref)
+{
+    /* Token is not stale */
+    if (ref->tr_tok->t_lastref == ref) 
+	return 0;
+
+    /*
+     * The token is stale. Reset to not stale so that the next call to 
+     * lwkt_is_stale will return "not stale" unless the token was acquired 
+     * again by a different thread in-between.
+     */
+    ref->tr_tok->t_lastref = ref;
+    return 1;
+}
Index: sys/thread.h
===================================================================
RCS file: /home/dcvs/src/sys/sys/thread.h,v
retrieving revision 1.90
diff -u -r1.90 thread.h
--- sys/thread.h	12 Dec 2007 23:49:24 -0000	1.90
+++ sys/thread.h	23 Jan 2008 12:20:05 -0000
@@ -106,6 +106,7 @@
     struct spinlock	t_spinlock;	/* Controls access */
     struct thread	*t_owner;	/* The current owner of the token */
     int			t_count;	/* Per-thread count */
+    lwkt_tokref_t	*t_lastref;	/* Last tokref that acquired token */ 
 } lwkt_token;
 
 #else
@@ -114,6 +115,7 @@
     struct spinlock	t_unused01;
     struct thread	*t_unused02;
     int			t_globalcount;	/* Global reference count */
+    lwkt_tokref_t	*t_lastref;	/* Last tokref that acquired token */ 
 } lwkt_token;
 
 #endif
@@ -361,6 +363,7 @@
 extern void lwkt_drain_token_requests(void);
 extern void lwkt_token_init(lwkt_token_t);
 extern void lwkt_token_uninit(lwkt_token_t);
+extern int  lwkt_is_stale(lwkt_tokref_t);
 
 extern void lwkt_token_pool_init(void);
 extern lwkt_token_t lwkt_token_pool_get(void *);




More information about the Kernel mailing list