+typedef uintptr_t spin_lock_t;
+extern void _spin_lock(spin_lock_t *lockp);
+extern int _spin_lock_try(spin_lock_t *lockp);
+extern void _spin_unlock(spin_lock_t *lockp);
+
+typedef struct SyncData {
+ struct SyncData* nextData;
+ id object;
+ int threadCount; // number of THREADS using this block
+ pthread_mutex_t mutex;
+ pthread_cond_t conditionVariable;
+} SyncData;
+
+typedef struct {
+ SyncData *data;
+ unsigned int lockCount; // number of times THIS THREAD locked this block
+} SyncCacheItem;
+
+typedef struct SyncCache {
+ unsigned int allocated;
+ unsigned int used;
+ SyncCacheItem list[0];
+} SyncCache;
+
+typedef struct {
+ spin_lock_t lock;
+ SyncData *data;
+} SyncList __attribute__((aligned(64)));
+// aligned to put locks on separate cache lines
+
+// Use multiple parallel lists to decrease contention among unrelated objects.
+#define COUNT 16
+#define HASH(obj) ((((uintptr_t)(obj)) >> 5) & (COUNT - 1))
+#define LOCK_FOR_OBJ(obj) sDataLists[HASH(obj)].lock
+#define LIST_FOR_OBJ(obj) sDataLists[HASH(obj)].data
+static SyncList sDataLists[COUNT];
+
+
+enum usage { ACQUIRE, RELEASE, CHECK };
+
+static SyncCache *fetch_cache(BOOL create)