Line data Source code
1 : /* src/threads/atomic.cpp - atomic instructions
2 :
3 : Copyright (C) 2008
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #include <stdint.h>
29 :
30 : #include "threads/atomic.hpp"
31 : #include "threads/mutex.hpp"
32 :
33 : // Gobal mutex for generic atomic instructions.
34 165 : static Mutex lock;
35 :
36 : namespace Atomic {
37 :
38 : /**
39 : * A generic atomic compare and swap for 32-bit integer values. This
40 : * function is using a mutex to provide atomicity.
41 : *
42 : * @param p Pointer to memory address.
43 : * @param oldval Old value to be expected.
44 : * @param newval New value to be stored.
45 : *
46 : * @return value of the memory location before the store
47 : */
48 0 : uint32_t generic_compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
49 : {
50 : uint32_t result;
51 :
52 0 : lock.lock();
53 :
54 : // Do the compare-and-swap.
55 :
56 0 : result = *p;
57 :
58 0 : if (oldval == result)
59 0 : *p = newval;
60 :
61 0 : lock.unlock();
62 :
63 0 : return result;
64 : }
65 :
66 :
67 : /**
68 : * A generic atomic compare and swap for 64-bit integer values. This
69 : * function is using a mutex to provide atomicity.
70 : *
71 : * @param p Pointer to memory address.
72 : * @param oldval Old value to be expected.
73 : * @param newval New value to be stored.
74 : *
75 : * @return value of the memory location before the store
76 : */
77 0 : uint64_t generic_compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
78 : {
79 : uint64_t result;
80 :
81 0 : lock.lock();
82 :
83 : // Do the compare-and-swap.
84 :
85 0 : result = *p;
86 :
87 0 : if (oldval == result)
88 0 : *p = newval;
89 :
90 0 : lock.unlock();
91 :
92 0 : return result;
93 : }
94 :
95 :
96 : /**
97 : * A generic atomic compare and swap for pointer values. This
98 : * function is using a mutex to provide atomicity.
99 : *
100 : * @param p Pointer to memory address.
101 : * @param oldval Old value to be expected.
102 : * @param newval New value to be stored.
103 : *
104 : * @return value of the memory location before the store
105 : */
106 0 : void* generic_compare_and_swap(volatile void** p, void* oldval, void* newval)
107 : {
108 : void* result;
109 :
110 0 : lock.lock();
111 :
112 : // Do the compare-and-swap.
113 :
114 0 : result = (void*) *p;
115 :
116 0 : if (oldval == result)
117 0 : *p = newval;
118 :
119 0 : lock.unlock();
120 :
121 0 : return result;
122 : }
123 :
124 :
125 : /**
126 : * A generic memory barrier. This function is using a mutex to
127 : * provide atomicity.
128 : */
129 0 : void generic_memory_barrier(void)
130 : {
131 0 : lock.lock();
132 0 : lock.unlock();
133 0 : }
134 :
135 : }
136 :
137 : // Legacy C interface.
138 :
139 : extern "C" {
140 0 : uint32_t Atomic_compare_and_swap_32(uint32_t *p, uint32_t oldval, uint32_t newval) { return Atomic::compare_and_swap(p, oldval, newval); }
141 0 : uint64_t Atomic_compare_and_swap_64(uint64_t *p, uint64_t oldval, uint64_t newval) { return Atomic::compare_and_swap(p, oldval, newval); }
142 0 : void* Atomic_compare_and_swap_ptr(void** p, void* oldval, void* newval) { return Atomic::compare_and_swap(p, oldval, newval); }
143 0 : void Atomic_memory_barrier(void) { Atomic::memory_barrier(); }
144 0 : void Atomic_write_memory_barrier(void) { Atomic::write_memory_barrier(); }
145 0 : void Atomic_instruction_barrier(void) { Atomic::instruction_barrier(); }
146 495 : }
147 :
148 :
149 : /*
150 : * These are local overrides for various environment variables in Emacs.
151 : * Please do not remove this and leave it at the end of the file, where
152 : * Emacs will automagically detect them.
153 : * ---------------------------------------------------------------------
154 : * Local variables:
155 : * mode: c++
156 : * indent-tabs-mode: t
157 : * c-basic-offset: 4
158 : * tab-width: 4
159 : * End:
160 : * vim:noexpandtab:sw=4:ts=4:
161 : */
|