Overview
Comment: | Fall back to of_tlskey if __thread is unavailable. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
95b1b31aa5c375e66d7461806b216ea4 |
User & Date: | js on 2012-07-14 22:21:24 |
Other Links: | manifest | tags |
Context
2012-07-15
| ||
00:38 | Fix missing initialization of size. check-in: 335ba77462 user: js tags: trunk | |
2012-07-14
| ||
22:21 | Fall back to of_tlskey if __thread is unavailable. check-in: 95b1b31aa5 user: js tags: trunk | |
21:02 | Fix forgotten __thread. check-in: eade7d765c user: js tags: trunk | |
Changes
Modified configure.ac from [b1e49e08ab] to [525f5e59fb].
︙ | ︙ | |||
446 447 448 449 450 451 452 453 454 455 456 457 458 459 | esac AC_DEFINE(OF_THREADS, 1, [Whether we have threads]) AC_SUBST(OFTHREAD_M, "OFThread.m") AC_SUBST(OFTHREADTESTS_M, "OFThreadTests.m") AC_SUBST(OFHTTPREQUESTTESTS_M, "OFHTTPRequestTests.m") AC_SUBST(THREADING_H, "threading.h") atomic_ops="none" AC_MSG_CHECKING(whether we have an atomic ops assembly implementation) AC_EGREP_CPP(yes, [ #if defined(__GNUC__) && (defined(__i386__) || \ defined(__amd64__) || defined(__x86_64__)) | > > > > > > > > > > > > > > > > > | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | esac AC_DEFINE(OF_THREADS, 1, [Whether we have threads]) AC_SUBST(OFTHREAD_M, "OFThread.m") AC_SUBST(OFTHREADTESTS_M, "OFThreadTests.m") AC_SUBST(OFHTTPREQUESTTESTS_M, "OFHTTPRequestTests.m") AC_SUBST(THREADING_H, "threading.h") AC_MSG_CHECKING(whether __thread works) AC_TRY_LINK([ /* It seems __thread is buggy with GCC 4.1 */ #if __GNUC__ == 4 && __GNUC_MINOR__ < 2 # error buggy #endif __thread int x = 0; ], [ x++; ], [ AC_MSG_RESULT(yes) AC_DEFINE(OF_COMPILER_TLS, 1, [Whether __thread works]) ], [ AC_MSG_RESULT(no) ]) atomic_ops="none" AC_MSG_CHECKING(whether we have an atomic ops assembly implementation) AC_EGREP_CPP(yes, [ #if defined(__GNUC__) && (defined(__i386__) || \ defined(__amd64__) || defined(__x86_64__)) |
︙ | ︙ |
Modified src/OFAutoreleasePool.m from [9b9e08d0f0] to [20bd5ed7f7].
︙ | ︙ | |||
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 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #import "OFAutoreleasePool.h" #import "OFArray.h" #import "OFNotImplementedException.h" extern id _objc_rootAutorelease(id); extern void* objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void*); static __thread void *first = NULL; @implementation OFAutoreleasePool + (id)addObject: (id)object { if (first == NULL) [[OFAutoreleasePool alloc] init]; return _objc_rootAutorelease(object); } + (void)_releaseAll { objc_autoreleasePoolPop(first); } - init { self = [super init]; @try { pool = objc_autoreleasePoolPush(); if (first == NULL) first = pool; _objc_rootAutorelease(self); } @catch (id e) { [self release]; @throw e; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #include <assert.h> #import "OFAutoreleasePool.h" #import "OFArray.h" #ifndef OF_COMPILER_TLS # import "threading.h" # import "OFInitializationFailedException.h" #endif #import "OFNotImplementedException.h" extern id _objc_rootAutorelease(id); extern void* objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void*); #ifdef OF_COMPILER_TLS static __thread void *first = NULL; #else static of_tlskey_t firstKey; #endif @implementation OFAutoreleasePool #ifndef OF_COMPILER_TLS + (void)initialize { if (self != [OFAutoreleasePool class]) return; if (!of_tlskey_new(&firstKey)) @throw [OFInitializationFailedException exceptionWithClass: self]; } #endif + (id)addObject: (id)object { #ifndef OF_COMPILER_TLS void *first = of_tlskey_get(firstKey); #endif if (first == NULL) [[OFAutoreleasePool alloc] init]; return _objc_rootAutorelease(object); } + (void)_releaseAll { #ifndef OF_COMPILER_TLS void *first = of_tlskey_get(firstKey); #endif objc_autoreleasePoolPop(first); } - init { self = [super init]; @try { #ifndef OF_COMPILER_TLS void *first = of_tlskey_get(firstKey); #endif pool = objc_autoreleasePoolPush(); if (first == NULL) #ifdef OF_COMPILER_TLS first = pool; #else if (!of_tlskey_set(firstKey, pool)) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; #endif _objc_rootAutorelease(self); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | - (void)dealloc { if (ignoreRelease) return; ignoreRelease = YES; if (first == pool) first = NULL; objc_autoreleasePoolPop(pool); [super dealloc]; } - retain | > > > > > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | - (void)dealloc { if (ignoreRelease) return; ignoreRelease = YES; #ifdef OF_COMPILER_TLS if (first == pool) first = NULL; #else if (of_tlskey_get(firstKey) == pool) assert(of_tlskey_set(firstKey, NULL)); #endif objc_autoreleasePoolPop(pool); [super dealloc]; } - retain |
︙ | ︙ |
Modified src/objfw-defs.h.in from [1faf553899] to [35b1efd8d0].
1 2 3 4 5 6 7 8 9 10 | #undef OF_APPLE_RUNTIME #undef OF_ATOMIC_OPS #undef OF_BIG_ENDIAN #undef OF_FLOAT_BIG_ENDIAN #undef OF_HAVE_ASPRINTF #undef OF_HAVE_BLOCKS #undef OF_HAVE_FAST_ENUMERATION #undef OF_HAVE_GCC_ATOMIC_OPS #undef OF_HAVE_OPTIONAL_PROTOCOLS #undef OF_HAVE_OSATOMIC | > | 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_COMPILER_TLS #undef OF_FLOAT_BIG_ENDIAN #undef OF_HAVE_ASPRINTF #undef OF_HAVE_BLOCKS #undef OF_HAVE_FAST_ENUMERATION #undef OF_HAVE_GCC_ATOMIC_OPS #undef OF_HAVE_OPTIONAL_PROTOCOLS #undef OF_HAVE_OSATOMIC |
︙ | ︙ |
Modified src/runtime/autorelease.m from [b91ab77a61] to [790a0b73c2].
︙ | ︙ | |||
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 | #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" #import "OFObject.h" #import "macros.h" static __thread id *objects = NULL; static __thread id *top = NULL; static __thread size_t size = 0; id objc_autorelease(id object) { return [object autorelease]; } void* objc_autoreleasePoolPush() { ptrdiff_t offset = top - objects; return (void*)offset; } void objc_autoreleasePoolPop(void *offset) { id *pool = objects + (ptrdiff_t)offset; id *iter; for (iter = pool; iter < top; iter++) [*iter release]; top = pool; } id _objc_rootAutorelease(id object) { if (objects == NULL) { if ((objects = malloc(of_pagesize)) == NULL) ERROR("Out of memory for autorelease pools!") top = objects; } if ((uintptr_t)top >= (uintptr_t)objects + size) { ptrdiff_t diff = top - objects; size += of_pagesize; if ((objects = realloc(objects, size)) == NULL) ERROR("Out of memory for autorelease pools!") top = objects + diff; } *top = object; top++; return object; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" #import "OFObject.h" #ifndef OF_COMPILER_TLS # import "threading.h" #endif #import "macros.h" #ifdef OF_COMPILER_TLS static __thread id *objects = NULL; static __thread id *top = NULL; static __thread size_t size = 0; #else static of_tlskey_t objectsKey, topKey, sizeKey; static void __attribute__((constructor)) init(void) { if (!of_tlskey_new(&objectsKey) || !of_tlskey_new(&sizeKey) || !of_tlskey_new(&topKey)) ERROR("Unable to create TLS key for autorelease pools!") } #endif id objc_autorelease(id object) { return [object autorelease]; } void* objc_autoreleasePoolPush() { #ifndef OF_COMPILER_TLS id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); #endif ptrdiff_t offset = top - objects; return (void*)offset; } void objc_autoreleasePoolPop(void *offset) { #ifndef OF_COMPILER_TLS id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); #endif id *pool = objects + (ptrdiff_t)offset; id *iter; for (iter = pool; iter < top; iter++) [*iter release]; #ifdef OF_COMPILER_TLS top = pool; #else if (!of_tlskey_set(topKey, pool)) ERROR("Failed to set TLS key!") #endif } id _objc_rootAutorelease(id object) { #ifndef OF_COMPILER_TLS id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey); #endif if (objects == NULL) { if ((objects = malloc(of_pagesize)) == NULL) ERROR("Out of memory for autorelease pools!") #ifndef OF_COMPILER_TLS if (!of_tlskey_set(objectsKey, objects)) ERROR("Failed to set TLS key!") if (!of_tlskey_set(sizeKey, (void*)(uintptr_t)of_pagesize)) ERROR("Failed to set TLS key!") #endif top = objects; } if ((uintptr_t)top >= (uintptr_t)objects + size) { ptrdiff_t diff = top - objects; size += of_pagesize; if ((objects = realloc(objects, size)) == NULL) ERROR("Out of memory for autorelease pools!") #ifndef OF_COMPILER_TLS if (!of_tlskey_set(objectsKey, objects)) ERROR("Failed to set TLS key!") if (!of_tlskey_set(sizeKey, (void*)(uintptr_t)size)) ERROR("Failed to set TLS key!") #endif top = objects + diff; } *top = object; top++; #ifndef OF_COMPILER_TLS if (!of_tlskey_set(topKey, objects)) ERROR("Failed to set TLS key!") #endif return object; } |