InnoDB Plugin  1.0
os0once.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
27 #ifndef os0once_h
28 #define os0once_h
29 
30 #include "univ.i"
31 
32 #include "os0sync.h"
33 #include "ut0ut.h"
34 
56 class os_once {
57 public:
59  typedef ib_uint32_t state_t;
60 
62  static const state_t NEVER_DONE = 0;
63 
65  static const state_t IN_PROGRESS = 1;
66 
68  static const state_t DONE = 2;
69 
70 #ifdef HAVE_ATOMIC_BUILTINS
71 
76  static
77  void
78  do_or_wait_for_done(
79  volatile state_t* state,
80  void (*do_func)(void*),
81  void* do_func_arg)
82  {
83  /* Avoid calling os_compare_and_swap_uint32() in the most
84  common case. */
85  if (*state == DONE) {
86  return;
87  }
88 
89  if (os_compare_and_swap_uint32(state,
91  /* We are the first. Call the function. */
92 
93  do_func(do_func_arg);
94 
95  const bool swapped = os_compare_and_swap_uint32(
96  state, IN_PROGRESS, DONE);
97 
98  ut_a(swapped);
99  } else {
100  /* The state is not NEVER_DONE, so either it is
101  IN_PROGRESS (somebody is calling the function right
102  now or DONE (it has already been called and completed).
103  Wait for it to become DONE. */
104  for (;;) {
105  const state_t s = *state;
106 
107  switch (s) {
108  case DONE:
109  return;
110  case IN_PROGRESS:
111  break;
112  case NEVER_DONE:
113  /* fall through */
114  default:
115  ut_error;
116  }
117 
118  UT_RELAX_CPU();
119  }
120  }
121  }
122 #endif /* HAVE_ATOMIC_BUILTINS */
123 };
124 
125 #endif /* os0once_h */