diff options
Diffstat (limited to 'include/linux/seqlock.h')
-rw-r--r-- | include/linux/seqlock.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index 1e8a8b6e837d..cf87a24c0f92 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h | |||
@@ -354,6 +354,35 @@ static inline void read_sequnlock_excl(seqlock_t *sl) | |||
354 | spin_unlock(&sl->lock); | 354 | spin_unlock(&sl->lock); |
355 | } | 355 | } |
356 | 356 | ||
357 | /** | ||
358 | * read_seqbegin_or_lock - begin a sequence number check or locking block | ||
359 | * @lock: sequence lock | ||
360 | * @seq : sequence number to be checked | ||
361 | * | ||
362 | * First try it once optimistically without taking the lock. If that fails, | ||
363 | * take the lock. The sequence number is also used as a marker for deciding | ||
364 | * whether to be a reader (even) or writer (odd). | ||
365 | * N.B. seq must be initialized to an even number to begin with. | ||
366 | */ | ||
367 | static inline void read_seqbegin_or_lock(seqlock_t *lock, int *seq) | ||
368 | { | ||
369 | if (!(*seq & 1)) /* Even */ | ||
370 | *seq = read_seqbegin(lock); | ||
371 | else /* Odd */ | ||
372 | read_seqlock_excl(lock); | ||
373 | } | ||
374 | |||
375 | static inline int need_seqretry(seqlock_t *lock, int seq) | ||
376 | { | ||
377 | return !(seq & 1) && read_seqretry(lock, seq); | ||
378 | } | ||
379 | |||
380 | static inline void done_seqretry(seqlock_t *lock, int seq) | ||
381 | { | ||
382 | if (seq & 1) | ||
383 | read_sequnlock_excl(lock); | ||
384 | } | ||
385 | |||
357 | static inline void read_seqlock_excl_bh(seqlock_t *sl) | 386 | static inline void read_seqlock_excl_bh(seqlock_t *sl) |
358 | { | 387 | { |
359 | spin_lock_bh(&sl->lock); | 388 | spin_lock_bh(&sl->lock); |