mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
win32: Thoroughly test for usability of WakeByAddress
This commit is contained in:
parent
544548c21c
commit
68a703e843
|
|
@ -7,6 +7,10 @@
|
||||||
# provided with absolutely no warranty. See the COPYING and CREDITS
|
# provided with absolutely no warranty. See the COPYING and CREDITS
|
||||||
# files for more information.
|
# 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 genesis/Makefile.features
|
||||||
-include Config
|
-include Config
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,29 +6,26 @@ cd ./tools-for-build > /dev/null
|
||||||
|
|
||||||
# Assumes the presence of $1-test.c, which when built and
|
# Assumes the presence of $1-test.c, which when built and
|
||||||
# run should return with 104 if the feature is present.
|
# 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() {
|
featurep() {
|
||||||
bin="$1-test"
|
bin="$1-test"
|
||||||
|
featurename=${2:-$1}
|
||||||
rm -f $bin
|
rm -f $bin
|
||||||
$GNUMAKE $bin -I ../src/runtime > /dev/null 2>&1 && echo "input" | ./$bin> /dev/null 2>&1
|
$GNUMAKE $bin -I ../src/runtime > /dev/null 2>&1 && echo "input" | ./$bin> /dev/null 2>&1
|
||||||
if [ "$?" -eq 104 ]
|
if [ "$?" -eq 104 ]
|
||||||
then
|
then
|
||||||
printf " :$1"
|
printf " :$featurename"
|
||||||
fi
|
fi
|
||||||
rm -f $bin
|
rm -f $bin
|
||||||
}
|
}
|
||||||
|
|
||||||
# Adding a nonexistent link library to Config.*-win32 will fail,
|
# 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
|
if [ "$sbcl_os" = win32 ] ; then
|
||||||
bin=os-provides-wakebyaddr-test
|
LOADLIBES=-lSynchronization featurep os-provides-wakebyaddr sb-futex
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# KLUDGE: ppc/darwin dlopen is special cased in make-config.sh, as
|
# KLUDGE: ppc/darwin dlopen is special cased in make-config.sh, as
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,50 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
WakeByAddressAll((void*)&main);
|
// Verify that WaitOnAddress returns right away if the mutex word has the wrong value.
|
||||||
return 104;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue