CACAO
lockword.hpp
Go to the documentation of this file.
1 /* src/threads/lockword.hpp - lockword implementation
2 
3  Copyright (C) 2008-2010
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 #ifndef _LOCKWORD_HPP
27 #define _LOCKWORD_HPP
28 
29 #include "config.h"
30 #include <stdint.h>
31 #include <assert.h>
32 #include "threads/atomic.hpp"
33 
34 /**
35  * Lockword.
36  */
37 class Lockword {
38 private:
39  static const int THIN_LOCK_WORD_SIZE = SIZEOF_VOID_P * 8; // Pointer size multiplied by 8-bit.
40  static const int THIN_LOCK_SHAPE_BIT = 0x01;
41 
42  static const uintptr_t THIN_UNLOCKED = 0;
43 
44  static const int THIN_LOCK_COUNT_SHIFT = 1;
45  static const int THIN_LOCK_COUNT_SIZE = 8;
46  static const int THIN_LOCK_COUNT_INCR = (1 << THIN_LOCK_COUNT_SHIFT);
47  static const int THIN_LOCK_COUNT_MAX = ((1 << THIN_LOCK_COUNT_SIZE) - 1);
48 
50 
53 
54 private:
55  // The actual lockword.
56  uintptr_t& _lockword;
57 
58 public:
59  Lockword(uintptr_t& lockword) : _lockword(lockword) {}
60 
61  void init() { _lockword = THIN_UNLOCKED; } // REMOVEME
62 
63  static inline uintptr_t pre_compute_thinlock(int32_t index);
64 
65  inline bool is_thin_lock () const;
66  inline bool is_fat_lock () const;
67 
68  inline bool is_unlocked() const;
69  inline bool lock (uintptr_t thinlock);
70  inline void unlock ();
71 
72  inline uintptr_t get_thin_lock () const;
73  inline uintptr_t get_thin_lock_without_count() const;
74  inline int32_t get_thin_lock_count () const;
75  inline int32_t get_thin_lock_thread_index () const;
76  inline struct lock_record_t* get_fat_lock () const;
77 
78  inline void set(uintptr_t lockword);
79  inline void set(struct lock_record_t* lr);
80 
81  inline bool is_max_thin_lock_count () const;
82  inline void increase_thin_lock_count();
83  inline void decrease_thin_lock_count();
84 
85  void inflate(struct lock_record_t* lr);
86 };
87 
88 
89 /**
90  * Pre-compute the thin lock value for a thread index.
91  *
92  * @param index The thead index (>= 1).
93  *
94  * @return The thin lock value for this thread index.
95  */
97 {
98  return (index << THIN_LOCK_TID_SHIFT) | THIN_UNLOCKED;
99 }
100 
101 
103 {
104  return ((_lockword & THIN_LOCK_SHAPE_BIT) == 0);
105 }
106 
107 
109 {
110  return ((_lockword & THIN_LOCK_SHAPE_BIT) != 0);
111 }
112 
113 
114 /**
115  * Check if the lockword is an unlocked thin-lock.
116  *
117  * @return true if unlocked, false otherwise.
118  */
120 {
121  return (_lockword == THIN_UNLOCKED);
122 }
123 
124 
125 /**
126  * Try to lock the lockword with the given thin-lock value.
127  *
128  * @param thinlock Thin-lock value to store in the Lockword.
129  *
130  * @return true if lock was successful, false otherwise.
131  */
132 bool Lockword::lock(uintptr_t thinlock)
133 {
134  // Atomically exchange the lockword value.
135  uintptr_t oldlockword = Atomic::compare_and_swap(&_lockword, THIN_UNLOCKED, thinlock);
136 
137  return Lockword(oldlockword).is_unlocked();
138 }
139 
140 
141 /**
142  * Set the lockword to THIN_UNLOCKED.
143  */
145 {
147 }
148 
149 
150 uintptr_t Lockword::get_thin_lock() const
151 {
152  return _lockword;
153 }
154 
155 
157 {
158  return (_lockword & ~THIN_LOCK_COUNT_MASK);
159 }
160 
161 
163 {
164  return (int32_t) (_lockword & THIN_LOCK_COUNT_MASK) >> THIN_LOCK_COUNT_SHIFT;
165 }
166 
167 
169 {
170  return (int32_t) (_lockword >> THIN_LOCK_TID_SHIFT);
171 }
172 
173 
175 {
176  return (struct lock_record_t*) (_lockword & ~THIN_LOCK_SHAPE_BIT);
177 }
178 
179 
180 void Lockword::set(uintptr_t lockword)
181 {
182  _lockword = lockword;
183 }
184 
185 
187 {
188  _lockword = ((uintptr_t) lr) | THIN_LOCK_SHAPE_BIT;
189 }
190 
191 
193 {
195 }
196 
197 
199 {
200  // Sanity check.
202 
204 }
205 
206 
208 {
209  // Sanity check.
210  assert(get_thin_lock_count() > 0);
211 
213 }
214 
215 #endif // _LOCKWORD_HPP
216 
217 
218 /*
219  * These are local overrides for various environment variables in Emacs.
220  * Please do not remove this and leave it at the end of the file, where
221  * Emacs will automagically detect them.
222  * ---------------------------------------------------------------------
223  * Local variables:
224  * mode: c++
225  * indent-tabs-mode: t
226  * c-basic-offset: 4
227  * tab-width: 4
228  * End:
229  * vim:noexpandtab:sw=4:ts=4:
230  */
Lockword(uintptr_t &lockword)
Definition: lockword.hpp:59
std::size_t index
uintptr_t & _lockword
Definition: lockword.hpp:56
T compare_and_swap(T *p, T o, T n)
Definition: atomic.hpp:92
void set(uintptr_t lockword)
Definition: lockword.hpp:180
static const int THIN_LOCK_COUNT_MASK
Definition: lockword.hpp:49
static const int THIN_LOCK_SHAPE_BIT
Definition: lockword.hpp:40
static uintptr_t pre_compute_thinlock(int32_t index)
Pre-compute the thin lock value for a thread index.
Definition: lockword.hpp:96
#define lr
Definition: md-asm.hpp:80
void init()
Definition: lockword.hpp:61
void unlock()
Set the lockword to THIN_UNLOCKED.
Definition: lockword.hpp:144
void decrease_thin_lock_count()
Definition: lockword.hpp:207
int32_t get_thin_lock_thread_index() const
Definition: lockword.hpp:168
static const uintptr_t THIN_UNLOCKED
Definition: lockword.hpp:42
int32_t get_thin_lock_count() const
Definition: lockword.hpp:162
static const int THIN_LOCK_WORD_SIZE
Definition: lockword.hpp:39
uintptr_t get_thin_lock_without_count() const
Definition: lockword.hpp:156
bool lock(uintptr_t thinlock)
Try to lock the lockword with the given thin-lock value.
Definition: lockword.hpp:132
bool is_thin_lock() const
Definition: lockword.hpp:102
void increase_thin_lock_count()
Definition: lockword.hpp:198
bool is_max_thin_lock_count() const
Definition: lockword.hpp:192
static const int THIN_LOCK_COUNT_SIZE
Definition: lockword.hpp:45
static const int THIN_LOCK_TID_SIZE
Definition: lockword.hpp:52
static const int THIN_LOCK_COUNT_SHIFT
Definition: lockword.hpp:44
Lockword.
Definition: lockword.hpp:37
bool is_unlocked() const
Check if the lockword is an unlocked thin-lock.
Definition: lockword.hpp:119
bool is_fat_lock() const
Definition: lockword.hpp:108
static const int THIN_LOCK_TID_SHIFT
Definition: lockword.hpp:51
static const int THIN_LOCK_COUNT_INCR
Definition: lockword.hpp:46
static const int THIN_LOCK_COUNT_MAX
Definition: lockword.hpp:47
void inflate(struct lock_record_t *lr)
Inflate the lock of the given object.
Definition: lockword.cpp:44
struct lock_record_t * get_fat_lock() const
Definition: lockword.hpp:174
uintptr_t get_thin_lock() const
Definition: lockword.hpp:150