diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Bmakefile | 10 | ||||
-rw-r--r-- | tests/ChangeLog | 19 | ||||
-rw-r--r-- | tests/GNUmakefile | 53 | ||||
-rw-r--r-- | tests/Makefile | 50 | ||||
-rwxr-xr-x | tests/SIZES.GC | 13 | ||||
-rwxr-xr-x | tests/SIZES.GCE | 13 | ||||
-rw-r--r-- | tests/Wmakefile | 7 | ||||
-rw-r--r-- | tests/barrier5.c | 46 | ||||
-rw-r--r-- | tests/once3.c | 11 | ||||
-rw-r--r-- | tests/self1.c | 4 | ||||
-rw-r--r-- | tests/stress1.c | 4 | ||||
-rw-r--r-- | tests/test.h | 4 |
12 files changed, 165 insertions, 69 deletions
diff --git a/tests/Bmakefile b/tests/Bmakefile index 9a2c2b4..169f42c 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -40,6 +40,7 @@ MKDIR = mkdir TOUCH = echo Passed > ECHO = @echo +# The next path is relative to $BUILD_DIR QAPC = ..\QueueUserAPCEx\User\quserex.dll CPHDR = pthread.h semaphore.h sched.h @@ -96,7 +97,7 @@ PASSES= loadfree.pass \ self2.pass \ cancel1.pass cancel2.pass \ semaphore4.pass semaphore4t.pass semaphore5.pass \ - barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ condvar4.pass condvar5.pass condvar6.pass \ @@ -114,7 +115,8 @@ PASSES= loadfree.pass \ cancel9.pass create3.pass stress1.pass BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ + benchtest6.bench help: @ $(ECHO) Run one of the following command lines: @@ -191,7 +193,7 @@ BCX-bench: @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< $(COPYFILES): - @ $(ECHO) Copying $@ + @ $(ECHO) Copying $(BUILD_DIR)\$@ @ $(CP) $(BUILD_DIR)\$@ . pthread.dll: $(CPDLL) @@ -221,11 +223,13 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: +benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass barrier3.pass: barrier2.pass barrier4.pass: barrier3.pass barrier5.pass: barrier4.pass +barrier6.pass: barrier5.pass cancel1.pass: create1.pass cancel2.pass: cancel1.pass cancel3.pass: context1.pass diff --git a/tests/ChangeLog b/tests/ChangeLog index 30f6ccb..1bdcc43 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,22 @@ +2010-06-19 Ross Johnson <Ross dot Johnson at homemail dot com dot au> + + * Makefile (STATICRESULTS): Add all tests into suite for static + library. + * GNUmakefile (STATICTESTS): Likewise, except for openmp1.c which + has a DLL dependency. + +2010-02-04 Ross Johnson <Ross dot Johnson at homemail dot com dot au> + + * openmp1.c: New; for libgomp compatibility (OpenMP). + * barrier5.c: Rewrite after changes to barriers. + * barrier6.c: New. + * benchtest6.c: New; timing barriers. + * GNUMakefile: Update for new tests. + * Makefile: Ditto. + * BMakefile: Ditto. + * once3.c: Improve cancelation testing. + * stress1.c: Fix comment. + 2007-01-04 Ross Johnson <Ross dot Johnson at homemail dot com dot au> * context1.c: Include context.h from library sources and remove diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 1762b6c..c431f2f 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -44,15 +44,15 @@ CAT = cat MKDIR = mkdir TOUCH = echo Passed > ECHO = @echo -MAKE = make +MAKE = make -k # # Mingw32 # XXCFLAGS = -XXLIBS = -lws2_32 +XXLIBS = -lws2_32 -lgomp #CFLAGS = -O3 -UNDEBUG -Wall $(XXCFLAGS) -CFLAGS = -g -UNDEBUG -Wall $(XXCFLAGS) +CFLAGS = -O3 -fopenmp -UNDEBUG -Wall $(XXCFLAGS) BUILD_DIR = .. INCLUDES = -I. @@ -67,6 +67,7 @@ GCX = $(TEST)$(DLL_VER) HDR = pthread.h semaphore.h sched.h LIB = libpthread$(GCX).a DLL = pthread$(GCX).dll +# The next path is relative to $BUILD_DIR QAPC = ../QueueUserAPCEx/User/quserex.dll COPYFILES = $(HDR) $(LIB) $(DLL) $(QAPC) @@ -74,7 +75,8 @@ COPYFILES = $(HDR) $(LIB) $(DLL) $(QAPC) # If a test case returns a non-zero exit code to the shell, make will # stop. -TESTS = sizes loadfree \ +TESTS = \ + sizes loadfree \ self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ semaphore1 semaphore2 semaphore3 \ condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ @@ -90,8 +92,8 @@ TESTS = sizes loadfree \ once1 once2 once3 once4 self2 \ cancel1 cancel2 \ semaphore4 semaphore4t semaphore5 \ - barrier1 barrier2 barrier3 barrier4 barrier5 \ - tsd1 tsd2 delay1 delay2 eyal1 \ + barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ + tsd1 tsd2 openmp1 delay1 delay2 eyal1 \ condvar3 condvar3_1 condvar3_2 condvar3_3 \ condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ errno1 \ @@ -109,10 +111,39 @@ STRESSTESTS = \ stress1 BENCHTESTS = \ - benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 + benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 benchtest6 STATICTESTS = \ - self1 + sizes \ + self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ + semaphore1 semaphore2 semaphore3 \ + condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ + create1 create2 reuse1 reuse2 equal1 \ + kill1 valid1 valid2 \ + exit2 exit3 exit4 exit5 \ + join0 join1 detach1 join2 join3 \ + mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ + mutex4 mutex6 mutex6n mutex6e mutex6r \ + mutex6s mutex6es mutex6rs \ + mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ + count1 \ + once1 once2 once3 once4 self2 \ + cancel1 cancel2 \ + semaphore4 semaphore4t semaphore5 \ + barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ + tsd1 tsd2 delay1 delay2 eyal1 \ + condvar3 condvar3_1 condvar3_2 condvar3_3 \ + condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ + errno1 \ + rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \ + rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \ + context1 cancel3 cancel4 cancel5 cancel6a cancel6d \ + cancel7 cancel8 \ + cleanup0 cleanup1 cleanup2 cleanup3 \ + priority1 priority2 inherit1 \ + spin1 spin2 spin3 spin4 \ + exception1 exception2 exception3 \ + cancel9 create3 stress1 PASSES = $(TESTS:%=%.pass) BENCHRESULTS = $(BENCHTESTS:%=%.bench) @@ -184,12 +215,14 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: +benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass barrier3.pass: barrier2.pass barrier4.pass: barrier3.pass barrier5.pass: barrier4.pass +barrier6.pass: barrier5.pass cancel1.pass: create1.pass cancel2.pass: cancel1.pass cancel2_1.pass: cancel2.pass @@ -277,6 +310,7 @@ once1.pass: create1.pass once2.pass: once1.pass once3.pass: once2.pass once4.pass: once3.pass +openmp1.pass: tsd2.pass priority1.pass: join1.pass priority2.pass: priority1.pass barrier3.pass reuse1.pass: create2.pass @@ -345,7 +379,7 @@ sizes.pass: sizes.exe @ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES) $(COPYFILES): - @ $(ECHO) Copying $@ + @ $(ECHO) Copying $(BUILD_DIR)/$@ @ $(CP) $(BUILD_DIR)/$@ . benchlib.o: benchlib.c @@ -366,6 +400,7 @@ clean: - $(RM) *.e - $(RM) *.i - $(RM) *.o + - $(RM) *.so - $(RM) *.obj - $(RM) *.pdb - $(RM) *.exe diff --git a/tests/Makefile b/tests/Makefile index 57fd2f4..c3342be 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -40,6 +40,7 @@ MKDIR = mkdir TOUCH = echo Passed > ECHO = @echo +# The next path is relative to $BUILD_DIR QAPC = ..\QueueUserAPCEx\User\quserex.dll CPHDR = pthread.h semaphore.h sched.h @@ -67,7 +68,7 @@ VCXFLAGS = /GX /TP /D__CLEANUP_C CPLIB = $(VCLIB) CPDLL = $(VCDLL) -CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Zi +CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi LFLAGS= /INCREMENTAL:NO INCLUDES=-I. BUILD_DIR=.. @@ -100,7 +101,7 @@ PASSES= sizes.pass loadfree.pass \ self2.pass \ cancel1.pass cancel2.pass \ semaphore4.pass semaphore4t.pass semaphore5.pass \ - barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ condvar4.pass condvar5.pass condvar6.pass \ @@ -119,13 +120,50 @@ PASSES= sizes.pass loadfree.pass \ cancel9.pass create3.pass stress1.pass BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ + benchtest6.bench STRESSRESULTS = \ stress1.stress STATICRESULTS = \ - self1.pass + sizes.pass \ + self1.pass mutex5.pass \ + mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass \ + semaphore1.pass semaphore2.pass semaphore3.pass \ + mutex2.pass mutex3.pass \ + mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass \ + condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass \ + exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass \ + kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.pass join2.pass join3.pass \ + mutex4.pass mutex6.pass mutex6n.pass mutex6e.pass mutex6r.pass \ + mutex6s.pass mutex6es.pass mutex6rs.pass \ + mutex7.pass mutex7n.pass mutex7e.pass mutex7r.pass \ + mutex8.pass mutex8n.pass mutex8e.pass mutex8r.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ + tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ + condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ + condvar4.pass condvar5.pass condvar6.pass \ + condvar7.pass condvar8.pass condvar9.pass \ + errno1.pass \ + rwlock1.pass rwlock2.pass rwlock3.pass rwlock4.pass \ + rwlock5.pass rwlock6.pass rwlock7.pass rwlock8.pass \ + rwlock2_t.pass rwlock3_t.pass rwlock4_t.pass rwlock5_t.pass rwlock6_t.pass rwlock6_t2.pass \ + context1.pass \ + cancel3.pass cancel4.pass cancel5.pass cancel6a.pass cancel6d.pass \ + cancel7.pass cancel8.pass \ + cleanup0.pass cleanup1.pass cleanup2.pass cleanup3.pass \ + priority1.pass priority2.pass inherit1.pass \ + spin1.pass spin2.pass spin3.pass spin4.pass \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass create3.pass stress1.pass help: @ $(ECHO) Run one of the following command lines: @@ -245,7 +283,7 @@ VC-static: @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< $(COPYFILES): - @ $(ECHO) Copying $@ + @ $(ECHO) Copying $(BUILD_DIR)\$@ @ $(CP) $(BUILD_DIR)\$@ . pthread.dll: $(CPDLL) @@ -274,12 +312,14 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: +benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass barrier3.pass: barrier2.pass barrier4.pass: barrier3.pass barrier5.pass: barrier4.pass +barrier6.pass: barrier5.pass cancel1.pass: create1.pass cancel2.pass: cancel1.pass cancel3.pass: context1.pass diff --git a/tests/SIZES.GC b/tests/SIZES.GC index ae09a84..9252581 100755 --- a/tests/SIZES.GC +++ b/tests/SIZES.GC @@ -1,20 +1,21 @@ Sizes of pthreads-win32 structs ------------------------------- - pthread_t_ 124 + pthread_t 8
+ ptw32_thread_t 140
pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 + sem_t_ 12
+ pthread_mutex_t_ 24
pthread_mutexattr_t_ 8 pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 + pthread_barrier_t_ 36
pthread_barrierattr_t_ 4 pthread_key_t_ 16 pthread_cond_t_ 32 pthread_condattr_t_ 4 pthread_rwlock_t_ 28 pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 + pthread_once_t_ 16
ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16
sched_param 4 ------------------------------- - diff --git a/tests/SIZES.GCE b/tests/SIZES.GCE index f36d0d2..a9ea64d 100755 --- a/tests/SIZES.GCE +++ b/tests/SIZES.GCE @@ -1,20 +1,21 @@ Sizes of pthreads-win32 structs ------------------------------- - pthread_t_ 60 + pthread_t 8
+ ptw32_thread_t 76
pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 + sem_t_ 12
+ pthread_mutex_t_ 24
pthread_mutexattr_t_ 8 pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 + pthread_barrier_t_ 36
pthread_barrierattr_t_ 4 pthread_key_t_ 16 pthread_cond_t_ 32 pthread_condattr_t_ 4 pthread_rwlock_t_ 28 pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 + pthread_once_t_ 16
ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16
sched_param 4 ------------------------------- - diff --git a/tests/Wmakefile b/tests/Wmakefile index 83cd34b..a4b64a3 100644 --- a/tests/Wmakefile +++ b/tests/Wmakefile @@ -68,7 +68,10 @@ LFLAGS= INCLUDES= -i=. BUILD_DIR=.. -COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) +# The next path is relative to $BUILD_DIR +QAPC = ..\QueueUserAPCEx\User\quserex.dll + +COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC) TEST = EHFLAGS = @@ -188,7 +191,7 @@ sizes.pass: sizes.exe @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< $(COPYFILES): .SYMBOLIC - @ $(ECHO) Copying $@ + @ $(ECHO) Copying $(BUILD_DIR)\$@ @ $(CP) $(BUILD_DIR)\$@ . pthread.dll: diff --git a/tests/barrier5.c b/tests/barrier5.c index 5b598c9..851398c 100644 --- a/tests/barrier5.c +++ b/tests/barrier5.c @@ -33,47 +33,36 @@ * * -------------------------------------------------------------------------- * - * Declare a single barrier object, set up a sequence of - * barrier points to prove lockstepness, and then destroy it. - * + * Set up a series of barriers at different heights and test various numbers + * of threads accessing, especially cases where there are more threads than the + * barrier height (count), i.e. test contention when the barrier is released. */ #include "test.h" enum { - NUMTHREADS = 16, - BARRIERS = 10000 + NUMTHREADS = 15, + HEIGHT = 10, + BARRIERMULTIPLE = 1000 }; pthread_barrier_t barrier = NULL; pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; - -int barrierReleases[BARRIERS + 1]; +LONG totalThreadCrossings; void * -func(void * barrierHeight) +func(void * crossings) { - int i; int result; int serialThreads = 0; - for (i = 1; i < BARRIERS; i++) + while ((LONG)crossings >= (LONG)InterlockedIncrement((LPLONG)&totalThreadCrossings)) { result = pthread_barrier_wait(&barrier); - assert(pthread_mutex_lock(&mx) == 0); - barrierReleases[i]++; - assert(pthread_mutex_unlock(&mx) == 0); - /* - * Confirm the correct number of releases from the previous - * barrier. We can't do the current barrier yet because there may - * still be threads waking up. - */ if (result == PTHREAD_BARRIER_SERIAL_THREAD) { serialThreads++; - assert(barrierReleases[i - 1] == (int) barrierHeight); - barrierReleases[i + 1] = 0; } else if (result != 0) { @@ -92,20 +81,23 @@ main() int i, j; int result; int serialThreadsTotal; + LONG Crossings; pthread_t t[NUMTHREADS + 1]; for (j = 1; j <= NUMTHREADS; j++) { - printf("Barrier height = %d\n", j); + int height = j<HEIGHT?j:HEIGHT; + + totalThreadCrossings = 0; + Crossings = height * BARRIERMULTIPLE; - barrierReleases[0] = j; - barrierReleases[1] = 0; + printf("Threads=%d, Barrier height=%d\n", j, height); - assert(pthread_barrier_init(&barrier, NULL, j) == 0); + assert(pthread_barrier_init(&barrier, NULL, height) == 0); for (i = 1; i <= j; i++) { - assert(pthread_create(&t[i], NULL, func, (void *) j) == 0); + assert(pthread_create(&t[i], NULL, func, (void *) Crossings) == 0); } serialThreadsTotal = 0; @@ -115,9 +107,7 @@ main() serialThreadsTotal += result; } - assert(serialThreadsTotal == BARRIERS - 1); - assert(barrierReleases[BARRIERS - 1] == j); - assert(barrierReleases[BARRIERS] == 0); + assert(serialThreadsTotal == BARRIERMULTIPLE); assert(pthread_barrier_destroy(&barrier) == 0); } diff --git a/tests/once3.c b/tests/once3.c index 51d2daa..c706f80 100644 --- a/tests/once3.c +++ b/tests/once3.c @@ -34,7 +34,7 @@ * -------------------------------------------------------------------------- * * Create several pthread_once objects and channel several threads - * through each. Make the init_routine cancelable and cancel them + * through each. Make the init_routine cancelable and cancel them with * waiters waiting. * * Depends on API functions: @@ -45,6 +45,8 @@ * pthread_once() */ +/* #define ASSERT_TRACE */ + #include "test.h" #define NUM_THREADS 100 /* Targeting each once control */ @@ -66,6 +68,7 @@ myfunc(void) { EnterCriticalSection(&numOnce.cs); numOnce.i++; + assert(numOnce.i > 0); LeaveCriticalSection(&numOnce.cs); /* Simulate slow once routine so that following threads pile up behind it */ Sleep(10); @@ -78,11 +81,11 @@ mythread(void * arg) { /* * Cancel every thread. These threads are deferred cancelable only, so - * only the thread performing the init_routine will see it (there are + * only the thread performing the once routine (my_func) will see it (there are * no other cancelation points here). The result will be that every thread - * eventually cancels only when it becomes the new initter. + * eventually cancels only when it becomes the new once thread. */ - pthread_cancel(pthread_self()); + assert(pthread_cancel(pthread_self()) == 0); assert(pthread_once(&once[(int) arg], myfunc) == 0); EnterCriticalSection(&numThreads.cs); numThreads.i++; diff --git a/tests/self1.c b/tests/self1.c index 59498d9..aa08328 100644 --- a/tests/self1.c +++ b/tests/self1.c @@ -54,7 +54,7 @@ main(int argc, char * argv[]) */ pthread_t self; -#ifdef PTW32_STATIC_LIB +#if defined(PTW32_STATIC_LIB) && !(defined(_MSC_VER) || defined(__MINGW32__)) pthread_win32_process_attach_np(); #endif @@ -62,7 +62,7 @@ main(int argc, char * argv[]) assert(self.p != NULL); -#ifdef PTW32_STATIC_LIB +#if defined(PTW32_STATIC_LIB) && !(defined(_MSC_VER) || defined(__MINGW32__)) pthread_win32_process_detach_np(); #endif return 0; diff --git a/tests/stress1.c b/tests/stress1.c index efaf445..3588361 100644 --- a/tests/stress1.c +++ b/tests/stress1.c @@ -54,7 +54,7 @@ * - Master and slave do battle continuously until main tells them to stop. * - Afterwards, the CV must be successfully destroyed (will return an * error if there are waiters (including any internal semaphore waiters, - * which, if there are, cannot not be real waiters). + * which, if there are, cannot be real waiters). * * Environment: * - @@ -97,7 +97,7 @@ static int timeoutCount = 0; static int signalsTakenCount = 0; static int signalsSent = 0; static int bias = 0; -static int timeout = 10;
// Must be > 0 +static int timeout = 10; // Must be > 0 enum { CTL_STOP = -1 diff --git a/tests/test.h b/tests/test.h index 3132c69..56fa335 100644 --- a/tests/test.h +++ b/tests/test.h @@ -56,7 +56,7 @@ #endif -char * error_string[] = { +const char * error_string[] = { "ZERO_or_EOK", "EPERM", "ENOFILE_or_ENOENT", @@ -99,7 +99,7 @@ char * error_string[] = { "ENOLCK", "ENOSYS", "ENOTEMPTY", - "EILSEQ", + "EILSEQ" }; /* |