lockcount list[0];
} _objc_lock_list;
+static tls_key_t lock_tls;
+
+static void
+destroyLocks(void *value)
+{
+ _objc_lock_list *locks = (_objc_lock_list *)value;
+ // fixme complain about any still-held locks?
+ if (locks) _free_internal(locks);
+}
+
static struct _objc_lock_list *
getLocks(BOOL create)
{
- _objc_pthread_data *data;
_objc_lock_list *locks;
- data = _objc_fetch_pthread_data(create);
- if (!data && !create) return NULL;
+ // Use a dedicated tls key to prevent differences vs non-debug in
+ // usage of objc's other tls keys (required for some unit tests).
+ INIT_ONCE_PTR(lock_tls, tls_create(&destroyLocks), (void)0);
- locks = data->lockList;
+ locks = (_objc_lock_list *)tls_get(lock_tls);
if (!locks) {
if (!create) {
return NULL;
locks = _calloc_internal(1, sizeof(_objc_lock_list) + sizeof(lockcount) * 16);
locks->allocated = 16;
locks->used = 0;
- data->lockList = locks;
+ tls_set(lock_tls, locks);
}
}
if (!create) {
return locks;
} else {
- data->lockList = _calloc_internal(1, sizeof(_objc_lock_list) + 2 * locks->used * sizeof(lockcount));
- data->lockList->used = locks->used;
- data->lockList->allocated = locks->used * 2;
- memcpy(data->lockList->list, locks->list, locks->used * sizeof(lockcount));
- _free_internal(locks);
- locks = data->lockList;
+ _objc_lock_list *oldlocks = locks;
+ locks = _calloc_internal(1, sizeof(_objc_lock_list) + 2 * oldlocks->used * sizeof(lockcount));
+ locks->used = oldlocks->used;
+ locks->allocated = oldlocks->used * 2;
+ memcpy(locks->list, oldlocks->list, locks->used * sizeof(lockcount));
+ tls_set(lock_tls, locks);
+ _free_internal(oldlocks);
}
}
_objc_fatal("lock not found!");
}
-__private_extern__ void
-_destroyLockList(struct _objc_lock_list *locks)
-{
- // fixme complain about any still-held locks?
- if (locks) _free_internal(locks);
-}
-
/***********************************************************************
* Mutex checking
**********************************************************************/
-__private_extern__ int
+PRIVATE_EXTERN int
_mutex_lock_debug(mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return _mutex_lock_nodebug(lock);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_mutex_try_lock_debug(mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return result;
}
-__private_extern__ int
+PRIVATE_EXTERN int
_mutex_unlock_debug(mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
return _mutex_unlock_nodebug(lock);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_mutex_assert_locked_debug(mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_mutex_assert_unlocked_debug(mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
* Recursive mutex checking
**********************************************************************/
-__private_extern__ int
+PRIVATE_EXTERN int
_recursive_mutex_lock_debug(recursive_mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return _recursive_mutex_lock_nodebug(lock);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_recursive_mutex_try_lock_debug(recursive_mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return result;
}
-__private_extern__ int
+PRIVATE_EXTERN int
_recursive_mutex_unlock_debug(recursive_mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
return _recursive_mutex_unlock_nodebug(lock);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_recursive_mutex_assert_locked_debug(recursive_mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_recursive_mutex_assert_unlocked_debug(recursive_mutex_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
* Monitor checking
**********************************************************************/
-__private_extern__ int
+PRIVATE_EXTERN int
_monitor_enter_debug(monitor_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return _monitor_enter_nodebug(lock);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_monitor_exit_debug(monitor_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
return _monitor_exit_nodebug(lock);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_monitor_wait_debug(monitor_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
return _monitor_wait_nodebug(lock);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_monitor_assert_locked_debug(monitor_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
}
-__private_extern__ void
+PRIVATE_EXTERN void
_monitor_assert_unlocked_debug(monitor_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
* rwlock checking
**********************************************************************/
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_read_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
_rwlock_read_nodebug(lock);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_rwlock_try_read_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return result;
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_unlock_read_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
_rwlock_unlock_read_nodebug(lock);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_write_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
}
-__private_extern__ int
+PRIVATE_EXTERN int
_rwlock_try_write_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(YES);
return result;
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_unlock_write_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_assert_reading_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_assert_writing_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_assert_locked_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);
}
}
-__private_extern__ void
+PRIVATE_EXTERN void
_rwlock_assert_unlocked_debug(rwlock_t *lock, const char *name)
{
_objc_lock_list *locks = getLocks(NO);