]> git.saurik.com Git - apple/libc.git/blobdiff - stdlib/FreeBSD/psort.c
Libc-1244.50.9.tar.gz
[apple/libc.git] / stdlib / FreeBSD / psort.c
index a95ce60d7ef9d234dc01062dd704dafb07f65eda..e9251ab945e16bea668babe5d6821f04db9ac8e2 100644 (file)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15 2008/01/14 09:21:34 das E
 #include <libkern/OSAtomic.h>
 #include <sys/mman.h>
 #include <errno.h>
+#include <os/lock.h>
 #define __APPLE_API_PRIVATE
 #include <machine/cpu_capabilities.h>
 
@@ -94,10 +95,8 @@ struct shared {
     size_t es;
     size_t turnoff;
     dispatch_queue_t queue;
-    pthread_cond_t cond;
-    pthread_mutex_t mutex;
-    OSSpinLock sharedlock;
-    int count;
+    dispatch_group_t group;
+    os_unfair_lock sharedlock;
 };
 
 static union args *
@@ -105,7 +104,7 @@ getargs(struct shared *shared)
 {
     union args *args;
 
-    OSSpinLockLock(&shared->sharedlock);
+    os_unfair_lock_lock(&shared->sharedlock);
     if(!shared->freelist) {
        struct page *page;
        union args *prev;
@@ -123,17 +122,17 @@ getargs(struct shared *shared)
     }
     args = shared->freelist;
     shared->freelist = args->next;
-    OSSpinLockUnlock(&shared->sharedlock);
+    os_unfair_lock_unlock(&shared->sharedlock);
     return args;
 }
 
 static void
 returnargs(struct shared *shared, union args *args)
 {
-    OSSpinLockLock(&shared->sharedlock);
+    os_unfair_lock_lock(&shared->sharedlock);
     args->next = shared->freelist;
     shared->freelist = args;
-    OSSpinLockUnlock(&shared->sharedlock);
+    os_unfair_lock_unlock(&shared->sharedlock);
 }
 
 /*
@@ -321,8 +320,8 @@ nevermind:
                        args->a = a;
                        args->n = r;
                        args->depth_limit = depth_limit;
-                       OSAtomicIncrement32(&shared->count);
-                       dispatch_async_f(shared->queue, args, _psort_parallel);
+                       dispatch_group_async_f(shared->group, shared->queue, args,
+                                       _psort_parallel);
                } else {
 #ifdef I_AM_PSORT_R
                        _psort(a, r, es, thunk, cmp, depth_limit, NULL);
@@ -352,11 +351,6 @@ _psort_parallel(void *x)
 #endif
                shared->cmp, args->depth_limit, shared);
        returnargs(shared, args);
-       if(OSAtomicDecrement32(&shared->count) <= 0) {
-               pthread_mutex_lock(&shared->mutex);
-               pthread_cond_signal(&shared->cond);
-               pthread_mutex_unlock(&shared->mutex);
-       }
 }
 
 /* fast, approximate integer square root */
@@ -381,7 +375,7 @@ psort(void *a, size_t n, size_t es, cmp_t *cmp)
                union args *args;
 
                bzero(&shared, sizeof(shared));
-               shared.sharedlock = OS_SPINLOCK_INIT;
+               shared.sharedlock = OS_UNFAIR_LOCK_INIT;
                if ((args = getargs(&shared)) != NULL) {
                        struct page *p, *pp;
 #ifdef I_AM_PSORT_R
@@ -395,8 +389,7 @@ psort(void *a, size_t n, size_t es, cmp_t *cmp)
                        shared.cmp = cmp;
                        shared.es = es;
                        shared.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-                       shared.cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
-                       shared.mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
+                       shared.group = dispatch_group_create();
                        args->a = a;
                        args->n = n;
                        args->depth_limit = DEPTH(n);
@@ -415,17 +408,11 @@ psort(void *a, size_t n, size_t es, cmp_t *cmp)
                         * this purpose.
                         */
                        shared.turnoff = isqrt(n);
-                       OSAtomicIncrement32(&shared.count);
                        _psort_parallel(args);
 
                        /* wait for queue to drain */
-                       pthread_mutex_lock(&shared.mutex);
-                       while(shared.count > 0)
-                               pthread_cond_wait(&shared.cond, &shared.mutex);
-
-                       pthread_mutex_unlock(&shared.mutex);
-                       pthread_mutex_destroy(&shared.mutex);
-                       pthread_cond_destroy(&shared.cond);
+                       dispatch_group_wait(shared.group, DISPATCH_TIME_FOREVER);
+                       dispatch_release(shared.group);
                        for(p = shared.pagelist; p; p = pp) {
                                pp = p->next;
                                munmap(p, PAGESIZE);