]> git.saurik.com Git - apple/libpthread.git/commitdiff
libpthread-138.10.4.tar.gz os-x-10112 os-x-10113 os-x-10114 os-x-10115 os-x-10116 v138.10.4
authorApple <opensource@apple.com>
Wed, 9 Dec 2015 05:20:08 +0000 (05:20 +0000)
committerApple <opensource@apple.com>
Wed, 9 Dec 2015 05:20:08 +0000 (05:20 +0000)
kern/kern_synch.c
libpthread.xcodeproj/project.pbxproj
src/internal.h
src/pthread_mutex.c
tests/Makefile
tests/Makefile.common [new file with mode: 0644]
tests/rwlock-22244050.c [new file with mode: 0644]

index 713691265dae1c17459d519ed9e31e9edcb54922..4e7674941a3530945e7a91fbf9c079c3d8172efb 100644 (file)
@@ -468,8 +468,8 @@ _ksyn_handle_missed_wakeups(ksyn_wait_queue_t kwq,
 {
        int res = 0;
        if (kwq->kw_pre_intrcount != 0 &&
-           kwq->kw_pre_intrtype == type &&
-           is_seqlower_eq(lockseq, kwq->kw_pre_intrseq)) {
+               kwq->kw_pre_intrtype == type &&
+               (kwq->kw_pre_intrseq == 0 || is_seqlower_eq(lockseq, kwq->kw_pre_intrseq))) {
                kwq->kw_pre_intrcount--;
                *retval = kwq->kw_pre_intrretbits;
                if (kwq->kw_pre_intrcount == 0) {
@@ -1413,7 +1413,8 @@ _psynch_rw_unlock(__unused proc_t p,
        int diff;
        uint32_t count = 0;
        uint32_t curgen = lgenval & PTHRW_COUNT_MASK;
-       
+       int clearedkflags = 0;
+
        error = ksyn_wqfind(rwlock, lgenval, ugenval, rw_wc, flags, (KSYN_WQTYPE_INDROP | KSYN_WQTYPE_RWLOCK), &kwq);
        if (error != 0) {
                return(error);
@@ -1439,6 +1440,7 @@ _psynch_rw_unlock(__unused proc_t p,
        /* no prepost and all threads are in place, reset the bit */
        if ((isinit != 0) && ((kwq->kw_kflags & KSYN_KWF_INITCLEARED) != 0)){
                kwq->kw_kflags &= ~KSYN_KWF_INITCLEARED;
+               clearedkflags = 1;
        }
        
        /* can handle unlock now */
@@ -1455,7 +1457,14 @@ out:
                /* update bits?? */
                *retval = updatebits;
        }
-       
+
+       // <rdar://problem/22244050> If any of the wakeups failed because they already
+       // returned to userspace because of a signal then we need to ensure that the
+       // reset state is not cleared when that thread returns. Otherwise,
+       // _pthread_rwlock_lock will clear the interrupted state before it is read.
+       if (clearedkflags != 0 && kwq->kw_pre_intrcount > 0) {
+               kwq->kw_kflags |= KSYN_KWF_INITCLEARED;
+       }
        
        ksyn_wqunlock(kwq);
        ksyn_wqrelease(kwq, 0, (KSYN_WQTYPE_INDROP | KSYN_WQTYPE_RWLOCK));
index ca9263c8714ae8088f72327e351c1f348a5bb109..eb6378767b460bdbfba504e9e28f4d4cee1d08e2 100644 (file)
                6EB232C81B0EB29D005915CE /* pthread_mutex_up.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_mutex_up.c; sourceTree = "<group>"; };
                6EB232C91B0EB29D005915CE /* resolver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resolver.c; sourceTree = "<group>"; };
                6EB232CA1B0EB29D005915CE /* resolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resolver.h; sourceTree = "<group>"; };
+               720A46E21B8D125900AB7950 /* Makefile.common */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.common; sourceTree = "<group>"; };
                74E594A41613AAF4006C417B /* libpthread_eOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpthread_eOS.a; sourceTree = BUILT_PRODUCTS_DIR; };
                9207EB711AA6E008006FFC86 /* wq_kevent_stress.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = wq_kevent_stress.c; sourceTree = "<group>"; };
                9240BF321AA669C4003C99B4 /* wqtrace.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wqtrace.lua; path = tools/wqtrace.lua; sourceTree = SOURCE_ROOT; };
                C9A960B618452CDD00AE10C8 /* install-lldbmacros.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-lldbmacros.sh"; sourceTree = "<group>"; };
                C9C2212D15FA978D00447568 /* pthread.aliases */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread.aliases; sourceTree = "<group>"; };
                C9C533841607C928009988FA /* kern_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kern_internal.h; sourceTree = "<group>"; };
+               C9C5F7381B8CE2D600C873EF /* rwlock-22244050.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "rwlock-22244050.c"; sourceTree = "<group>"; };
                C9CA27D91602813000259F78 /* pthread.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = pthread.kext; sourceTree = BUILT_PRODUCTS_DIR; };
                C9CA27DC1602813000259F78 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = System/Library/Frameworks/Kernel.framework; sourceTree = SDKROOT; };
                C9D9E8FE1626248800448CED /* pthread-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "pthread-Info.plist"; sourceTree = "<group>"; };
                9264D6821A9D3E010094346B /* tests */ = {
                        isa = PBXGroup;
                        children = (
+                               720A46E21B8D125900AB7950 /* Makefile.common */,
                                9264D6881A9D3E010094346B /* Makefile */,
                                9264D6831A9D3E010094346B /* atfork.c */,
                                9264D6841A9D3E010094346B /* cond.c */,
                                9264D6891A9D3E010094346B /* maxwidth.c */,
                                9264D68A1A9D3E010094346B /* mutex.c */,
                                9264D68B1A9D3E010094346B /* once.c */,
+                               C9C5F7381B8CE2D600C873EF /* rwlock-22244050.c */,
                                9264D68C1A9D3E010094346B /* rwlock-signal.c */,
                                9264D68D1A9D3E010094346B /* rwlock.c */,
                                9264D68E1A9D3E010094346B /* tsd.c */,
                };
 /* End PBXHeadersBuildPhase section */
 
+/* Begin PBXLegacyTarget section */
+               720A46DE1B8D0B7700AB7950 /* Tests */ = {
+                       isa = PBXLegacyTarget;
+                       buildArgumentsString = "$(ACTION)";
+                       buildConfigurationList = 720A46E11B8D0B7700AB7950 /* Build configuration list for PBXLegacyTarget "Tests" */;
+                       buildPhases = (
+                       );
+                       buildToolPath = /usr/bin/make;
+                       buildWorkingDirectory = tests;
+                       dependencies = (
+                       );
+                       name = Tests;
+                       passBuildSettingsInEnvironment = 1;
+                       productName = Test;
+               };
+/* End PBXLegacyTarget section */
+
 /* Begin PBXNativeTarget section */
                6E8C16511B14F08A00C8987C /* libsystem_pthread.dylib introspection */ = {
                        isa = PBXNativeTarget;
                        attributes = {
                                LastUpgradeCheck = 0700;
                                ORGANIZATIONNAME = "";
+                               TargetAttributes = {
+                                       720A46DE1B8D0B7700AB7950 = {
+                                               CreatedOnToolsVersion = 7.0;
+                                       };
+                               };
                        };
                        buildConfigurationList = C9A325DC15B7347000270056 /* Build configuration list for PBXProject "libpthread" */;
                        compatibilityVersion = "Xcode 3.2";
                                C90E7AAC15DC3D3300A06D48 /* All */,
                                C91D01B5162892FF0002E29A /* Kext */,
                                C98832C115DEB44000B3308E /* Embedded */,
+                               720A46DE1B8D0B7700AB7950 /* Tests */,
                                6E8C16511B14F08A00C8987C /* libsystem_pthread.dylib introspection */,
                                C9A325E115B7347000270056 /* libsystem_pthread.dylib */,
                                C90E7A9E15DC3C3800A06D48 /* libpthread.a */,
                        };
                        name = Debug;
                };
+               720A46DF1B8D0B7700AB7950 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Release;
+               };
+               720A46E01B8D0B7700AB7950 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = NO;
+                               DEBUGGING_SYMBOLS = YES;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               ENABLE_TESTABILITY = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               MTL_ENABLE_DEBUG_INFO = YES;
+                               ONLY_ACTIVE_ARCH = YES;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Debug;
+               };
                74E594A31613AAF4006C417B /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = C99EA612161F8288003EBC56 /* eos.xcconfig */;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               720A46E11B8D0B7700AB7950 /* Build configuration list for PBXLegacyTarget "Tests" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               720A46DF1B8D0B7700AB7950 /* Release */,
+                               720A46E01B8D0B7700AB7950 /* Debug */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+               };
                74E594A21613AAF4006C417B /* Build configuration list for PBXNativeTarget "libpthread.a eOS" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 5a13fe339f4bb5699f4ffcbd5cdc8474fbc8b878..fd5f0cc047ed19890bbc1c0c8e86e7fc81272206 100644 (file)
@@ -250,12 +250,14 @@ typedef struct {
 #if defined(__LP64__)
        uint32_t _pad;
 #endif
-       uint32_t m_tid[2]; // thread id of thread that has mutex locked, misaligned locks may span to first field of m_seq
-       uint32_t m_seq[3];
+       uint32_t m_tid[2]; // thread id of thread that has mutex locked
+       uint32_t m_seq[2]; // mutex sequence id
+       uint32_t m_mis[2]; // for misaligned locks m_tid/m_seq will span into here
 #if defined(__LP64__)
-       uint32_t _reserved;
+       uint32_t _reserved[4];
+#else
+       uint32_t _reserved[1];
 #endif
-       void *reserved2[2];
 } _pthread_mutex;
 
 
@@ -322,8 +324,12 @@ typedef struct {
 #endif
 } _pthread_rwlock;
 
+#include "pthread.h"
 #include "pthread_spis.h"
 
+_Static_assert(sizeof(_pthread_mutex) == sizeof(pthread_mutex_t),
+               "Incorrect _pthread_mutex structure size");
+
 // Internal references to pthread_self() use TSD slot 0 directly.
 inline static pthread_t __attribute__((__pure__))
 _pthread_self_direct(void)
index d214739ab8ac1e63f70733539215ab84420f157f..566c5e903f4574816b14e8ae88a231340f3235d8 100644 (file)
@@ -69,6 +69,8 @@
 #define        PLOCKSTAT_MUTEX_RELEASE(x, y)
 #endif /* PLOCKSTAT */
 
+#define PTHREAD_MUTEX_INIT_UNUSED 1
+
 extern int __unix_conforming;
 
 #ifndef BUILDING_VARIANT
@@ -109,8 +111,9 @@ static inline void
 MUTEX_GETSEQ_ADDR(_pthread_mutex *mutex,
                  volatile uint64_t **seqaddr)
 {
-       // addr of m_seq[1] for misaligned, m_seq[0] for aligned mutex struct
-       *seqaddr = (volatile uint64_t *)(((uintptr_t)&mutex->m_seq[1]) & ~0x7ul);
+       // 64-bit aligned address inside m_seq array (&m_seq[0] for aligned mutex)
+       // We don't require more than byte alignment on OS X. rdar://22278325
+       *seqaddr = (volatile uint64_t*)(((uintptr_t)mutex->m_seq + 0x7ul) & ~0x7ul);
 }
 
 PTHREAD_ALWAYS_INLINE
@@ -118,8 +121,9 @@ static inline void
 MUTEX_GETTID_ADDR(_pthread_mutex *mutex,
                                  volatile uint64_t **tidaddr)
 {
-       // addr of m_tid[1] for misaligned, m_tid[0] for aligned mutex struct
-       *tidaddr = (volatile uint64_t *)(((uintptr_t)&mutex->m_tid[1]) & ~0x7ul);
+       // 64-bit aligned address inside m_tid array (&m_tid[0] for aligned mutex)
+       // We don't require more than byte alignment on OS X. rdar://22278325
+       *tidaddr = (volatile uint64_t*)(((uintptr_t)mutex->m_tid + 0x7ul) & ~0x7ul);
 }
 
 #ifndef BUILDING_VARIANT /* [ */
@@ -994,8 +998,11 @@ pthread_mutex_unlock(pthread_mutex_t *omutex)
 
 
 static inline int
-_pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint32_t static_type)
+_pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr,
+               uint32_t static_type)
 {
+       mutex->mtxopts.value = 0;
+       mutex->mtxopts.options.mutex = 1;
        if (attr) {
                if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) {
                        return EINVAL;
@@ -1031,27 +1038,21 @@ _pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint
                }
                mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED;
        }
