1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 /*
  12  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  13  *
  14  * seqlock.h - Definitions of sequence lock algorithm.
  15  *
  16  * Example for reader:
  17  *
  18  * do {
  19  *    int seq = seq_read_begin(&seqlock);
  20  *    ...
  21  * } while (seq_read_retry(&seqlock, seq));
  22  *
  23  */
  24 
  25 #ifndef _SYS_SEQLOCK_H
  26 #define _SYS_SEQLOCK_H
  27 
  28 #ifdef  __cplusplus
  29 extern "C" {
  30 #endif
  31 
  32 #include <sys/types.h>
  33 #include <sys/mutex.h>
  34 #include <sys/atomic.h>           /* for membar_consumer() */
  35 
  36 typedef struct seqlock {
  37         int      sequence;
  38         kmutex_t lock;
  39 } seqlock_t;
  40 
  41 extern void seq_init(seqlock_t *);
  42 extern void seq_destroy(seqlock_t *);
  43 extern int  seq_read_begin(volatile seqlock_t *);
  44 
  45 /*
  46  * Code under seq_write_lock() should be fast and
  47  * must not call sleeping function
  48  */
  49 extern void seq_write_lock(seqlock_t *);
  50 extern void seq_write_unlock(seqlock_t *);
  51 
  52 static boolean_t seq_read_retry(const seqlock_t *seqlock, int seq)
  53 {
  54         membar_consumer();
  55         return (seqlock->sequence != seq);
  56 }
  57 #pragma inline(seq_read_retry)
  58 
  59 #ifdef  __cplusplus
  60 }
  61 #endif
  62 
  63 #endif  /* _SYS_SEQLOCK_H */