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 11 struct once { 12 atomic_t state; 13 struct mutex lock; 14 }; 15 16 static 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) \ 24 do { \ 25 static struct lock_class_key __key; \ 26 __once_init((once), #once, &__key); \ 27 } while (0) 28 29 static 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 */ 46