Multi-core Hash Joins
Main-memory hash join implementations for multi-core CPUs
lock.h
1/*
2 Copyright 2011, Spyros Blanas.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef LOCK_H
19#define LOCK_H
20
21typedef volatile char Lock_t;
22
23inline void unlock(Lock_t * _l) __attribute__((always_inline));
24inline void lock(Lock_t * _l) __attribute__((always_inline));
25inline int tas(volatile char * lock) __attribute__((always_inline));
26
27/*
28 * Non-recursive spinlock. Using `xchg` and `ldstub` as in PostgresSQL.
29 */
30/* Call blocks and retunrs only when it has the lock. */
31inline void lock(Lock_t * _l) {
32 while(tas(_l)) {
33#if defined(__i386__) || defined(__x86_64__)
34 __asm__ __volatile__ ("pause\n");
35#endif
36 }
37}
38
40inline void unlock(Lock_t * _l) {
41 *_l = 0;
42}
43
44inline int tas(volatile char * lock)
45{
46// `register` is deprecated in c++17
47#if __cplusplus >= 201703L
48 char res = 1;
49#else
50 register char res = 1;
51#endif // __cplusplus >= 201703L
52#if defined(__i386__) || defined(__x86_64__)
53 __asm__ __volatile__ (
54 "lock xchgb %0, %1\n"
55 : "+q"(res), "+m"(*lock)
56 :
57 : "memory", "cc");
58#elif defined(__sparc__)
59 __asm__ __volatile__ (
60 "ldstub [%2], %0"
61 : "=r"(res), "+m"(*lock)
62 : "r"(lock)
63 : "memory");
64#else
65#error TAS not defined for this architecture.
66#endif
67 return res;
68}
69
70#endif /* LOCK_H */