Overview
Comment: | Change spinlock implementation, add fallbacks and move to threading.h. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
921b158d17b26c1aeb6b3bee85234d78 |
User & Date: | js on 2010-01-30 01:17:15 |
Other Links: | manifest | tags |
Context
2010-01-30
| ||
01:50 | Fall back to spinlocks if atomic ops are unavailable. check-in: bd6a71aad3 user: js tags: trunk | |
01:17 | Change spinlock implementation, add fallbacks and move to threading.h. check-in: 921b158d17 user: js tags: trunk | |
00:50 | Add -[tryLock] to OFMutex. check-in: 20e1c0e24b user: js tags: trunk | |
Changes
Modified configure.ac from [9eadb6c419] to [2dac0a970f].
︙ | ︙ | |||
72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ], [ AC_DEFINE(OF_APPLE_RUNTIME, 1, [Whether we use the Apple ObjC runtime]) AC_SUBST(RUNTIME_DEF, "-DOF_APPLE_RUNTIME") objc_runtime="Apple"]) AC_MSG_RESULT($objc_runtime) AC_CHECK_FUNC(objc_getProperty,, [ AC_SUBST(OBJC_PROPERTIES_M, "objc_properties.m")]) AC_CHECK_FUNC(objc_enumerationMutation, [ AC_DEFINE(HAVE_OBJC_ENUMERATIONMUTATION, 1, [Whether we have objc_enumerationMutation])]) BUILDSYS_LIB | > > | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | ], [ AC_DEFINE(OF_APPLE_RUNTIME, 1, [Whether we use the Apple ObjC runtime]) AC_SUBST(RUNTIME_DEF, "-DOF_APPLE_RUNTIME") objc_runtime="Apple"]) AC_MSG_RESULT($objc_runtime) AC_CHECK_FUNC(objc_getProperty,, [ AC_DEFINE(NEED_OBJC_PROPERTIES_INIT, 1, [Whether objc_properties_init needs to be called]) AC_SUBST(OBJC_PROPERTIES_M, "objc_properties.m")]) AC_CHECK_FUNC(objc_enumerationMutation, [ AC_DEFINE(HAVE_OBJC_ENUMERATIONMUTATION, 1, [Whether we have objc_enumerationMutation])]) BUILDSYS_LIB |
︙ | ︙ | |||
147 148 149 150 151 152 153 | AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") AC_ARG_ENABLE(threads, AS_HELP_STRING([--disable-threads], [disable thread support])) if test x"$enable_threads" != x"no"; then case "$host_os" in | | | | | | | | | | | > > > > > > | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") AC_ARG_ENABLE(threads, AS_HELP_STRING([--disable-threads], [disable thread support])) if test x"$enable_threads" != x"no"; then case "$host_os" in mingw*) AC_MSG_CHECKING(for threads) AC_MSG_RESULT(win32) ;; *) ACX_PTHREAD([ CPPLAGS="$CPPFLAGS $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" AC_DEFINE(OF_HAVE_PTHREADS, 1, [Whether we have pthreads]) AC_CHECK_FUNC(pthread_spin_lock, [ AC_DEFINE(OF_HAVE_PTHREAD_SPINLOCKS, 1, [Whether we have pthread spinlocks])]) AC_CHECK_FUNC(sched_yield, [ AC_DEFINE(OF_HAVE_SCHED_YIELD, 1, [Whether we have sched_yield])]) ], [ AC_MSG_ERROR(No supported threads found!)]) ;; esac AC_DEFINE(OF_THREADS, 1, [Whether we have threads]) AC_SUBST(OFTHREAD_M, "OFThread.m") AC_SUBST(THREADING_H, "threading.h") AC_CHECK_FUNC(objc_sync_enter,, [ |
︙ | ︙ | |||
212 213 214 215 216 217 218 | AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations]) AC_MSG_RESULT(gcc builtins) elif test x"$have_libkern_osatomic_h" = x"yes"; then AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations]) AC_MSG_RESULT(libkern/OSAtomic.h) else AC_MSG_RESULT(none) | < | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations]) AC_MSG_RESULT(gcc builtins) elif test x"$have_libkern_osatomic_h" = x"yes"; then AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations]) AC_MSG_RESULT(libkern/OSAtomic.h) else AC_MSG_RESULT(none) fi else dnl We can only have one thread - therefore everything is atomic AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations]) fi AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") |
︙ | ︙ |
Modified src/OFObject.m from [14884d461d] to [f35a66b387].
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | static struct { Class isa; } alloc_failed_exception; #ifdef NEED_OBJC_SYNC_INIT extern BOOL objc_sync_init(); #endif static void enumeration_mutation_handler(id obj) { @throw [OFEnumerationMutationException newWithClass: [obj class]]; } | > > > > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | static struct { Class isa; } alloc_failed_exception; #ifdef NEED_OBJC_SYNC_INIT extern BOOL objc_sync_init(); #endif #ifdef NEED_OBJC_PROPERTIES_INIT extern BOOL objc_properties_init(); #endif static void enumeration_mutation_handler(id obj) { @throw [OFEnumerationMutationException newWithClass: [obj class]]; } |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | { #ifdef NEED_OBJC_SYNC_INIT if (!objc_sync_init()) { fputs("Runtime error: objc_sync_init() failed!\n", stderr); abort(); } #endif #ifdef OF_APPLE_RUNTIME objc_setEnumerationMutationHandler(enumeration_mutation_handler); #endif } + (void)initialize | > > > > > > > > | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | { #ifdef NEED_OBJC_SYNC_INIT if (!objc_sync_init()) { fputs("Runtime error: objc_sync_init() failed!\n", stderr); abort(); } #endif #ifdef NEED_OBJC_PROPERTIES_INIT if (!objc_properties_init()) { fputs("Runtime error: objc_properties_init() failed!\n", stderr); abort(); } #endif #ifdef OF_APPLE_RUNTIME objc_setEnumerationMutationHandler(enumeration_mutation_handler); #endif } + (void)initialize |
︙ | ︙ |
Modified src/atomic.h from [a774b233fa] to [a1c4c931ea].
︙ | ︙ | |||
39 40 41 42 43 44 45 | # error No atomic operations available! #endif #if !defined(OF_THREADS) || defined(OF_HAVE_GCC_ATOMIC_OPS) # define of_atomic_inc32(p) of_atomic_add32(p, 1) # define of_atomic_dec32(p) of_atomic_sub32(p, 1) #endif | < < < < < < < < < | 39 40 41 42 43 44 45 | # error No atomic operations available! #endif #if !defined(OF_THREADS) || defined(OF_HAVE_GCC_ATOMIC_OPS) # define of_atomic_inc32(p) of_atomic_add32(p, 1) # define of_atomic_dec32(p) of_atomic_sub32(p, 1) #endif |
Modified src/objc_properties.m from [684035ffa6] to [63edddc2b7].
︙ | ︙ | |||
11 12 13 14 15 16 17 | #include "config.h" #import <objc/objc.h> #import "OFExceptions.h" | > | | > > > > > > > > > > > > > > > > | | > > > > | > > | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include "config.h" #import <objc/objc.h> #import "OFExceptions.h" #ifdef OF_THREADS #import "threading.h" #define NUM_SPINLOCKS 8 /* needs to be a power of 2 */ #define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1) static of_spinlock_t spinlocks[NUM_SPINLOCKS]; #endif BOOL objc_properties_init() { #ifdef OF_THREADS size_t i; for (i = 0; i < NUM_SPINLOCKS; i++) if (!of_spinlock_new(&spinlocks[i])) return NO; #endif return YES; } id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) { if (atomic) { id *ptr = (id*)((char*)self + offset); #ifdef OF_THREADS unsigned hash = SPINLOCK_HASH(ptr); of_spinlock_lock(&spinlocks[hash]); @try { return [[*ptr retain] autorelease]; } @finally { of_spinlock_unlock(&spinlocks[hash]); } #else return [[*ptr retain] autorelease]; #endif } return *(id*)((char*)self + offset); } void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, BOOL atomic, BOOL copy) { if (atomic) { id *ptr = (id*)((char*)self + offset); #ifdef OF_THREADS unsigned hash = SPINLOCK_HASH(ptr); of_spinlock_lock(&spinlocks[hash]); @try { #endif id old = *ptr; switch (copy) { case 0: *ptr = [value retain]; break; case 2: /* * Apple uses this to indicate that the copy * should be mutable. Please hit them for * abusing a poor BOOL! */ *ptr = [value mutableCopy]; break; default: *ptr = [value copy]; } [old release]; #ifdef OF_THREADS } @finally { of_spinlock_unlock(&spinlocks[hash]); } #endif return; } id *ptr = (id*)((char*)self + offset); id old = *ptr; |
︙ | ︙ |
Modified src/objfw-defs.h.in from [59fa4d3305] to [e92fcadc33].
1 2 3 4 5 6 7 8 9 10 11 | #undef OF_APPLE_RUNTIME #undef OF_ATOMIC_OPS #undef OF_BIG_ENDIAN #undef OF_GNU_RUNTIME #undef OF_HAVE_ASPRINTF #undef OF_HAVE_GCC_ATOMIC_OPS #undef OF_HAVE_LIBKERN_OSATOMIC_H #undef OF_HAVE_PTHREADS #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | #undef OF_APPLE_RUNTIME #undef OF_ATOMIC_OPS #undef OF_BIG_ENDIAN #undef OF_GNU_RUNTIME #undef OF_HAVE_ASPRINTF #undef OF_HAVE_GCC_ATOMIC_OPS #undef OF_HAVE_LIBKERN_OSATOMIC_H #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS #undef OF_HAVE_SCHED_YIELD #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX |
Modified src/threading.h from [118d170b8a] to [f8a41f877f].
︙ | ︙ | |||
181 182 183 184 185 186 187 | { #if defined(OF_HAVE_PTHREADS) return (pthread_key_delete(key) ? NO : YES); #elif defined(_WIN32) return (TlsFree(key) ? YES : NO); #endif } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | { #if defined(OF_HAVE_PTHREADS) return (pthread_key_delete(key) ? NO : YES); #elif defined(_WIN32) return (TlsFree(key) ? YES : NO); #endif } #if defined(OF_ATOMIC_OPS) # import "atomic.h" typedef int32_t of_spinlock_t; # define of_spinlock_new(s) ((*(s) = 0) + YES) # define of_spinlock_trylock(s) (of_atomic_cmpswap32(s, 0, 1) ? YES : NO) # ifdef OF_HAVE_SCHED_YIELD # define of_spinlock_lock(s) \ while (!of_spinlock_trylock(s)) \ sched_yield() # else # define of_spinlock_lock(s) while (!of_spinlock_trylock(s)); # endif # define of_spinlock_unlock(s) *(s) = 0 # define of_spinlock_free(s) YES #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) typedef pthread_spinlock_t of_spinlock_t; # define of_spinlock_new(s) (pthread_spin_init(s, 0) ? NO : YES) # define of_spinlock_trylock(s) (pthread_spin_trylock(s) ? NO : YES) # define of_spinlock_lock(s) pthread_spin_lock(s) # define of_spinlock_unlock(s) pthread_spin_unlock(s) # define of_spinlock_free(s) (pthread_spin_destroy(s) ? NO : YES) #else typedef of_mutex_t of_spinlock_t; # define of_spinlock_new(s) of_mutex_new(s) # define of_spinlock_trylock(s) of_mutex_trylock(s) # define of_spinlock_lock(s) of_mutex_lock(s) # define of_spinlock_unlock(s) of_mutex_unlock(s) # define of_spinlock_free(s) of_mutex_free(s) #endif |