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 */