1/* Copyright 2016 Google Inc.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License. */
14
15#ifndef NSYNC_PUBLIC_NSYNC_ONCE_H_
16#define NSYNC_PUBLIC_NSYNC_ONCE_H_
17
18#include <inttypes.h>
19#include "nsync_cpp.h"
20#include "nsync_atomic.h"
21
22NSYNC_CPP_START_
23
24/* An nsync_once allows a function to be called exactly once, when first referenced. */
25typedef nsync_atomic_uint32_ nsync_once;
26
27/* An initializer for nsync_once; it is guaranteed to be all zeroes. */
28#define NSYNC_ONCE_INIT NSYNC_ATOMIC_UINT32_INIT_
29
30/* The first time nsync_run_once() or nsync_run_once_arg() is applied to *once,
31 the supplied function is run (with argument, in the case of nsync_run_once_arg()).
32 Other callers will wait until the run of the function is complete, and then
33 return without running the function again. */
34void nsync_run_once (nsync_once *once, void (*f) (void));
35void nsync_run_once_arg (nsync_once *once, void (*farg) (void *arg), void *arg);
36
37/* Same as nsync_run_once()/nsync_run_once_arg() but uses a spinloop.
38 Can be used on the same nsync_once as nsync_run_once/nsync_run_once_arg().
39
40 These *_spin variants should be used only in contexts where normal blocking
41 is disallowed, such as within user-space schedulers, when the runtime is
42 not fully initialized, etc. They provide no significant performance benefit,
43 and they should be avoided in normal code. */
44void nsync_run_once_spin (nsync_once *once, void (*f) (void));
45void nsync_run_once_arg_spin (nsync_once *once, void (*farg) (void *arg), void *arg);
46
47NSYNC_CPP_END_
48
49#endif /*NSYNC_PUBLIC_NSYNC_ONCE_H_*/
50