From 820ca4b34c23ef8d91edade437f0f9fd781f8b89 Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 25 Oct 2001 23:51:53 +0000 Subject: * GNUmakefile (libwsock32): Add to linker flags for WSAGetLastError() and WSASetLastError(). * Makefile (wsock32.lib): Likewise. * create.c: Minor mostly inert changes. * implement.h (PTW32_MAX): Move into here and renamed from sched.h. (PTW32_MIN): Likewise. * GNUmakefile (TEST_ICE): Define if testing internal implementation of InterlockedCompareExchange. * Makefile (TEST_ICE): Likewise. * private.c (TEST_ICE): Likewise. --- ChangeLog | 14 ++++++ GNUmakefile | 7 ++- Makefile | 3 +- create.c | 6 +-- implement.h | 18 ++++--- nonportable.c | 12 ++++- private.c | 22 ++++----- sched.c | 12 ++--- spin.c | 1 + tests/ChangeLog | 12 +++++ tests/benchtest5.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/condvar2.c | 1 - tests/condvar2_1.c | 3 +- tests/condvar3_1.c | 3 +- tests/condvar3_2.c | 3 +- tests/count1.c | 6 +-- tests/inherit1.c | 51 +++++++++++++++++-- tests/priority1.c | 63 ++++++++++++++++++++---- tests/priority2.c | 52 ++++++++++++++++++-- 19 files changed, 368 insertions(+), 62 deletions(-) create mode 100644 tests/benchtest5.c diff --git a/ChangeLog b/ChangeLog index 489aa84..a0e2fc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2001-10-25 Ross Johnson + + * GNUmakefile (libwsock32): Add to linker flags for + WSAGetLastError() and WSASetLastError(). + * Makefile (wsock32.lib): Likewise. + * create.c: Minor mostly inert changes. + * implement.h (PTW32_MAX): Move into here and renamed + from sched.h. + (PTW32_MIN): Likewise. + * GNUmakefile (TEST_ICE): Define if testing internal + implementation of InterlockedCompareExchange. + * Makefile (TEST_ICE): Likewise. + * private.c (TEST_ICE): Likewise. + 2001-10-24 Ross Johnson * attr.c (pthread_attr_setstacksize): Quell warning diff --git a/GNUmakefile b/GNUmakefile index 60bee78..2ae35f9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -32,8 +32,11 @@ CXX = g++ AR = ar OPT = -O3 +#OPT = -O3 -DTEST_ICE #OPT = -O2 -DNDEBUG -finline-functions +LFLAGS = -lwsock32 + GC_CFLAGS = -D__CLEANUP_C GCE_CFLAGS = -D__CLEANUP_CXX -x c++ -mthreads @@ -88,11 +91,11 @@ tests: $(GC_DLL): $(OBJS) - $(CC) $(OPT) -shared -o $@ $^ + $(CC) $(OPT) -shared -o $@ $^ $(LFLAGS) dlltool -k --dllname $@ --output-lib $(GC_LIB) --def pthread.def $(GCE_DLL): $(OBJS) - $(CXX) $(OPT) -mthreads -shared -o $@ $^ + $(CXX) $(OPT) -mthreads -shared -o $@ $^ $(LFLAGS) dlltool -k --dllname $@ --output-lib $(GCE_LIB) --def pthread.def clean: diff --git a/Makefile b/Makefile index 723fa2b..dacaac0 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ VSEFLAGS = /D__CLEANUP_SEH #C cleanup code VCFLAGS = /D__CLEANUP_C +#CFLAGS = /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DPTW32_BUILD /DTEST_ICE CFLAGS = /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DPTW32_BUILD OBJ= attr.obj \ @@ -84,7 +85,7 @@ install: $(DLLS) $(DLLS): $(OBJ) pthread.def cl /LD /Zi /nologo $(OBJ) \ /link /nodefaultlib:libcmt /implib:$*.lib \ - msvcrt.lib /def:pthread.def /out:$@ + msvcrt.lib wsock32.lib /def:pthread.def /out:$@ .c.obj: cl $(EHFLAGS) $(CFLAGS) -c $< diff --git a/create.c b/create.c index d36300d..2ca8705 100644 --- a/create.c +++ b/create.c @@ -160,7 +160,7 @@ pthread_create (pthread_t * tid, */ if (attr != NULL && *attr != NULL) { - (void) SetThreadPriority(thread->threadH, + (void) SetThreadPriority(threadH, PTHREAD_INHERIT_SCHED == (*attr)->inheritsched ? GetThreadPriority(GetCurrentThread()) : (*attr)->param.sched_priority ); @@ -176,7 +176,7 @@ pthread_create (pthread_t * tid, /* * This lock will force pthread_threadStart() to wait until we have - * the thread handle. + * the thread handle and have set the priority. */ (void) pthread_mutex_lock(&thread->cancelLock); @@ -214,7 +214,7 @@ pthread_create (pthread_t * tid, */ if (attr != NULL && *attr != NULL) { - (void) SetThreadPriority(thread->threadH, + (void) SetThreadPriority(threadH, PTHREAD_INHERIT_SCHED == (*attr)->inheritsched ? GetThreadPriority(GetCurrentThread()) : (*attr)->param.sched_priority ); diff --git a/implement.h b/implement.h index dfb2dba..a1cb628 100644 --- a/implement.h +++ b/implement.h @@ -380,7 +380,16 @@ enum { }; +/* Useful macros */ +#define PTW32_MAX(a,b) ((a)<(b)?(b):(a)) +#define PTW32_MIN(a,b) ((a)>(b)?(b):(a)) + + /* Declared in global.c */ +extern PTW32_INTERLOCKED_LONG (WINAPI *ptw32_interlocked_compare_exchange)(PTW32_INTERLOCKED_LPLONG, + PTW32_INTERLOCKED_LONG, + PTW32_INTERLOCKED_LONG); + extern int ptw32_processInitialized; extern pthread_key_t ptw32_selfThreadKey; extern pthread_key_t ptw32_cleanupKey; @@ -418,13 +427,8 @@ extern "C" { * ===================== * ===================== */ -PTW32_INTERLOCKED_LONG -(WINAPI *ptw32_interlocked_compare_exchange)(PTW32_INTERLOCKED_LPLONG, - PTW32_INTERLOCKED_LONG, - PTW32_INTERLOCKED_LONG); - -PTW32_INTERLOCKED_LONG -ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG ptr, +PTW32_INTERLOCKED_LONG WINAPI +ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG location, PTW32_INTERLOCKED_LONG value, PTW32_INTERLOCKED_LONG comparand); diff --git a/nonportable.c b/nonportable.c index de9dc07..27363c1 100644 --- a/nonportable.c +++ b/nonportable.c @@ -194,13 +194,15 @@ pthread_win32_process_attach_np () pthread_count++; #endif +#ifndef TEST_ICE + /* * Load KERNEL32 and try to get address of InterlockedCompareExchange */ ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); ptw32_interlocked_compare_exchange = - (PTW32_INTERLOCKED_LONG (PT_STDCALL *)(PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG)) + (PTW32_INTERLOCKED_LONG (WINAPI *)(PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress(ptw32_h_kernel32, (const TCHAR *)TEXT("InterlockedCompareExchange")); @@ -211,7 +213,7 @@ pthread_win32_process_attach_np () if (ptw32_interlocked_compare_exchange == NULL) { - ptw32_interlocked_compare_exchange = &ptw32_InterlockedCompareExchange; + ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; /* * If InterlockedCompareExchange is not being used, then free @@ -231,6 +233,12 @@ pthread_win32_process_attach_np () ptw32_h_kernel32 = 0; } +#else /* TEST_ICE */ + + ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; + +#endif /* TEST_ICE */ + return result; } diff --git a/private.c b/private.c index f97d9f4..ffe44e1 100644 --- a/private.c +++ b/private.c @@ -1033,8 +1033,8 @@ ptw32_pop_cleanup_all(int execute) * This can't be inlined because we need to know it's address so that * we can call it through a pointer. */ -PTW32_INTERLOCKED_LONG -ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG ptr, +PTW32_INTERLOCKED_LONG WINAPI +ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG location, PTW32_INTERLOCKED_LONG value, PTW32_INTERLOCKED_LONG comparand) { @@ -1042,13 +1042,13 @@ ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG ptr, #if defined(_M_IX86) || defined(_X86_) -#if defined(__MSVCRT__) +#if defined(_MSC_VER) _asm { PUSH ecx PUSH edx - MOV ecx,dword ptr [ptr] ; Load ECX with plTarget - MOV edx,dword ptr [value] ; Load EDX with lValue + MOV ecx,dword ptr [location] + MOV edx,dword ptr [value] MOV eax,dword ptr [comparand] LOCK CMPXCHG dword ptr [ecx],edx ; if (EAX == [ECX]), ; [ECX] = EDX @@ -1064,12 +1064,12 @@ ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG ptr, __asm__ ( "lock\n\t" - "cmpxchgl %3,(%0)" /* if (EAX == [ptr]), */ - /* [ptr] = value */ - /* else */ - /* EAX = [ptr] */ - :"=r" (ptr), "=a" (result) - :"0" (ptr), "q" (value), "a" (comparand) + "cmpxchgl %3,(%0)" /* if (EAX == [location]), */ + /* [location] = value */ + /* else */ + /* EAX = [location] */ + :"=r" (location), "=a" (result) + :"0" (location), "q" (value), "a" (comparand) : "memory" ); #endif diff --git a/sched.c b/sched.c index 8ef502f..a964d16 100644 --- a/sched.c +++ b/sched.c @@ -240,10 +240,6 @@ pthread_getschedparam(pthread_t thread, int *policy, */ -#define sched_Max(a,b) ((a)<(b)?(b):(a)) -#define sched_Min(a,b) ((a)>(b)?(b):(a)) - - int sched_get_priority_max(int policy) { @@ -254,10 +250,10 @@ sched_get_priority_max(int policy) #if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL) /* WinCE? */ - return sched_Max(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); + return PTW32_MAX(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); #else /* This is independent of scheduling policy in Win32. */ - return sched_Max(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL) + return PTW32_MAX(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); #endif } @@ -272,10 +268,10 @@ sched_get_priority_min(int policy) #if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL) /* WinCE? */ - return sched_Min(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); + return PTW32_MIN(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); #else /* This is independent of scheduling policy in Win32. */ - return sched_Min(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); + return PTW32_MIN(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL); #endif } diff --git a/spin.c b/spin.c index 09c5031..070e3ff 100644 --- a/spin.c +++ b/spin.c @@ -110,6 +110,7 @@ pthread_spin_init(pthread_spinlock_t *lock, int pshared) #endif /* _POSIX_THREAD_PROCESS_SHARED */ } + } s = (pthread_spinlock_t) calloc(1, sizeof(*s)); diff --git a/tests/ChangeLog b/tests/ChangeLog index 93e6342..77d81db 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,15 @@ +2001-10-25 Ross Johnson + + * condvar2.c: Remove reference to cv->nWaitersUnblocked. + * condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * count1.c: lower NUMTHREADS from 60 to 30. + * inherit1.c: Determine valid priority values and then + assert values returned by POSIX routines are the same. + * priority1.c: Likewise. + * priority2.c: Likewise. + 2001-07-12 Ross Johnson * barrier5.c: Assert that precisely one thread receives diff --git a/tests/benchtest5.c b/tests/benchtest5.c new file mode 100644 index 0000000..0bdaf90 --- /dev/null +++ b/tests/benchtest5.c @@ -0,0 +1,141 @@ +/* + * benchtest5.c + * + * Measure time taken to complete an elementary operation. + * + * - Semaphore + * Single thread iteration over post/wait for a semaphore. + */ + +#include "test.h" +#include + +#ifdef __GNUC__ +#include +#endif + +#include "benchtest.h" + +#define ITERATIONS 10000000L + +sem_t sema; + +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void +reportTest (char * testNameString) +{ + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-40s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + printf( "========================================================================\n"); + printf( "\nOperations on a semaphore.\n%ld iterations\n\n", + ITERATIONS); + printf( "%-40s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == 1); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + /* + * Now we can start the actual tests + */ + assert(sem_init(&sema, 0, 0) == 0); + TESTSTART + assert(sem_post(&sema) == 0); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("Post"); + + + assert(sem_init(&sema, 0, ITERATIONS) == 0); + TESTSTART + assert(sem_wait(&sema) == 0); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("Wait without blocking"); + + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == 1); + assert(1 == 1); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + /* + * Now we can start the actual tests + */ + assert(sem_init(&sema, 0, 0) == 0); + TESTSTART + assert(sem_post(&sema) == 0); + assert(sem_wait(&sema) == 0); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("Post then Wait without blocking"); + + + assert(sem_init(&sema, 0, 1) == 0); + TESTSTART + assert(sem_wait(&sema) == 0); + assert(sem_post(&sema) == 0); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("Wait then Post without blocking"); + + printf( "========================================================================\n"); + + /* + * End of tests. + */ + + return 0; +} diff --git a/tests/condvar2.c b/tests/condvar2.c index 369cef6..211f0ec 100644 --- a/tests/condvar2.c +++ b/tests/condvar2.c @@ -80,7 +80,6 @@ main() { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); - fprintf(stderr, "\tWaitersUnblocked = %ld\n", cv->nWaitersUnblocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); diff --git a/tests/condvar2_1.c b/tests/condvar2_1.c index feae128..32bf9fc 100644 --- a/tests/condvar2_1.c +++ b/tests/condvar2_1.c @@ -49,7 +49,7 @@ static pthread_mutex_t mutex; static struct timespec abstime = { 0, 0 }; enum { - NUMTHREADS = 60 + NUMTHREADS = 30 }; void * @@ -108,7 +108,6 @@ main() { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); - fprintf(stderr, "\tWaitersUnblocked = %ld\n", cv->nWaitersUnblocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); diff --git a/tests/condvar3_1.c b/tests/condvar3_1.c index ea5f33f..4cf460a 100644 --- a/tests/condvar3_1.c +++ b/tests/condvar3_1.c @@ -56,7 +56,7 @@ static int awoken = 0; static int waiting = 0; enum { - NUMTHREADS = 60 + NUMTHREADS = 30 }; void * @@ -146,7 +146,6 @@ main() { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); - fprintf(stderr, "\tWaitersUnblocked = %ld\n", cv->nWaitersUnblocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); diff --git a/tests/condvar3_2.c b/tests/condvar3_2.c index e5f451b..e2ccfd0 100644 --- a/tests/condvar3_2.c +++ b/tests/condvar3_2.c @@ -54,7 +54,7 @@ static int timedout = 0; static int awoken = 0; enum { - NUMTHREADS = 60 + NUMTHREADS = 30 }; void * @@ -140,7 +140,6 @@ main() { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); - fprintf(stderr, "\tWaitersUnblocked = %ld\n", cv->nWaitersUnblocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); diff --git a/tests/count1.c b/tests/count1.c index ae30ed0..b00f7b3 100644 --- a/tests/count1.c +++ b/tests/count1.c @@ -7,11 +7,7 @@ #include "test.h" -#if ! defined (__MINGW32__) || defined (__MSVCRT__) -#define NUMTHREADS (60) -#else -#define NUMTHREADS (59) -#endif +#define NUMTHREADS (30) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t threads[NUMTHREADS]; diff --git a/tests/inherit1.c b/tests/inherit1.c index a909eb7..2263cc6 100644 --- a/tests/inherit1.c +++ b/tests/inherit1.c @@ -41,6 +41,16 @@ #include "test.h" +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; + + void * func(void * arg) { int policy; @@ -50,6 +60,32 @@ void * func(void * arg) return (void *) param.sched_priority; } + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO); + SetThreadPriority(threadH, prioSet); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + } + + return (void *) 0; +} + + int main() { @@ -59,29 +95,36 @@ main() void * result = NULL; struct sched_param param; struct sched_param mainParam; - int maxPrio; - int minPrio; int prio; int policy; int inheritsched = -1; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + assert(pthread_attr_init(&attr) == 0); assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0); assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0); assert(inheritsched == PTHREAD_INHERIT_SCHED); - for (prio = minPrio; prio < maxPrio; prio++) + for (prio = minPrio; prio <= maxPrio; prio++) { mainParam.sched_priority = prio; + /* Set the thread's priority to a known initial value. */ + SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO); + /* Change the main thread priority */ assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0); assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0); assert(policy == SCHED_OTHER); - assert(mainParam.sched_priority == prio); + assert(mainParam.sched_priority == + validPriorities[prio+(PTW32TEST_MAXPRIORITIES/2)]); for (param.sched_priority = prio; param.sched_priority <= maxPrio; diff --git a/tests/priority1.c b/tests/priority1.c index a311028..1ec9f4d 100644 --- a/tests/priority1.c +++ b/tests/priority1.c @@ -41,16 +41,52 @@ #include "test.h" -void * func(void * arg) +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; + +void * +func(void * arg) { int policy; struct sched_param param; + pthread_t threadID = pthread_self(); - assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); + assert(pthread_getschedparam(threadID, &policy, ¶m) == 0); assert(policy == SCHED_OTHER); - return (void *) param.sched_priority; + return (void *) (param.sched_priority); +} + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO); + SetThreadPriority(threadH, prioSet); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + } + + return (void *) 0; } - + + int main() { @@ -58,20 +94,29 @@ main() pthread_attr_t attr; void * result = NULL; struct sched_param param; - int maxPrio = sched_get_priority_max(SCHED_OTHER); - int minPrio = sched_get_priority_min(SCHED_OTHER); + + assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); + assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); assert(pthread_attr_init(&attr) == 0); assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0); + /* Set the thread's priority to a known initial value. */ + SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()), + PTW32TEST_THREAD_INIT_PRIO); + for (param.sched_priority = minPrio; param.sched_priority <= maxPrio; param.sched_priority++) { assert(pthread_attr_setschedparam(&attr, ¶m) == 0); - assert(pthread_create(&t, &attr, func, NULL) == 0); - pthread_join(t, &result); - assert((int) result == param.sched_priority); + assert(pthread_create(&t, &attr, func, (void *) &attr) == 0); + assert(pthread_join(t, &result) == 0); + assert((int) result == + validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); } return 0; diff --git a/tests/priority2.c b/tests/priority2.c index 4dcf385..06a5a13 100644 --- a/tests/priority2.c +++ b/tests/priority2.c @@ -41,6 +41,14 @@ #include "test.h" +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; pthread_mutex_t startMx = PTHREAD_MUTEX_INITIALIZER; void * func(void * arg) @@ -54,15 +62,52 @@ void * func(void * arg) assert(policy == SCHED_OTHER); return (void *) param.sched_priority; } + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO); + SetThreadPriority(threadH, prioSet); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + } + + return (void *) 0; +} + + int main() { pthread_t t; void * result = NULL; struct sched_param param; - int maxPrio = sched_get_priority_max(SCHED_OTHER); - int minPrio = sched_get_priority_min(SCHED_OTHER); + + assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); + assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + + /* Set the thread's priority to a known initial value. + * If the new priority is invalid then the threads priority + * is unchanged from the previous value. + */ + SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()), + PTW32TEST_THREAD_INIT_PRIO); for (param.sched_priority = minPrio; param.sched_priority <= maxPrio; @@ -73,7 +118,8 @@ main() assert(pthread_setschedparam(t, SCHED_OTHER, ¶m) == 0); assert(pthread_mutex_unlock(&startMx) == 0); pthread_join(t, &result); - assert((int) result == param.sched_priority); + assert((int) result == + validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); } return 0; -- cgit v1.2.3