jcs's openbsd hax
openbsd
at jcs 164 lines 2.8 kB view raw
1/* Public domain. */ 2 3#ifndef _LINUX_SEQLOCK_H 4#define _LINUX_SEQLOCK_H 5 6#include <sys/types.h> 7#include <sys/mutex.h> 8#include <sys/atomic.h> 9#include <linux/lockdep.h> 10#include <linux/processor.h> 11#include <linux/preempt.h> 12#include <linux/compiler.h> 13 14typedef struct { 15 unsigned int sequence; 16} seqcount_t; 17 18static inline void 19__seqcount_init(seqcount_t *s, const char *name, 20 struct lock_class_key *key) 21{ 22 s->sequence = 0; 23} 24 25static inline void 26seqcount_init(seqcount_t *s) 27{ 28 __seqcount_init(s, NULL, NULL); 29} 30 31static inline unsigned int 32__read_seqcount_begin(const seqcount_t *s) 33{ 34 unsigned int r; 35 for (;;) { 36 r = s->sequence; 37 if ((r & 1) == 0) 38 break; 39 cpu_relax(); 40 } 41 return r; 42} 43 44static inline unsigned int 45read_seqcount_begin(const seqcount_t *s) 46{ 47 unsigned int r = __read_seqcount_begin(s); 48 membar_consumer(); 49 return r; 50} 51 52static inline int 53__read_seqcount_retry(const seqcount_t *s, unsigned start) 54{ 55 return (s->sequence != start); 56} 57 58static inline int 59read_seqcount_retry(const seqcount_t *s, unsigned start) 60{ 61 membar_consumer(); 62 return __read_seqcount_retry(s, start); 63} 64 65static inline void 66write_seqcount_begin(seqcount_t *s) 67{ 68 s->sequence++; 69 membar_producer(); 70} 71 72static inline void 73write_seqcount_end(seqcount_t *s) 74{ 75 membar_producer(); 76 s->sequence++; 77} 78 79static inline unsigned int 80raw_read_seqcount(const seqcount_t *s) 81{ 82 unsigned int r = s->sequence; 83 membar_consumer(); 84 return r; 85} 86 87typedef struct { 88 unsigned int seq; 89 struct mutex lock; 90} seqlock_t; 91 92static inline void 93seqlock_init(seqlock_t *sl, int wantipl) 94{ 95 sl->seq = 0; 96 mtx_init(&sl->lock, wantipl); 97} 98 99static inline void 100write_seqlock(seqlock_t *sl) 101{ 102 mtx_enter(&sl->lock); 103 sl->seq++; 104 membar_producer(); 105} 106 107static inline void 108__write_seqlock_irqsave(seqlock_t *sl) 109{ 110 mtx_enter(&sl->lock); 111 sl->seq++; 112 membar_producer(); 113} 114#define write_seqlock_irqsave(_sl, _flags) do { \ 115 _flags = 0; \ 116 __write_seqlock_irqsave(_sl); \ 117 } while (0) 118 119static inline void 120write_sequnlock(seqlock_t *sl) 121{ 122 membar_producer(); 123 sl->seq++; 124 mtx_leave(&sl->lock); 125} 126 127static inline void 128__write_sequnlock_irqrestore(seqlock_t *sl) 129{ 130 membar_producer(); 131 sl->seq++; 132 mtx_leave(&sl->lock); 133} 134#define write_sequnlock_irqrestore(_sl, _flags) do { \ 135 (void)(_flags); \ 136 __write_sequnlock_irqrestore(_sl); \ 137 } while (0) 138 139static inline unsigned int 140read_seqbegin(seqlock_t *sl) 141{ 142 return READ_ONCE(sl->seq); 143} 144 145static inline unsigned int 146read_seqretry(seqlock_t *sl, unsigned int pos) 147{ 148 return sl->seq != pos; 149} 150 151typedef struct { 152 seqcount_t seq; 153 struct rwlock lock; 154} seqcount_mutex_t; 155 156#define seqcount_mutex_init(s, l) seqcount_init(&(s)->seq) 157 158static inline unsigned int 159seqprop_sequence(const seqcount_mutex_t *sm) 160{ 161 return READ_ONCE(sm->seq.sequence); 162} 163 164#endif