diff --git a/Makefile.am b/Makefile.am index e92529f4..96a0249e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -334,8 +334,7 @@ if ANDROID include_HEADERS += include/android-ifaddrs.h \ include/pthread-barrier.h libuv_la_SOURCES += src/unix/android-ifaddrs.c \ - src/unix/pthread-fixes.c \ - src/unix/pthread-barrier.c + src/unix/pthread-fixes.c endif if CYGWIN @@ -361,8 +360,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ - src/unix/proctitle.c \ - src/unix/pthread-barrier.c + src/unix/proctitle.c test_run_tests_LDFLAGS += -lutil endif @@ -454,7 +452,6 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \ -qFLOAT=IEEE libuv_la_LDFLAGS += -qXPLINK libuv_la_SOURCES += src/unix/pthread-fixes.c \ - src/unix/pthread-barrier.c \ src/unix/no-fsevents.c \ src/unix/os390.c \ src/unix/os390-syscalls.c \ diff --git a/android-configure b/android-configure index 7ffc035c..b5c11cd4 100755 --- a/android-configure +++ b/android-configure @@ -2,17 +2,20 @@ export TOOLCHAIN=$PWD/android-toolchain mkdir -p $TOOLCHAIN +API=${3:-24} $1/build/tools/make-standalone-toolchain.sh \ --toolchain=arm-linux-androideabi-4.9 \ --arch=arm \ --install-dir=$TOOLCHAIN \ - --platform=android-21 + --platform=android-$API \ + --force export PATH=$TOOLCHAIN/bin:$PATH export AR=arm-linux-androideabi-ar export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export LINK=arm-linux-androideabi-g++ export PLATFORM=android +export CFLAGS="-D__ANDROID_API__=$API" if [[ $2 == 'gyp' ]] then diff --git a/include/pthread-barrier.h b/include/pthread-barrier.h index 900ebedd..07db9b8a 100644 --- a/include/pthread-barrier.h +++ b/include/pthread-barrier.h @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #define PTHREAD_BARRIER_SERIAL_THREAD 0x12345 +#define UV__PTHREAD_BARRIER_FALLBACK 1 /* * To maintain ABI compatibility with diff --git a/src/unix/pthread-barrier.c b/src/unix/pthread-barrier.c deleted file mode 100644 index b6e604d4..00000000 --- a/src/unix/pthread-barrier.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright (c) 2016, Kari Tristan Helgason - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#include "uv-common.h" -#include "pthread-barrier.h" - -#include -#include - -/* TODO: support barrier_attr */ -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* barrier_attr, - unsigned count) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || count == 0) - return EINVAL; - - if (barrier_attr != NULL) - return ENOTSUP; - - b = uv__malloc(sizeof(*b)); - if (b == NULL) - return ENOMEM; - - b->in = 0; - b->out = 0; - b->threshold = count; - - if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0) - goto error2; - if ((rc = pthread_cond_init(&b->cond, NULL)) != 0) - goto error; - - barrier->b = b; - return 0; - -error: - pthread_mutex_destroy(&b->mutex); -error2: - uv__free(b); - return rc; -} - -int pthread_barrier_wait(pthread_barrier_t* barrier) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || barrier->b == NULL) - return EINVAL; - - b = barrier->b; - /* Lock the mutex*/ - if ((rc = pthread_mutex_lock(&b->mutex)) != 0) - return rc; - - /* Increment the count. If this is the first thread to reach the threshold, - wake up waiters, unlock the mutex, then return - PTHREAD_BARRIER_SERIAL_THREAD. */ - if (++b->in == b->threshold) { - b->in = 0; - b->out = b->threshold - 1; - rc = pthread_cond_signal(&b->cond); - assert(rc == 0); - - pthread_mutex_unlock(&b->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - /* Otherwise, wait for other threads until in is set to 0, - then return 0 to indicate this is not the first thread. */ - do { - if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0) - break; - } while (b->in != 0); - - /* mark thread exit */ - b->out--; - pthread_cond_signal(&b->cond); - pthread_mutex_unlock(&b->mutex); - return rc; -} - -int pthread_barrier_destroy(pthread_barrier_t* barrier) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || barrier->b == NULL) - return EINVAL; - - b = barrier->b; - - if ((rc = pthread_mutex_lock(&b->mutex)) != 0) - return rc; - - if (b->in > 0 || b->out > 0) - rc = EBUSY; - - pthread_mutex_unlock(&b->mutex); - - if (rc) - return rc; - - pthread_cond_destroy(&b->cond); - pthread_mutex_destroy(&b->mutex); - uv__free(barrier->b); - barrier->b = NULL; - return 0; -} diff --git a/src/unix/thread.c b/src/unix/thread.c index a9b5e4c0..8244f7d7 100644 --- a/src/unix/thread.c +++ b/src/unix/thread.c @@ -41,6 +41,110 @@ #define NANOSEC ((uint64_t) 1e9) +#if defined(UV__PTHREAD_BARRIER_FALLBACK) +/* TODO: support barrier_attr */ +int pthread_barrier_init(pthread_barrier_t* barrier, + const void* barrier_attr, + unsigned count) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || count == 0) + return EINVAL; + + if (barrier_attr != NULL) + return ENOTSUP; + + b = uv__malloc(sizeof(*b)); + if (b == NULL) + return ENOMEM; + + b->in = 0; + b->out = 0; + b->threshold = count; + + if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0) + goto error2; + if ((rc = pthread_cond_init(&b->cond, NULL)) != 0) + goto error; + + barrier->b = b; + return 0; + +error: + pthread_mutex_destroy(&b->mutex); +error2: + uv__free(b); + return rc; +} + +int pthread_barrier_wait(pthread_barrier_t* barrier) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || barrier->b == NULL) + return EINVAL; + + b = barrier->b; + /* Lock the mutex*/ + if ((rc = pthread_mutex_lock(&b->mutex)) != 0) + return rc; + + /* Increment the count. If this is the first thread to reach the threshold, + wake up waiters, unlock the mutex, then return + PTHREAD_BARRIER_SERIAL_THREAD. */ + if (++b->in == b->threshold) { + b->in = 0; + b->out = b->threshold - 1; + rc = pthread_cond_signal(&b->cond); + assert(rc == 0); + + pthread_mutex_unlock(&b->mutex); + return PTHREAD_BARRIER_SERIAL_THREAD; + } + /* Otherwise, wait for other threads until in is set to 0, + then return 0 to indicate this is not the first thread. */ + do { + if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0) + break; + } while (b->in != 0); + + /* mark thread exit */ + b->out--; + pthread_cond_signal(&b->cond); + pthread_mutex_unlock(&b->mutex); + return rc; +} + +int pthread_barrier_destroy(pthread_barrier_t* barrier) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || barrier->b == NULL) + return EINVAL; + + b = barrier->b; + + if ((rc = pthread_mutex_lock(&b->mutex)) != 0) + return rc; + + if (b->in > 0 || b->out > 0) + rc = EBUSY; + + pthread_mutex_unlock(&b->mutex); + + if (rc) + return rc; + + pthread_cond_destroy(&b->cond); + pthread_mutex_destroy(&b->mutex); + uv__free(barrier->b); + barrier->b = NULL; + return 0; +} +#endif + + int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { int err; pthread_attr_t* attr; diff --git a/uv.gyp b/uv.gyp index 825edd9f..b09889c7 100644 --- a/uv.gyp +++ b/uv.gyp @@ -217,8 +217,7 @@ 'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.c', - 'src/unix/pthread-barrier.c' + 'src/unix/darwin-proctitle.c' ], 'defines': [ '_DARWIN_USE_64_BIT_INODE=1', @@ -253,7 +252,6 @@ 'src/unix/linux-syscalls.h', 'src/unix/pthread-fixes.c', 'src/unix/android-ifaddrs.c', - 'src/unix/pthread-barrier.c', 'src/unix/procfs-exepath.c', 'src/unix/sysinfo-loadavg.c', 'src/unix/sysinfo-memory.c', @@ -322,7 +320,6 @@ ['OS=="os390"', { 'sources': [ 'src/unix/pthread-fixes.c', - 'src/unix/pthread-barrier.c', 'src/unix/no-fsevents.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c'