svn commit: r331660 - head/sys/sys

Mateusz Guzik mjg at FreeBSD.org
Wed Mar 28 04:38:46 UTC 2018


Author: mjg
Date: Wed Mar 28 04:38:45 2018
New Revision: 331660
URL: https://svnweb.freebsd.org/changeset/base/331660

Log:
  seq: provide a comment explaining what seq is for and note 2 caveats

Modified:
  head/sys/sys/seq.h

Modified: head/sys/sys/seq.h
==============================================================================
--- head/sys/sys/seq.h	Wed Mar 28 03:15:42 2018	(r331659)
+++ head/sys/sys/seq.h	Wed Mar 28 04:38:45 2018	(r331660)
@@ -41,26 +41,52 @@ typedef uint32_t seq_t;
 #ifdef _KERNEL
 
 /*
- * Typical usage:
+ * seq allows readers and writers to work with a consistent snapshot. Modifying
+ * operations must be enclosed within a transaction delineated by
+ * seq_write_beg/seq_write_end. The trick works by having the writer increment
+ * the sequence number twice, at the beginning and end of the transaction.
+ * The reader detects that the sequence number has not changed between its start
+ * and end, and that the sequence number is even, to validate consistency.
  *
+ * Some fencing (both hard fencing and compiler barriers) may be needed,
+ * depending on the cpu. Modern AMD cpus provide strong enough guarantees to not
+ * require any fencing by the reader or writer.
+ *
+ * Example usage:
+ *
  * writers:
- * 	lock_exclusive(&obj->lock);
- * 	seq_write_begin(&obj->seq);
- * 	.....
- * 	seq_write_end(&obj->seq);
- * 	unlock_exclusive(&obj->unlock);
+ *     lock_exclusive(&obj->lock);
+ *     seq_write_begin(&obj->seq);
+ *     obj->var1 = ...;
+ *     obj->var2 = ...;
+ *     seq_write_end(&obj->seq);
+ *     unlock_exclusive(&obj->lock);
  *
  * readers:
- * 	obj_t lobj;
- * 	seq_t seq;
+ *    int var1, var2;
+ *    seq_t seq;
  *
- * 	for (;;) {
- * 		seq = seq_read(&gobj->seq);
- * 		lobj = gobj;
- * 		if (seq_consistent(&gobj->seq, seq))
- * 			break;
- * 	}
- * 	foo(lobj);
+ *    for (;;) {
+ *    	      seq = seq_read(&obj->seq);
+ *            var1 = obj->var1;
+ *            var2 = obj->var2;
+ *            if (seq_consistent(&obj->seq, seq))
+ *                   break;
+ *    }
+ *    .....
+ *
+ * Writers may not block or sleep in any way.
+ *
+ * There are 2 minor caveats in this implementation:
+ *
+ * 1. There is no guarantee of progress. That is, a large number of writers can
+ * interfere with the execution of the readers and cause the code to live-lock
+ * in a loop trying to acquire a consistent snapshot.
+ *
+ * 2. If the reader loops long enough, the counter may overflow and eventually
+ * wrap back to its initial value, fooling the reader into accepting the
+ * snapshot.  Given that this needs 4 billion transactional writes across a
+ * single contended reader, it is unlikely to ever happen.
  */		
 
 /* A hack to get MPASS macro */


More information about the svn-src-all mailing list