mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
255 lines
6.7 KiB
C
255 lines
6.7 KiB
C
/*=============================================================================
|
|
**
|
|
** Source: threadpriority.c
|
|
**
|
|
** Purpose: Test to ensure GetThreadPriority works properly.
|
|
**
|
|
** Dependencies: PAL_Initialize
|
|
** PAL_Terminate
|
|
** Fail
|
|
** CreateThread
|
|
** WaitForSingleObject
|
|
** GetLastError
|
|
** time()
|
|
**
|
|
**
|
|
** Copyright (c) 2002 Microsoft Corporation. All rights reserved.
|
|
**
|
|
** The use and distribution terms for this software are contained in the file
|
|
** named license.txt, which can be found in the root of this distribution.
|
|
** By using this software in any fashion, you are agreeing to be bound by the
|
|
** terms of this license.
|
|
**
|
|
** You must not remove this notice, or any other, from this software.
|
|
**
|
|
**
|
|
**===========================================================================*/
|
|
#include <palsuite.h>
|
|
|
|
|
|
/* one thread for each priority level */
|
|
#define NUM_THREADS 7
|
|
|
|
/*
|
|
* we keep track of the thread handles globally
|
|
* to avoid calling GetCurrentThread() -- we want
|
|
* to minimize dependencies on other functions
|
|
*/
|
|
static HANDLE hThread[ NUM_THREADS ] =
|
|
{
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
/*
|
|
* each priority level is represented, from
|
|
* lowest to highest
|
|
*/
|
|
static int nPriority[ NUM_THREADS ] =
|
|
{
|
|
THREAD_PRIORITY_IDLE,
|
|
THREAD_PRIORITY_LOWEST,
|
|
THREAD_PRIORITY_BELOW_NORMAL,
|
|
THREAD_PRIORITY_NORMAL,
|
|
THREAD_PRIORITY_ABOVE_NORMAL,
|
|
THREAD_PRIORITY_HIGHEST,
|
|
THREAD_PRIORITY_TIME_CRITICAL
|
|
};
|
|
|
|
static long nElapsedTime[ NUM_THREADS ] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
|
|
/**
|
|
* CheckThreadPriority
|
|
*
|
|
* Helper function that checks the current thread priority
|
|
* against an expected value.
|
|
*/
|
|
static VOID CheckThreadPriority( int index, int expectedPriority )
|
|
{
|
|
int priority;
|
|
DWORD dwError = 0;
|
|
|
|
/* get the current thread priority */
|
|
priority = GetThreadPriority( hThread[index] );
|
|
if( priority == THREAD_PRIORITY_ERROR_RETURN )
|
|
{
|
|
/* GetThreadPriority call failed */
|
|
dwError = GetLastError();
|
|
Fail( "Unexpected GetThreadPriority() failure at index %d "
|
|
"with error %d\n", index, dwError );
|
|
}
|
|
else if( priority != expectedPriority )
|
|
{
|
|
/* unexpected thread priority detected */
|
|
Fail( "Unexpected initial thread priority value %d reported\n",
|
|
priority );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* ThreadFunc
|
|
*
|
|
* Thread function that sets its own priority to the priority
|
|
* value in the global array nPriority[] at the index specified
|
|
* as an argument to the thread function.
|
|
*/
|
|
DWORD PALAPI ThreadFunc( LPVOID param )
|
|
{
|
|
int i, j, k;
|
|
int index;
|
|
int total = 0;
|
|
time_t start;
|
|
time_t finish;
|
|
long duration;
|
|
DWORD dwError = 0;
|
|
|
|
/* cast function argument to a thread priority value */
|
|
index = (int)param;
|
|
if( index < 0 || index >= NUM_THREADS )
|
|
{
|
|
Fail( "Thread index argument was out of range, value was %d\n",
|
|
index );
|
|
}
|
|
|
|
/*
|
|
* check the old thread priority, it should be THREAD_PRIORITY_NORMAL,
|
|
* if not it could potentially be a bug in GetThreadPriority() and not
|
|
* in CreateThread() -- at the very least it provides us with a known
|
|
* thread priority value to test against under a known condition even
|
|
* if it's a trivial one.
|
|
*/
|
|
CheckThreadPriority( index, THREAD_PRIORITY_NORMAL );
|
|
|
|
|
|
/* set the new thread priority */
|
|
if( ! SetThreadPriority( hThread[index], nPriority[index] ) )
|
|
{
|
|
dwError = GetLastError();
|
|
Fail( "Unexpected SetThreadPriority() failure with error %d\n",
|
|
dwError );
|
|
}
|
|
|
|
/* time this thread's duration */
|
|
time( &start );
|
|
|
|
/* check the new thread priority */
|
|
CheckThreadPriority( index, nPriority[index] );
|
|
|
|
/*
|
|
* Do a lengthy benign operation
|
|
*/
|
|
for( i=0; i<1000; i++ )
|
|
{
|
|
for( j=0; j<1000; j++ )
|
|
{
|
|
total = j * i;
|
|
for( k=0; k<1000; k++ )
|
|
{
|
|
total += k + i;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* finish timing the thread and calculate the duration */
|
|
time( &finish );
|
|
duration = (long)(finish - start);
|
|
|
|
/* update the elapsed time array */
|
|
nElapsedTime[ index ] = duration;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* main
|
|
*
|
|
* executable entry point
|
|
*/
|
|
INT __cdecl main( INT argc, CHAR **argv )
|
|
{
|
|
DWORD IDThread;
|
|
|
|
int i;
|
|
|
|
/* PAL initialization */
|
|
if( (PAL_Initialize(argc, argv)) != 0 )
|
|
{
|
|
return( FAIL );
|
|
}
|
|
|
|
/* set the thread priority of the main to the highest possible value
|
|
this will give the chance to the main thread to create all the
|
|
other threads */
|
|
if(!SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL))
|
|
{
|
|
DWORD dwError;
|
|
|
|
dwError = GetLastError();
|
|
Fail( "Unexpected SetThreadPriority() failure with error %d\n",
|
|
dwError );
|
|
}
|
|
|
|
printf( "Launching multiple threads, please wait...\n" );
|
|
|
|
/* Create multiple threads. */
|
|
for( i = 0; i < NUM_THREADS; i++ )
|
|
{
|
|
hThread[i] = CreateThread( NULL, /* no security attributes */
|
|
0, /* use default stack size */
|
|
(LPTHREAD_START_ROUTINE) ThreadFunc, /* thread function */
|
|
(LPVOID) i, /* pass thread index as */
|
|
/* function argument */
|
|
CREATE_SUSPENDED, /* create suspended */
|
|
&IDThread ); /* returns thread identifier */
|
|
|
|
/* Check the return value for success. */
|
|
if( hThread[i] == NULL )
|
|
{
|
|
/*ERROR */
|
|
DWORD dwError = GetLastError();
|
|
Fail( "Unexpected CreateThread error %d\n",
|
|
dwError );
|
|
}
|
|
|
|
ResumeThread(hThread[i]);
|
|
}
|
|
|
|
/* Wait for all threads to finish */
|
|
for (i = 0; i < NUM_THREADS; i++)
|
|
{
|
|
DWORD dwRet;
|
|
|
|
dwRet = WaitForSingleObject( hThread[i], INFINITE );
|
|
|
|
if( dwRet == WAIT_FAILED )
|
|
{
|
|
/* ERROR */
|
|
DWORD dwError = GetLastError();
|
|
Fail( "Unexpected WaitForSingleObject error %d\n",
|
|
dwError );
|
|
}
|
|
}
|
|
|
|
/* make sure the thread processing times match the priorities */
|
|
for( i=NUM_THREADS-1; i > 0; i-- )
|
|
{
|
|
if( nElapsedTime[i] >= nElapsedTime[i-1] )
|
|
{
|
|
/*
|
|
* a lower-priority thread finished faster than a lower-priority
|
|
* thread -- this shouldn't happen if the dummy thread function
|
|
* is non-trivial in length
|
|
*/
|
|
Fail( "Failed: processing time doesn't match thread priority\n" );
|
|
}
|
|
}
|
|
|
|
PAL_Terminate();
|
|
return PASS;
|
|
}
|