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 
__once_init(struct once * once,const char * name,struct lock_class_key * key)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 /*
30  * call_once - Ensure a function has been called exactly once
31  *
32  * @once: Tracking struct
33  * @cb: Function to be called
34  *
35  * If @once has never completed successfully before, call @cb and, if
36  * it returns a zero or positive value, mark @once as completed.  Return
37  * the value returned by @cb
38  *
39  * If @once has completed succesfully before, return 0.
40  *
41  * The call to @cb is implicitly surrounded by a mutex, though for
42  * efficiency the * function avoids taking it after the first call.
43  */
call_once(struct once * once,int (* cb)(struct once *))44 static inline int call_once(struct once *once, int (*cb)(struct once *))
45 {
46 	int r, state;
47 
48 	/* Pairs with atomic_set_release() below.  */
49 	if (atomic_read_acquire(&once->state) == ONCE_COMPLETED)
50 		return 0;
51 
52 	guard(mutex)(&once->lock);
53 	state = atomic_read(&once->state);
54 	if (unlikely(state != ONCE_NOT_STARTED))
55 		return WARN_ON_ONCE(state != ONCE_COMPLETED) ? -EINVAL : 0;
56 
57 	atomic_set(&once->state, ONCE_RUNNING);
58 	r = cb(once);
59 	if (r < 0)
60 		atomic_set(&once->state, ONCE_NOT_STARTED);
61 	else
62 		atomic_set_release(&once->state, ONCE_COMPLETED);
63 	return r;
64 }
65 
66 #endif /* _LINUX_CALL_ONCE_H */
67