ClanLib  2.3.7
interlocked_variable.h
Go to the documentation of this file.
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2011 The ClanLib Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries ClanLib may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Magnus Norddahl
27 */
28 
31 
32 #pragma once
33 
34 #include "../api_core.h"
35 #include "system.h"
36 
37 #ifdef WIN32
38 #include <windows.h>
39 #else
40 #include "../System/cl_platform.h"
41 #endif
42 
43 // __sync_val_compare_and_swap was not introduced until gcc 4.1
44 #if defined(WIN32) || __GNUC__ > 4 || (__GNUC__ == 4 & __GNUC_MINOR__ >= 1)
45 
49 class CL_InterlockedVariable
50 {
51 public:
52 #ifdef WIN32
53  CL_InterlockedVariable()
54  : val((LONG*)CL_System::aligned_alloc(sizeof(LONG), 4))
55  {
56  set(0);
57  }
58 
59  CL_InterlockedVariable(const CL_InterlockedVariable &src)
60  : val((LONG*)CL_System::aligned_alloc(sizeof(LONG), 4))
61  {
62  set(src.get());
63  }
64 
65  ~CL_InterlockedVariable()
66  {
67  CL_System::aligned_free((void*)val);
68  }
69 
70  CL_InterlockedVariable &operator =(const CL_InterlockedVariable &src)
71  {
72  set(src.get());
73  return *this;
74  }
75 
76  LONG get() const
77  {
78  return InterlockedCompareExchange(val, 0, 0);
79  }
80 
81  void set(LONG new_value)
82  {
83  InterlockedExchange(val, new_value);
84  }
85 
86  LONG increment()
87  {
88  return InterlockedIncrement(val);
89  }
90 
91  LONG decrement()
92  {
93  return InterlockedDecrement(val);
94  }
95 
96  bool compare_and_swap(LONG expected_value, LONG new_value)
97  {
98  return InterlockedCompareExchange(val, new_value, expected_value) == expected_value;
99  }
100 
101 private:
102  volatile LONG *val;
103 
104 #else
105  CL_InterlockedVariable()
106  : val((cl_byte32*)CL_System::aligned_alloc(sizeof(cl_byte32), 4))
107  {
108  set(0);
109  }
110 
111  CL_InterlockedVariable(const CL_InterlockedVariable &src)
112  : val((cl_byte32*)CL_System::aligned_alloc(sizeof(cl_byte32), 4))
113  {
114  set(src.get());
115  }
116 
117  ~CL_InterlockedVariable()
118  {
119  CL_System::aligned_free((void*)val);
120  }
121 
122  CL_InterlockedVariable &operator =(const CL_InterlockedVariable &src)
123  {
124  set(src.get());
125  return *this;
126  }
127 
128  int get() const
129  {
130  return __sync_val_compare_and_swap(val, 0, 0);
131  }
132 
133  void set(int new_value)
134  {
135  __sync_lock_test_and_set(val, new_value);
136  }
137 
138  int increment()
139  {
140  return __sync_add_and_fetch(val, 1);
141  }
142 
143  int decrement()
144  {
145  return __sync_sub_and_fetch(val, 1);
146  }
147 
148  bool compare_and_swap(int expected_value, int new_value)
149  {
150  return __sync_bool_compare_and_swap(val, expected_value, new_value);
151  }
152 
153 private:
154  volatile cl_byte32 *val;
155 
156 #endif
157 };
158 
159 #endif
160