(file) Return to once.h CVS log (file) (dir) Up to [OMI] / omi / pal

 1 krisbash 1.1 #ifndef _pal_once_h
 2              #define _pal_once_h
 3              
 4              #include "palcommon.h"
 5              #include "atomic.h"
 6              
 7              #ifdef _MSC_VER
 8              #include <intrin.h>
 9              #endif
10              
11              PAL_BEGIN_EXTERNC
12              
13              typedef struct _Once
14              {
15                  void* value;
16              }
17              Once;
18              
19              #define ONCE_STATE_INVOKING         -2 
20              #define ONCE_STATE_NOTINVOKEDYET    -1
21              
22 krisbash 1.1 #define ONCE_INITIALIZER { (void*)ONCE_STATE_NOTINVOKEDYET }
23              
24              typedef _Success_(return == 0) int (*OnceWorkerFunction)(
25                  _In_ void* data,
26                  _Outptr_result_maybenull_ void** value);
27              
28              int __Once_Invoke(
29                  _Inout_ Once* self,
30                  _In_ OnceWorkerFunction func,
31                  _In_ void* data);
32              
33              PAL_INLINE int Once_Invoke(
34                  _Inout_ Once* self,
35                  _In_ OnceWorkerFunction func,
36                  _In_ void* data)
37              {
38                  int result = 0;
39                  void* value = self->value;
40              
41              /* To prevent confusing behavior, disallow compiler reordering. */
42              #if defined(_MSC_VER)
43 krisbash 1.1     _ReadBarrier();
44              #elif defined(__GNUC__)
45                  asm volatile("" ::: "memory");
46              #else
47                  /* Nothing. */
48              #endif
49              
50                  if ((size_t)value >= (size_t)ONCE_STATE_INVOKING)
51                      result = __Once_Invoke(self, func, data);
52              
53                  return result;
54              }
55              
56              /* All callers to Once_Invoke (except _WithBarrier) must dereference
57               * initialized data through this macro. */
58              #define Once_Invoke_Value(self) ((self)->value)
59              
60              PAL_INLINE int Once_Invoke_WithBarrier(
61                  _Inout_ Once* self,
62                  _In_ OnceWorkerFunction func,
63                  _In_ void* data)
64 krisbash 1.1 {
65                  int result = Once_Invoke(self, func, data);
66              
67                  NonX86MemoryBarrier();
68                  return result;
69              }
70              
71              PAL_END_EXTERNC
72              
73              #endif /* _pal_once_h */

ViewCVS 0.9.2