Merge pull request #1450 from embray/cygwin/forking
Fix issues with forking on Cygwin
This commit is contained in:
commit
d31f62cf02
|
@ -304,6 +304,7 @@ endif
|
||||||
ifeq ($(OSNAME), CYGWIN_NT)
|
ifeq ($(OSNAME), CYGWIN_NT)
|
||||||
NEED_PIC = 0
|
NEED_PIC = 0
|
||||||
NO_EXPRECISION = 1
|
NO_EXPRECISION = 1
|
||||||
|
OS_CYGWIN_NT = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(OSNAME), WINNT)
|
ifneq ($(OSNAME), WINNT)
|
||||||
|
|
|
@ -40,6 +40,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(OS_CYGWIN_NT) && !defined(unlikely)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is a thread implementation for Win32 lazy implementation */
|
/* This is a thread implementation for Win32 lazy implementation */
|
||||||
|
|
||||||
/* Thread server common infomation */
|
/* Thread server common infomation */
|
||||||
|
@ -53,7 +61,7 @@ typedef struct{
|
||||||
|
|
||||||
} blas_pool_t;
|
} blas_pool_t;
|
||||||
|
|
||||||
/* We need this grobal for cheking if initialization is finished. */
|
/* We need this global for cheking if initialization is finished. */
|
||||||
int blas_server_avail = 0;
|
int blas_server_avail = 0;
|
||||||
|
|
||||||
/* Local Variables */
|
/* Local Variables */
|
||||||
|
@ -340,6 +348,11 @@ int blas_thread_init(void){
|
||||||
|
|
||||||
int exec_blas_async(BLASLONG pos, blas_queue_t *queue){
|
int exec_blas_async(BLASLONG pos, blas_queue_t *queue){
|
||||||
|
|
||||||
|
#if defined(SMP_SERVER) && defined(OS_CYGWIN_NT)
|
||||||
|
// Handle lazy re-init of the thread-pool after a POSIX fork
|
||||||
|
if (unlikely(blas_server_avail == 0)) blas_thread_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
blas_queue_t *current;
|
blas_queue_t *current;
|
||||||
|
|
||||||
current = queue;
|
current = queue;
|
||||||
|
@ -405,6 +418,11 @@ int exec_blas_async_wait(BLASLONG num, blas_queue_t *queue){
|
||||||
/* Execute Threads */
|
/* Execute Threads */
|
||||||
int exec_blas(BLASLONG num, blas_queue_t *queue){
|
int exec_blas(BLASLONG num, blas_queue_t *queue){
|
||||||
|
|
||||||
|
#if defined(SMP_SERVER) && defined(OS_CYGWIN_NT)
|
||||||
|
// Handle lazy re-init of the thread-pool after a POSIX fork
|
||||||
|
if (unlikely(blas_server_avail == 0)) blas_thread_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ALL_THREADED
|
#ifndef ALL_THREADED
|
||||||
int (*routine)(blas_arg_t *, void *, void *, double *, double *, BLASLONG);
|
int (*routine)(blas_arg_t *, void *, void *, double *, double *, BLASLONG);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,7 +74,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef OS_WINDOWS
|
#if defined(OS_WINDOWS) && !defined(OS_CYGWIN_NT)
|
||||||
#define ALLOC_WINDOWS
|
#define ALLOC_WINDOWS
|
||||||
#ifndef MEM_LARGE_PAGES
|
#ifndef MEM_LARGE_PAGES
|
||||||
#define MEM_LARGE_PAGES 0x20000000
|
#define MEM_LARGE_PAGES 0x20000000
|
||||||
|
@ -88,7 +88,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifndef OS_WINDOWS
|
#if !defined(OS_WINDOWS) || defined(OS_CYGWIN_NT)
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#ifndef NO_SYSV_IPC
|
#ifndef NO_SYSV_IPC
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
@ -323,7 +323,7 @@ void openblas_fork_handler()
|
||||||
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60035
|
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60035
|
||||||
// In the mean time build with USE_OPENMP=0 or link against another
|
// In the mean time build with USE_OPENMP=0 or link against another
|
||||||
// implementation of OpenMP.
|
// implementation of OpenMP.
|
||||||
#if !(defined(OS_WINDOWS) || defined(OS_ANDROID)) && defined(SMP_SERVER)
|
#if !((defined(OS_WINDOWS) && !defined(OS_CYGWIN_NT)) || defined(OS_ANDROID)) && defined(SMP_SERVER)
|
||||||
int err;
|
int err;
|
||||||
err = pthread_atfork ((void (*)(void)) BLASFUNC(blas_thread_shutdown), NULL, NULL);
|
err = pthread_atfork ((void (*)(void)) BLASFUNC(blas_thread_shutdown), NULL, NULL);
|
||||||
if(err != 0)
|
if(err != 0)
|
||||||
|
|
|
@ -12,7 +12,15 @@ OBJS=utest_main.o test_amax.o
|
||||||
#test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_fork.o
|
#test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_fork.o
|
||||||
|
|
||||||
ifneq ($(NO_LAPACK), 1)
|
ifneq ($(NO_LAPACK), 1)
|
||||||
OBJS += test_potrs.o
|
#OBJS += test_potrs.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef OS_WINDOWS
|
||||||
|
OBJS += test_fork.o
|
||||||
|
else
|
||||||
|
ifdef OS_CYGWIN_NT
|
||||||
|
OBJS += test_fork.o
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all : run_test
|
all : run_test
|
||||||
|
|
|
@ -31,8 +31,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
#ifndef OS_WINDOWS
|
#include "openblas_utest.h"
|
||||||
#include "common_utest.h"
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <cblas.h>
|
#include <cblas.h>
|
||||||
|
|
||||||
|
@ -54,11 +53,11 @@ void check_dgemm(double *a, double *b, double *result, double *expected, int n)
|
||||||
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, n, n, n,
|
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, n, n, n,
|
||||||
1.0, a, n, b, n, 0.0, result, n);
|
1.0, a, n, b, n, 0.0, result, n);
|
||||||
for(i = 0; i < n * n; ++i) {
|
for(i = 0; i < n * n; ++i) {
|
||||||
CU_ASSERT_DOUBLE_EQUAL(expected[i], result[i], CHECK_EPS);
|
ASSERT_DBL_NEAR_TOL(expected[i], result[i], DOUBLE_EPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_fork_safety(void)
|
CTEST(fork, safety)
|
||||||
{
|
{
|
||||||
int n = 1000;
|
int n = 1000;
|
||||||
int i;
|
int i;
|
||||||
|
@ -89,7 +88,7 @@ void test_fork_safety(void)
|
||||||
|
|
||||||
fork_pid = fork();
|
fork_pid = fork();
|
||||||
if (fork_pid == -1) {
|
if (fork_pid == -1) {
|
||||||
CU_FAIL("Failed to fork process.");
|
CTEST_ERR("Failed to fork process.");
|
||||||
} else if (fork_pid == 0) {
|
} else if (fork_pid == 0) {
|
||||||
// Compute a DGEMM product in the child process to check that the
|
// Compute a DGEMM product in the child process to check that the
|
||||||
// thread pool as been properly been reinitialized after the fork.
|
// thread pool as been properly been reinitialized after the fork.
|
||||||
|
@ -99,7 +98,7 @@ void test_fork_safety(void)
|
||||||
// recursively
|
// recursively
|
||||||
fork_pid_nested = fork();
|
fork_pid_nested = fork();
|
||||||
if (fork_pid_nested == -1) {
|
if (fork_pid_nested == -1) {
|
||||||
CU_FAIL("Failed to fork process.");
|
CTEST_ERR("Failed to fork process.");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (fork_pid_nested == 0) {
|
} else if (fork_pid_nested == 0) {
|
||||||
check_dgemm(a, b, d, c, n);
|
check_dgemm(a, b, d, c, n);
|
||||||
|
@ -108,8 +107,8 @@ void test_fork_safety(void)
|
||||||
check_dgemm(a, b, d, c, n);
|
check_dgemm(a, b, d, c, n);
|
||||||
int child_status = 0;
|
int child_status = 0;
|
||||||
pid_t wait_pid = wait(&child_status);
|
pid_t wait_pid = wait(&child_status);
|
||||||
CU_ASSERT(wait_pid == fork_pid_nested);
|
ASSERT_EQUAL(wait_pid, fork_pid_nested);
|
||||||
CU_ASSERT(WEXITSTATUS (child_status) == 0);
|
ASSERT_EQUAL(0, WEXITSTATUS (child_status));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,8 +116,7 @@ void test_fork_safety(void)
|
||||||
// Wait for the child to finish and check the exit code.
|
// Wait for the child to finish and check the exit code.
|
||||||
int child_status = 0;
|
int child_status = 0;
|
||||||
pid_t wait_pid = wait(&child_status);
|
pid_t wait_pid = wait(&child_status);
|
||||||
CU_ASSERT(wait_pid == fork_pid);
|
ASSERT_EQUAL(wait_pid, fork_pid);
|
||||||
CU_ASSERT(WEXITSTATUS (child_status) == 0);
|
ASSERT_EQUAL(0, WEXITSTATUS (child_status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in New Issue