On Fri, Jul 17, 2020 at 10:28:18PM -0700, Eric Biggers wrote: > I'm still not sure this is the best API. I cast my vote for something along the following lines. It's simple, easily understood and easily used. The approach has two variants: One that returns an integer and one that returns a pointer. I'll use the pointer variant to illustrate. Given a type "T", an object x of type pointer-to-T, and a function "func" that takes various arguments and returns a pointer-to-T, the accepted API for calling func once would be to create once_func() as follows: T *once_func(T **ppt, args...) { static DEFINE_MUTEX(mut); T *p; p = smp_load_acquire(ppt); /* Mild optimization */ if (p) return p; mutex_lock(mut); p = smp_load_acquire(ppt); if (!p) { p = func(args...); if (!IS_ERR_OR_NULL(p)) smp_store_release(ppt, p); } mutex_unlock(mut); return p; } Users then would have to call once_func(&x, args...) and check the result. Different x objects would constitute different "once" domains. (In the integer variant, x, p and the return type of func are all int, and ppt is an int *. Everything else is the same. This variant would be used in cases where you're not allocating anything, you're doing some other sort of initialization only once.) While this would be a perfectly good recipe in itself, the whole thing can be made much simpler for users by creating a MAKE_ONCE_FUNC macro which would generate once_func given the type T, the name "func", and the args. The result is type-safe. IMO the fact that once_func() is not inline is an advantage, not a drawback. Yes, it doesn't actually do any allocation or anything like that -- the idea is that once_func's purpose is merely to ensure that func is successfully called only once. Any memory allocation or other stuff of that sort should be handled by func. In fact, the only drawback I can think of is that because this relies on a single mutex for all the different possible x's, it might lead to locking conflicts (if func had to call once_func() recursively, for example). In most reasonable situations such conflicts would not arise. Alan Stern