@@ -19,38 +19,45 @@ #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS -# import "mutex.h" -# define NUM_SPINLOCKS 8 /* needs to be a power of 2 */ -# define SPINLOCK_HASH(p) ((unsigned)((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1)) -static of_spinlock_t spinlocks[NUM_SPINLOCKS]; +# import "OFPlainMutex.h" +# define numSpinlocks 8 /* needs to be a power of 2 */ +static OFSpinlock spinlocks[numSpinlocks]; + +static OF_INLINE size_t +spinlockSlot(const void *ptr) +{ + return ((size_t)((uintptr_t)ptr >> 4) & (numSpinlocks - 1)); +} #endif #ifdef OF_HAVE_THREADS OF_CONSTRUCTOR() { - for (size_t i = 0; i < NUM_SPINLOCKS; i++) - if (of_spinlock_new(&spinlocks[i]) != 0) - OBJC_ERROR("Failed to initialize spinlocks!"); + for (size_t i = 0; i < numSpinlocks; i++) + if (OFSpinlockNew(&spinlocks[i]) != 0) + OBJC_ERROR("Failed to create spinlocks!"); } #endif id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic) { if (atomic) { id *ptr = (id *)(void *)((char *)self + offset); #ifdef OF_HAVE_THREADS - unsigned hash = SPINLOCK_HASH(ptr); + size_t slot = spinlockSlot(ptr); - OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0); + if (OFSpinlockLock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to lock spinlock!"); @try { return [[*ptr retain] autorelease]; } @finally { - OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0); + if (OFSpinlockUnlock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to unlock spinlock!"); } #else return [[*ptr retain] autorelease]; #endif } @@ -63,13 +70,14 @@ signed char copy) { if (atomic) { id *ptr = (id *)(void *)((char *)self + offset); #ifdef OF_HAVE_THREADS - unsigned hash = SPINLOCK_HASH(ptr); + size_t slot = spinlockSlot(ptr); - OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0); + if (OFSpinlockLock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to lock spinlock!"); @try { #endif id old = *ptr; switch (copy) { @@ -84,11 +92,12 @@ } [old release]; #ifdef OF_HAVE_THREADS } @finally { - OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0); + if (OFSpinlockUnlock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to unlock spinlock!"); } #endif return; } @@ -115,17 +124,19 @@ objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { if (atomic) { #ifdef OF_HAVE_THREADS - unsigned hash = SPINLOCK_HASH(src); + size_t slot = spinlockSlot(src); - OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0); + if (OFSpinlockLock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to lock spinlock!"); #endif memcpy(dest, src, size); #ifdef OF_HAVE_THREADS - OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0); + if (OFSpinlockUnlock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to unlock spinlock!"); #endif return; } @@ -136,17 +147,19 @@ objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { if (atomic) { #ifdef OF_HAVE_THREADS - unsigned hash = SPINLOCK_HASH(src); + size_t slot = spinlockSlot(src); - OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0); + if (OFSpinlockLock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to lock spinlock!"); #endif memcpy(dest, src, size); #ifdef OF_HAVE_THREADS - OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0); + if (OFSpinlockUnlock(&spinlocks[slot]) != 0) + OBJC_ERROR("Failed to unlock spinlock!"); #endif return; } @@ -165,11 +178,11 @@ *outCount = 0; return NULL; } - objc_global_mutex_lock(); + objc_globalMutex_lock(); count = 0; if (class->info & OBJC_CLASS_INFO_NEW_ABI) for (iter = class->propertyList; iter != NULL; iter = iter->next) @@ -177,11 +190,11 @@ if (count == 0) { if (outCount != NULL) *outCount = 0; - objc_global_mutex_unlock(); + objc_globalMutex_unlock(); return NULL; } properties = malloc((count + 1) * sizeof(objc_property_t)); if (properties == NULL) @@ -189,17 +202,20 @@ i = 0; for (iter = class->propertyList; iter != NULL; iter = iter->next) for (unsigned int j = 0; j < iter->count; j++) properties[i++] = &iter->properties[j]; - OF_ENSURE(i == count); + + if (i != count) + OBJC_ERROR("Fatal internal inconsistency!"); + properties[count] = NULL; if (outCount != NULL) *outCount = count; - objc_global_mutex_unlock(); + objc_globalMutex_unlock(); return properties; } const char * @@ -217,22 +233,22 @@ if (strlen(name) != 1) return NULL; switch (*name) { case 'T': - ret = of_strdup(property->getter.typeEncoding); + ret = objc_strdup(property->getter.typeEncoding); nullIsError = true; break; case 'G': if (property->attributes & OBJC_PROPERTY_GETTER) { - ret = of_strdup(property->getter.name); + ret = objc_strdup(property->getter.name); nullIsError = true; } break; case 'S': if (property->attributes & OBJC_PROPERTY_SETTER) { - ret = of_strdup(property->setter.name); + ret = objc_strdup(property->setter.name); nullIsError = true; } break; #define BOOL_CASE(name, field, flag) \ case name: \ @@ -251,9 +267,9 @@ #undef BOOL_CASE } if (nullIsError && ret == NULL) OBJC_ERROR("Not enough memory to copy property attribute " - "value"); + "value!"); return ret; }