Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with forking on Cygwin #1450

Merged
merged 3 commits into from
Feb 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.system
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ endif
ifeq ($(OSNAME), CYGWIN_NT)
NEED_PIC = 0
NO_EXPRECISION = 1
OS_CYGWIN_NT = 1
endif

ifneq ($(OSNAME), WINNT)
Expand Down
20 changes: 19 additions & 1 deletion driver/others/blas_server_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
#include <stdlib.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 */

/* Thread server common infomation */
Expand All @@ -53,7 +61,7 @@ typedef struct{

} 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;

/* Local Variables */
Expand Down Expand Up @@ -340,6 +348,11 @@ int blas_thread_init(void){

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;

current = queue;
Expand Down Expand Up @@ -405,6 +418,11 @@ int exec_blas_async_wait(BLASLONG num, blas_queue_t *queue){
/* Execute Threads */
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
int (*routine)(blas_arg_t *, void *, void *, double *, double *, BLASLONG);
#endif
Expand Down
6 changes: 3 additions & 3 deletions driver/others/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "common.h"
#include <errno.h>

#ifdef OS_WINDOWS
#if defined(OS_WINDOWS) && !defined(OS_CYGWIN_NT)
#define ALLOC_WINDOWS
#ifndef MEM_LARGE_PAGES
#define MEM_LARGE_PAGES 0x20000000
Expand All @@ -88,7 +88,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include <fcntl.h>

#ifndef OS_WINDOWS
#if !defined(OS_WINDOWS) || defined(OS_CYGWIN_NT)
#include <sys/mman.h>
#ifndef NO_SYSV_IPC
#include <sys/shm.h>
Expand Down Expand Up @@ -323,7 +323,7 @@ void openblas_fork_handler()
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60035
// In the mean time build with USE_OPENMP=0 or link against another
// 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;
err = pthread_atfork ((void (*)(void)) BLASFUNC(blas_thread_shutdown), NULL, NULL);
if(err != 0)
Expand Down
10 changes: 9 additions & 1 deletion utest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

all : run_test
Expand Down
20 changes: 9 additions & 11 deletions utest/test_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

**********************************************************************************/

#ifndef OS_WINDOWS
#include "common_utest.h"
#include "openblas_utest.h"
#include <sys/wait.h>
#include <cblas.h>

Expand All @@ -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,
1.0, a, n, b, n, 0.0, result, n);
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 i;
Expand Down Expand Up @@ -89,7 +88,7 @@ void test_fork_safety(void)

fork_pid = fork();
if (fork_pid == -1) {
CU_FAIL("Failed to fork process.");
CTEST_ERR("Failed to fork process.");
} else if (fork_pid == 0) {
// Compute a DGEMM product in the child process to check that the
// thread pool as been properly been reinitialized after the fork.
Expand All @@ -99,7 +98,7 @@ void test_fork_safety(void)
// recursively
fork_pid_nested = fork();
if (fork_pid_nested == -1) {
CU_FAIL("Failed to fork process.");
CTEST_ERR("Failed to fork process.");
exit(1);
} else if (fork_pid_nested == 0) {
check_dgemm(a, b, d, c, n);
Expand All @@ -108,17 +107,16 @@ void test_fork_safety(void)
check_dgemm(a, b, d, c, n);
int child_status = 0;
pid_t wait_pid = wait(&child_status);
CU_ASSERT(wait_pid == fork_pid_nested);
CU_ASSERT(WEXITSTATUS (child_status) == 0);
ASSERT_EQUAL(wait_pid, fork_pid_nested);
ASSERT_EQUAL(0, WEXITSTATUS (child_status));
exit(0);
}
} else {
check_dgemm(a, b, d, c, n);
// Wait for the child to finish and check the exit code.
int child_status = 0;
pid_t wait_pid = wait(&child_status);
CU_ASSERT(wait_pid == fork_pid);
CU_ASSERT(WEXITSTATUS (child_status) == 0);
ASSERT_EQUAL(wait_pid, fork_pid);
ASSERT_EQUAL(0, WEXITSTATUS (child_status));
}
}
#endif