Changeset 53ee27e for libcfa/src/bits
- Timestamp:
- Aug 4, 2020, 5:13:51 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- eafec07
- Parents:
- 3f850d7 (diff), 21b0a23 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- libcfa/src/bits
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/debug.hfa
r3f850d7 r53ee27e 15 15 16 16 #pragma once 17 18 #include <assert.h> 17 19 18 20 #ifdef __CFA_DEBUG__ -
libcfa/src/bits/defs.hfa
r3f850d7 r53ee27e 16 16 #pragma once 17 17 18 #include <stdbool.h>19 #include <stddef.h>20 18 #include <stdint.h> 21 19 … … 54 52 return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); 55 53 } 56 57 // #define __CFA_NO_BIT_TEST_AND_SET__58 59 #if defined( __i386 )60 static inline bool __atomic_bts(volatile unsigned long int * target, unsigned long int bit ) {61 #if defined(__CFA_NO_BIT_TEST_AND_SET__)62 unsigned long int mask = 1ul << bit;63 unsigned long int ret = __atomic_fetch_or(target, mask, (int)__ATOMIC_RELAXED);64 return (ret & mask) != 0;65 #else66 int result = 0;67 asm volatile(68 "LOCK btsl %[bit], %[target]\n\t"69 : "=@ccc" (result)70 : [target] "m" (*target), [bit] "r" (bit)71 );72 return result != 0;73 #endif74 }75 76 static inline bool __atomic_btr(volatile unsigned long int * target, unsigned long int bit ) {77 #if defined(__CFA_NO_BIT_TEST_AND_SET__)78 unsigned long int mask = 1ul << bit;79 unsigned long int ret = __atomic_fetch_and(target, ~mask, (int)__ATOMIC_RELAXED);80 return (ret & mask) != 0;81 #else82 int result = 0;83 asm volatile(84 "LOCK btrl %[bit], %[target]\n\t"85 :"=@ccc" (result)86 : [target] "m" (*target), [bit] "r" (bit)87 );88 return result != 0;89 #endif90 }91 #elif defined( __x86_64 )92 static inline bool __atomic_bts(volatile unsigned long long int * target, unsigned long long int bit ) {93 #if defined(__CFA_NO_BIT_TEST_AND_SET__)94 unsigned long long int mask = 1ul << bit;95 unsigned long long int ret = __atomic_fetch_or(target, mask, (int)__ATOMIC_RELAXED);96 return (ret & mask) != 0;97 #else98 int result = 0;99 asm volatile(100 "LOCK btsq %[bit], %[target]\n\t"101 : "=@ccc" (result)102 : [target] "m" (*target), [bit] "r" (bit)103 );104 return result != 0;105 #endif106 }107 108 static inline bool __atomic_btr(volatile unsigned long long int * target, unsigned long long int bit ) {109 #if defined(__CFA_NO_BIT_TEST_AND_SET__)110 unsigned long long int mask = 1ul << bit;111 unsigned long long int ret = __atomic_fetch_and(target, ~mask, (int)__ATOMIC_RELAXED);112 return (ret & mask) != 0;113 #else114 int result = 0;115 asm volatile(116 "LOCK btrq %[bit], %[target]\n\t"117 :"=@ccc" (result)118 : [target] "m" (*target), [bit] "r" (bit)119 );120 return result != 0;121 #endif122 }123 #elif defined( __ARM_ARCH )124 #error __atomic_bts and __atomic_btr not implemented for arm125 #else126 #error uknown hardware architecture127 #endif -
libcfa/src/bits/locks.hfa
r3f850d7 r53ee27e 130 130 pthread_mutex_init(&lock, &mattr); 131 131 132 pthread_cond_init (&cond, 0p);132 pthread_cond_init (&cond, (const pthread_condattr_t *)0p); // workaround trac#208: cast should not be required 133 133 val = 0; 134 134 } … … 164 164 165 165 #undef CHECKED 166 167 struct $thread; 168 extern void park( __cfaabi_dbg_ctx_param ); 169 extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 ); 170 static inline struct $thread * active_thread (); 171 172 // Semaphore which only supports a single thread 173 struct single_sem { 174 struct $thread * volatile ptr; 175 }; 176 177 static inline { 178 void ?{}(single_sem & this) { 179 this.ptr = 0p; 180 } 181 182 void ^?{}(single_sem & this) {} 183 184 bool wait(single_sem & this) { 185 for() { 186 struct $thread * expected = this.ptr; 187 if(expected == 1p) { 188 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 189 return false; 190 } 191 } 192 else { 193 /* paranoid */ verify( expected == 0p ); 194 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 195 park( __cfaabi_dbg_ctx ); 196 return true; 197 } 198 } 199 200 } 201 } 202 203 bool post(single_sem & this) { 204 for() { 205 struct $thread * expected = this.ptr; 206 if(expected == 1p) return false; 207 if(expected == 0p) { 208 if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 209 return false; 210 } 211 } 212 else { 213 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 214 unpark( expected __cfaabi_dbg_ctx2 ); 215 return true; 216 } 217 } 218 } 219 } 220 } 166 221 #endif
Note:
See TracChangeset
for help on using the changeset viewer.