Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v6.14-rc1 45 lines 1.2 kB view raw
1#ifndef _LINUX_CALL_ONCE_H 2#define _LINUX_CALL_ONCE_H 3 4#include <linux/types.h> 5#include <linux/mutex.h> 6 7#define ONCE_NOT_STARTED 0 8#define ONCE_RUNNING 1 9#define ONCE_COMPLETED 2 10 11struct once { 12 atomic_t state; 13 struct mutex lock; 14}; 15 16static inline void __once_init(struct once *once, const char *name, 17 struct lock_class_key *key) 18{ 19 atomic_set(&once->state, ONCE_NOT_STARTED); 20 __mutex_init(&once->lock, name, key); 21} 22 23#define once_init(once) \ 24do { \ 25 static struct lock_class_key __key; \ 26 __once_init((once), #once, &__key); \ 27} while (0) 28 29static inline void call_once(struct once *once, void (*cb)(struct once *)) 30{ 31 /* Pairs with atomic_set_release() below. */ 32 if (atomic_read_acquire(&once->state) == ONCE_COMPLETED) 33 return; 34 35 guard(mutex)(&once->lock); 36 WARN_ON(atomic_read(&once->state) == ONCE_RUNNING); 37 if (atomic_read(&once->state) != ONCE_NOT_STARTED) 38 return; 39 40 atomic_set(&once->state, ONCE_RUNNING); 41 cb(once); 42 atomic_set_release(&once->state, ONCE_COMPLETED); 43} 44 45#endif /* _LINUX_CALL_ONCE_H */