root/src/utils/noit_atomic.h

Revision 1452e3302fd8c2b4ded895773bf38dc163b2d914, 2.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

add some x86 and x86_64 atomic support

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #ifndef UTILS_NOIT_ATOMIC_H
7 #define UTILS_NOIT_ATOMIC_H
8
9 #include "noit_config.h"
10
11 typedef int32_t noit_atomic_t;
12 typedef int64_t noit_atomic64_t;
13
14 #ifdef HAVE_LIBKERN_OSATOMIC_H
15 /*
16  * This secion is for Darwin.
17  * And we simply don't run on 32bit PPC.  Life's a bitch.
18  */
19 #include <libkern/OSAtomic.h>
20 typedef OSSpinLock noit_spinlock_t;
21 #define noit_atomic_cas32 OSAtomicCompareAndSwap32
22 #define noit_atomic_cas64 OSAtomicCompareAndSwap64
23 #define noit_atomic_inc32 OSAtomicIncrement32
24 #define noit_atomic_inc64 OSAtomicIncrement64
25 #define noit_atomic_dec32 OSAtomicDecrement32
26 #define noit_atomic_dec64 OSAtomicDecrement64
27 #define noit_spinlock_lock OSSpinLockLock
28 #define noit_spinlock_unlock OSSpinLockUnlock
29 #define noit_spinlock_trylock OSSpinLockTry
30 #elif defined(__GNUC__)
31
32 typedef u_int32_t noit_atomic32_t
33 typedef u_int64_t noit_atomic64_t
34
35 #if (SIZEOF_VOID_P == 4)
36 #define noit_atomic_casptr(a,b,c) noit_atomic_cas32((a),(void *)(b),(void *)(c))
37 #elif (SIZEOF_VOID_P == 8)
38 #define noit_atomic_casptr(a,b,c) noit_atomic_cas64((a),(void *)(b),(void *)(c))
39 #else
40 #error unsupported pointer width
41 #endif
42
43 static inline noit_atomic32_t
44 noit_atomic_cas32(volatile noit_atomic32_t *ptr
45                   volatile noit_atomic32_t rpl,
46                   volatile noit_atomic32_t curr) {
47   noit_atomic32_t prev;
48   __asm__ volatile (
49       "lock; cmpxchgl %1, %2"
50     : "=a" (prev)
51     : "r"  (rpl), "m" (*(ptr)), "0" (curr)
52     : "memory");
53   return prev;
54 }
55
56 #ifdef __x86_64__
57 static inline noit_atomic64_t
58 noit_atomic_cas64(volatile noit_atomic64_t *ptr
59                   volatile noit_atomic64_t rpl,
60                   volatile noit_atomic64_t curr) {
61   noit_atomic64_t prev;
62   __asm__ volatile (
63       "lock; cmpxchgq %1, %2"
64     : "=a" (prev)
65     : "r"  (rpl), "m" (*(ptr)), "0" (curr)
66     : "memory");
67   return prev;
68 }
69 #else
70 static inline noit_atomic64_t
71 noit_atomic_cas64(volatile noit_atomic64_t *ptr
72                   volatile noit_atomic64_t rpl,
73                   volatile noit_atomic64_t curr) {
74   noit_atomic64_t prev;
75   __asm__ volatile (
76       "pushl %%ebx;"
77       "mov 4+%1,%%ecx;"
78       "mov %1,%%ebx;"
79       "lock;"
80       "cmpxchg8b (%3);"
81       "popl %%ebx"
82     : "=A" (prev)
83     : "m" (rpl), "A" (curr), "r" (ptr)
84     : "%ebx", "%ecx", "memory");
85   return prev;
86 };
87 #endif
88
89 #else
90 #error Please stub out the atomics section for your platform
91 #endif
92
93 #endif
Note: See TracBrowser for help on using the browser.