-       
-       mutex->mtxopts.options.notify = 0;
-       mutex->mtxopts.options.unused = 0;
-       mutex->mtxopts.options.hold = 0;
-       mutex->mtxopts.options.mutex = 1;
-       mutex->mtxopts.options.lock_count = 0;
-
-       mutex->m_tid[0] = 0;
-       mutex->m_tid[1] = 0;
-       mutex->m_seq[0] = 0;
-       mutex->m_seq[1] = 0;
-       mutex->m_seq[2] = 0;
-       mutex->prioceiling = 0;
        mutex->priority = 0;
 
-       mutex->mtxopts.options.misalign = (((uintptr_t)&mutex->m_seq[0]) & 0x7ul) != 0;
-       if (mutex->mtxopts.options.misalign) {
-               mutex->m_tid[0] = ~0u;
-       } else {
-               mutex->m_seq[2] = ~0u;
+       volatile uint64_t *seqaddr;
+       MUTEX_GETSEQ_ADDR(mutex, &seqaddr);
+       volatile uint64_t *tidaddr;
+       MUTEX_GETTID_ADDR(mutex, &tidaddr);
+#if PTHREAD_MUTEX_INIT_UNUSED
+       if ((uint32_t*)tidaddr != mutex->m_tid) {
+               mutex->mtxopts.options.misalign = 1;
+               __builtin_memset(mutex->m_tid, 0xff, sizeof(mutex->m_tid));
        }
+       __builtin_memset(mutex->m_mis, 0xff, sizeof(mutex->m_mis));
+#endif // PTHREAD_MUTEX_INIT_UNUSED
+       *tidaddr = 0;
+       *seqaddr = 0;
 
        long sig = _PTHREAD_MUTEX_SIG;
        if (mutex->mtxopts.options.type == PTHREAD_MUTEX_NORMAL &&
@@ -1060,9 +1061,19 @@ _pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint
                sig = _PTHREAD_MUTEX_SIG_fast;
        }
 
-       // unused, purely for detecting copied mutexes and smashes during debugging:
-       mutex->reserved2[0] = ~(uintptr_t)mutex; // use ~ to hide from leaks
-       mutex->reserved2[1] = (uintptr_t)sig;
+#if PTHREAD_MUTEX_INIT_UNUSED
+       // For detecting copied mutexes and smashes during debugging
+       uint32_t sig32 = (uint32_t)sig;
+#if defined(__LP64__)
+       uintptr_t guard =  ~(uintptr_t)mutex; // use ~ to hide from leaks
+       __builtin_memcpy(mutex->_reserved, &guard, sizeof(guard));
+       mutex->_reserved[2] = sig32;
+       mutex->_reserved[3] = sig32;
+       mutex->_pad = sig32;
+#else
+       mutex->_reserved[0] = sig32;
+#endif
+#endif // PTHREAD_MUTEX_INIT_UNUSED
 
        // Ensure all contents are properly set before setting signature.
 #if defined(__LP64__)
index 219bc92d07e158bd31557a92e1a727296cbf600d..98a4f3c398113b70541ba945d1f96d07fa2f64f0 100644 (file)
@@ -2,7 +2,12 @@ SOURCES := $(wildcard *.c)
 TARGETS := $(patsubst %.c,%,$(SOURCES))
 TESTS   := $(patsubst %,test-%,$(TARGETS))
 
-CFLAGS := -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
+include Makefile.common
+
+CFLAGS += -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
+
+%: %.c
+       $(CC) -o $(BUILDDIR)/$@ $< $(CFLAGS)
 
 all: $(TARGETS)
 
@@ -17,4 +22,15 @@ $(TESTS): test-%: %
 clean:
        rm -f $(TARGETS)
 
+setup:
+       mkdir -p $(BUILDDIR)
+
+
+# B&I Targets
+
+installhdrs:
+
+install: setup all
+
+
 .PHONY: all test check clean $(TESTS)
diff --git a/tests/Makefile.common b/tests/Makefile.common
new file mode 100644 (file)
index 0000000..c0c4396
--- /dev/null
@@ -0,0 +1,122 @@
+# Code 'borrowed' from xnu/tools/tests Makefile structure.
+#
+# This provides a somewhat flexible framework (albeit, not perfect)
+# for building tests for multiple platforms using the correct toolset
+#
+# Please contact: nwertman@apple.com with any questions
+
+
+ifneq ($(SRCROOT),)
+SRCDIR=$(SRCROOT)
+else
+SRCDIR?=$(shell /bin/pwd)
+endif
+
+ifneq ($(OBJROOT),)
+OBJDIR?=$(OBJROOT)
+else
+OBJDIR?=$(SRCDIR)/build/obj
+endif
+
+ifneq ($(DSTROOT),)
+BUILDDIR?=$(DSTROOT)/AppleInternal/CoreOS/tests/$(PROJECT)
+else
+BUILDDIR?=$(SRCDIR)/build/dst
+endif
+
+#
+# Common definitions for test directories
+#
+
+XCRUN := /usr/bin/xcrun
+SDKROOT ?= macosx.internal
+
+# SDKROOT may be passed as a shorthand like "iphoneos.internal". We
+# must resolve these to a full path and override SDKROOT.
+
+SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-path)
+ifeq ($(strip $(SDKROOT)_$(SDKROOT_RESOLVED)),/_)
+SDKROOT_RESOLVED := /
+endif
+override SDKROOT = $(SDKROOT_RESOLVED)
+
+SDKVERSION := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-version)
+
+PLATFORMPATH := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-platform-path)
+PLATFORM := $(shell echo $(PLATFORMPATH) | sed 's,^.*/\([^/]*\)\.platform$$,\1,')
+
+ifeq ($(PLATFORM),watchOS)
+PLATFORM := WatchOS
+endif
+
+SUPPORTED_EMBEDDED_PLATFORMS := iPhoneOS iPhoneOSNano tvOS AppleTVOS WatchOS
+Embedded = $(if $(filter $(SUPPORTED_EMBEDDED_PLATFORMS),$(PLATFORM)),YES,NO)
+
+#
+# Deployment target flag
+#
+ifeq ($(PLATFORM),MacOSX)
+DEPLOYMENT_TARGET_FLAGS = -mmacosx-version-min=$(SDKVERSION)
+else ifeq ($(PLATFORM),WatchOS)
+DEPLOYMENT_TARGET_FLAGS = -mwatchos-version-min=$(SDKVERSION)
+else ifeq ($(PLATFORM),tvOS)
+DEPLOYMENT_TARGET_FLAGS = -mtvos-version-min=$(SDKVERSION)
+else ifeq ($(PLATFORM),AppleTVOS)
+DEPLOYMENT_TARGET_FLAGS = -mtvos-version-min=$(SDKVERSION)
+else ifneq ($(filter $(SUPPORTED_EMBEDDED_PLATFORMS),$(PLATFORM)),)
+DEPLOYMENT_TARGET_FLAGS = -miphoneos-version-min=$(SDKVERSION)
+else ifneq ($(filter $(SUPPORTED_SIMULATOR_PLATFORMS),$(PLATFORM)),)
+DEPLOYMENT_TARGET_FLAGS =
+else
+DEPLOYMENT_TARGET_FLAGS =
+endif
+
+DEPLOYMENT_TARGET_DEFINES = -DPLATFORM_$(PLATFORM)
+
+
+
+# setup the TARGETSDK and SDKROOT variables
+TARGETSDK:=$(SDKROOT)
+SDKROOTPATH:=$(SDKROOT)
+
+# make sure we have a build directory
+$(shell [ -d "$(BUILDDIR)" ] || mkdir -p $(BUILDDIR))
+
+#arch configs if not provided
+ifdef RC_ARCHS
+ARCH_CONFIGS:=$(RC_ARCHS)
+endif
+
+ifeq ($(ARCH_CONFIGS),)
+ARCH_CONFIGS:=
+ifeq ($(Embedded),YES)
+ARCH_CONFIGS:=$(shell $(XCRUN) -sdk $(TARGETSDK) otool -f -v $(SDKROOT)/usr/lib/system/libsystem_kernel.dylib | grep architecture | cut -d' '  -f 2 | tr '\n' ' ')
+else
+ARCH_CONFIGS:=x86_64 i386
+endif
+endif
+
+ARCH_CONFIGS_32:=$(filter-out %64,$(ARCH_CONFIGS))
+ARCH_CONFIGS_64:=$(filter %64,$(ARCH_CONFIGS))
+
+ARCH_FLAGS:=$(foreach argarch,$(ARCH_CONFIGS),-arch $(argarch) )
+
+
+#setup the compiler flags.
+CC:=$(shell $(XCRUN) -sdk "$(TARGETSDK)" -find clang)
+MIG:=$(shell $(XCRUN) -sdk "$(TARGETSDK)" -find mig)
+CODESIGN:=$(shell $(XCRUN) -sdk "$(TARGETSDK)" -find codesign)
+CODESIGN_ALLOCATE:=$(shell $(XCRUN) -sdk "$(TARGETSDK)" -find codesign_allocate)
+PLUTIL:=$(shell $(XCRUN) -sdk "$(TARGETSDK)" -find plutil)
+
+CFLAGS=-I$(BUILDDIR) -I. -isysroot $(SDKROOTPATH) $(ARCH_FLAGS)
+
+ifeq ($(Embedded),YES)
+TARGET_NAME=ios
+CONFIG_EMBED_DEFINE:= -DCONFIG_EMBEDDED=1
+else
+TARGET_NAME=osx
+CONFIG_EMBED_DEFINE:=
+endif
+
+MORECFLAGS=$(CONFIG_EMBED_DEFINE)
\ No newline at end of file
diff --git a/tests/rwlock-22244050.c b/tests/rwlock-22244050.c
new file mode 100644 (file)
index 0000000..a7b86e1
--- /dev/null
@@ -0,0 +1,51 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libkern/OSAtomic.h>
+
+pthread_t thr;
+pthread_rwlock_t lock;
+OSSpinLock slock = 0;
+int i = 0;
+
+void sighandler(int sig)
+{
+       if (sig == SIGUSR1) {
+               OSSpinLockLock(&slock);
+               OSSpinLockUnlock(&slock);               
+       } else {
+               // ALARM
+               fprintf(stderr, "FAIL (%d)\n", i);
+               exit(1);
+       }
+}
+
+void* thread(void *arg)
+{
+       pthread_rwlock_rdlock(&lock);
+       pthread_rwlock_unlock(&lock);
+       return NULL;
+}
+
+int main(int argc, const char *argv[])
+{
+       pthread_rwlock_init(&lock, NULL);
+       signal(SIGUSR1, sighandler);
+       signal(SIGALRM, sighandler);
+
+       alarm(30);
+
+       while (i++ < 10000) {
+               pthread_rwlock_wrlock(&lock);
+               pthread_create(&thr, NULL, thread, NULL);
+               OSSpinLockLock(&slock);
+               pthread_kill(thr, SIGUSR1);
+               pthread_rwlock_unlock(&lock);
+               OSSpinLockUnlock(&slock);
+       }
+       
+       fprintf(stderr, "PASS\n");
+       return 0;
+}