Loading...
--- Libc/Libc-1725.40.4/stdlib/FreeBSD/psort.c
+++ Libc/Libc-825.26/stdlib/FreeBSD/psort.c
@@ -42,11 +42,8 @@
#include <libkern/OSAtomic.h>
#include <sys/mman.h>
#include <errno.h>
-#include <os/lock.h>
#define __APPLE_API_PRIVATE
#include <machine/cpu_capabilities.h>
-
-#include "libc_private.h" // for LIBC_ABORT
#ifdef I_AM_PSORT_R
typedef int cmp_t(void *, const void *, const void *);
@@ -97,8 +94,10 @@
size_t es;
size_t turnoff;
dispatch_queue_t queue;
- dispatch_group_t group;
- os_unfair_lock sharedlock;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ OSSpinLock sharedlock;
+ int count;
};
static union args *
@@ -106,7 +105,7 @@
{
union args *args;
- os_unfair_lock_lock(&shared->sharedlock);
+ OSSpinLockLock(&shared->sharedlock);
if(!shared->freelist) {
struct page *page;
union args *prev;
@@ -124,17 +123,17 @@
}
args = shared->freelist;
shared->freelist = args->next;
- os_unfair_lock_unlock(&shared->sharedlock);
+ OSSpinLockUnlock(&shared->sharedlock);
return args;
}
static void
returnargs(struct shared *shared, union args *args)
{
- os_unfair_lock_lock(&shared->sharedlock);
+ OSSpinLockLock(&shared->sharedlock);
args->next = shared->freelist;
shared->freelist = args;
- os_unfair_lock_unlock(&shared->sharedlock);
+ OSSpinLockUnlock(&shared->sharedlock);
}
/*
@@ -155,7 +154,9 @@
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static inline void
-swapfunc(char *a, char *b, int n, int swaptype)
+swapfunc(a, b, n, swaptype)
+ char *a, *b;
+ int n, swaptype;
{
if(swaptype <= 1)
swapcode(long, a, b, n)
@@ -320,8 +321,8 @@
args->a = a;
args->n = r;
args->depth_limit = depth_limit;
- dispatch_group_async_f(shared->group, shared->queue, args,
- _psort_parallel);
+ OSAtomicIncrement32(&shared->count);
+ dispatch_async_f(shared->queue, args, _psort_parallel);
} else {
#ifdef I_AM_PSORT_R
_psort(a, r, es, thunk, cmp, depth_limit, NULL);
@@ -351,6 +352,11 @@
#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 */
@@ -375,7 +381,7 @@
union args *args;
bzero(&shared, sizeof(shared));
- shared.sharedlock = OS_UNFAIR_LOCK_INIT;
+ shared.sharedlock = OS_SPINLOCK_INIT;
if ((args = getargs(&shared)) != NULL) {
struct page *p, *pp;
#ifdef I_AM_PSORT_R
@@ -389,7 +395,8 @@
shared.cmp = cmp;
shared.es = es;
shared.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- shared.group = dispatch_group_create();
+ shared.cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
+ shared.mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
args->a = a;
args->n = n;
args->depth_limit = DEPTH(n);
@@ -408,11 +415,17 @@
* this purpose.
*/
shared.turnoff = isqrt(n);
+ OSAtomicIncrement32(&shared.count);
_psort_parallel(args);
/* wait for queue to drain */
- dispatch_group_wait(shared.group, DISPATCH_TIME_FOREVER);
- dispatch_release(shared.group);
+ 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);
for(p = shared.pagelist; p; p = pp) {
pp = p->next;
munmap(p, PAGESIZE);