diff --git a/tools-for-build/Makefile b/tools-for-build/Makefile index 1be91e9df..4c4355b4b 100644 --- a/tools-for-build/Makefile +++ b/tools-for-build/Makefile @@ -7,6 +7,10 @@ # provided with absolutely no warranty. See the COPYING and CREDITS # files for more information. +# it is illogical that this makefile pulls in Makefile.features, +# which is presumed not to exist, and which when it does exist causes +# confusion as to what flags should be added in for a generic C compile. +# Why do we do this??? -include genesis/Makefile.features -include Config diff --git a/tools-for-build/grovel-features.sh b/tools-for-build/grovel-features.sh index 1727e35db..4f277dfd1 100644 --- a/tools-for-build/grovel-features.sh +++ b/tools-for-build/grovel-features.sh @@ -6,29 +6,26 @@ cd ./tools-for-build > /dev/null # Assumes the presence of $1-test.c, which when built and # run should return with 104 if the feature is present. +# We presumes that the build machine matches the target machine +# in terms of a whether each feature presence test should pass. featurep() { bin="$1-test" + featurename=${2:-$1} rm -f $bin $GNUMAKE $bin -I ../src/runtime > /dev/null 2>&1 && echo "input" | ./$bin> /dev/null 2>&1 if [ "$?" -eq 104 ] then - printf " :$1" + printf " :$featurename" fi rm -f $bin } # Adding a nonexistent link library to Config.*-win32 will fail, -# so this needs its own recipe to detect the library. +# so we pass -lSynchronization to the featurep test specifically +# and not in the general make rule. +# It will get added in by Config.*-win32 only if LISP_FEATURE_SB_FUTEX. if [ "$sbcl_os" = win32 ] ; then - bin=os-provides-wakebyaddr-test - rm -f $bin - # pass -f /dev/null to use only builtin Make recipes - LOADLIBES=-lSynchronization $GNUMAKE -f /dev/null $bin > /dev/null 2>&1 - if [ "$?" -eq 0 ] - then - printf " :sb-futex" - fi - rm -f $bin + LOADLIBES=-lSynchronization featurep os-provides-wakebyaddr sb-futex fi # KLUDGE: ppc/darwin dlopen is special cased in make-config.sh, as diff --git a/tools-for-build/os-provides-wakebyaddr-test.c b/tools-for-build/os-provides-wakebyaddr-test.c index b318498f7..7b3da046d 100644 --- a/tools-for-build/os-provides-wakebyaddr-test.c +++ b/tools-for-build/os-provides-wakebyaddr-test.c @@ -1,7 +1,50 @@ #include +int mutex_word = 0; +int expect = 9; + +DWORD waiter(void* arg) { + mutex_word = expect = 2; + return WaitOnAddress(&mutex_word, &expect, 4, 100); // .1 sec max +} +DWORD waker(void* arg) { + mutex_word = 0; + WakeByAddressSingle(&mutex_word); + return 0; +} + int main() { - WakeByAddressAll((void*)&main); - return 104; + // Verify that WaitOnAddress returns right away if the mutex word has the wrong value. + int result = WaitOnAddress(&mutex_word, &expect, 4, 500); // max = .5 sec + if (!result) return 0; // what? shouldn't be an error to mismatch + + // Try really waiting + mutex_word = 9; + result = WaitOnAddress(&mutex_word, &expect, 4, 20); // wait 20 millisec + // expect a timeout + if (!(result == 0 && GetLastError()==ERROR_TIMEOUT)) return 0; + + // Simulate a lisp mutex being woken + HANDLE hWaiter, hWaker; + hWaiter = CreateThread(NULL, 0, + waiter, 0, /* function and argument */ + 0, /* flags */ + 0); /* id */ + + hWaker = CreateThread(NULL, 0, + waker, 0, /* function and argument */ + CREATE_SUSPENDED, /* flags */ + 0); /* id */ + + for (;;) { + // wait for the waiter to place itself into a wait state on the mutex + if (mutex_word == 2) break; + Sleep(10); // 10 millisec + } + // Give them some time to rendezvous + ResumeThread(hWaker); + WaitForSingleObject(hWaiter, 200); // .2 sec max + if (mutex_word == 0) return 104; + return 1; }