added new priority manipulating routines

This commit is contained in:
Jeff Hill
2000-03-16 02:25:10 +00:00
parent 740f2de82a
commit 4ebcbd5f50
2 changed files with 160 additions and 78 deletions

View File

@@ -19,6 +19,7 @@
# define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <process.h>
#define epicsExportSharedSymbols
#include "shareLib.h"
@@ -36,17 +37,31 @@ typedef struct {
char isSuspended;
} win32ThreadParam;
static win32ThreadParam anonymousThreadParm =
{0, 0, 0, "anonymous", 0, 0};
static DWORD tlsIndexWIN32 = 0xFFFFFFFF;
typedef struct osdThreadPrivate {
DWORD key;
} osdThreadPrivate;
#define osdPriorityStateCount 7
static HANDLE win32ThreadGlobalMutex = 0;
static int win32ThreadInitOK = 0;
#define osdPriorityStateCount 7u
static const int osdPriorityList [osdPriorityStateCount] =
{
THREAD_PRIORITY_IDLE,
THREAD_PRIORITY_LOWEST,
THREAD_PRIORITY_BELOW_NORMAL,
THREAD_PRIORITY_NORMAL,
THREAD_PRIORITY_ABOVE_NORMAL,
THREAD_PRIORITY_HIGHEST,
THREAD_PRIORITY_TIME_CRITICAL,
};
/*
* threadCleanupWIN32 ()
*/
@@ -122,21 +137,11 @@ epicsShareFunc void epicsShareAPI threadInit (void)
}
/*
* threadGetOsdPriorityValue ()
* osdPriorityMagFromPriorityOSI ()
*/
static int threadGetOsdPriorityValue (unsigned osiPriority)
static unsigned osdPriorityMagFromPriorityOSI ( unsigned osiPriority )
{
static const int osdPriorityValue [osdPriorityStateCount] =
{
THREAD_PRIORITY_IDLE,
THREAD_PRIORITY_LOWEST,
THREAD_PRIORITY_BELOW_NORMAL,
THREAD_PRIORITY_NORMAL,
THREAD_PRIORITY_ABOVE_NORMAL,
THREAD_PRIORITY_HIGHEST,
THREAD_PRIORITY_TIME_CRITICAL,
};
unsigned index;
unsigned magnitude;
// optimizer will remove this one if threadPriorityMin is zero
// and osiPriority is unsigned
@@ -148,50 +153,99 @@ static int threadGetOsdPriorityValue (unsigned osiPriority)
osiPriority = threadPriorityMax;
}
index = osiPriority * osdPriorityStateCount;
index /= (threadPriorityMax - threadPriorityMin) + 1;
magnitude = osiPriority * osdPriorityStateCount;
magnitude /= (threadPriorityMax - threadPriorityMin)+1;
return osdPriorityValue[index];
return magnitude;
}
/*
* threadGetOsdPriorityValue ()
*/
static int threadGetOsdPriorityValue ( unsigned osiPriority )
{
unsigned magnitude = osdPriorityMagFromPriorityOSI ( osiPriority );
return osdPriorityList[magnitude];
}
/*
* osdPriorityMagFromPriorityOSI ()
*/
static unsigned osdPriorityMagFromPriorityOSD ( int osdPriority )
{
unsigned magnitude;
for ( magnitude=0u; magnitude<osdPriorityStateCount; magnitude++ ) {
if ( osdPriority == osdPriorityList[magnitude] ) {
break;
}
}
assert ( magnitude < osdPriorityStateCount );
return magnitude;
}
/*
* osdPriorityMagFromPriorityOSI ()
*/
static unsigned osiPriorityMagFromMagnitueOSD ( unsigned magnitude )
{
unsigned osiPriority;
osiPriority = magnitude * (threadPriorityMax - threadPriorityMin);
osiPriority /= osdPriorityStateCount - 1u;
osiPriority += threadPriorityMin;
return osiPriority;
}
/*
* threadGetOsiPriorityValue ()
*/
static unsigned threadGetOsiPriorityValue (int osdPriority)
static unsigned threadGetOsiPriorityValue ( int osdPriority )
{
unsigned index;
int osiPriority;
unsigned magnitude = osdPriorityMagFromPriorityOSD ( osdPriority );
return osiPriorityMagFromMagnitueOSD (magnitude);
}
switch (osdPriority) {
case THREAD_PRIORITY_TIME_CRITICAL:
return threadPriorityMax;
case THREAD_PRIORITY_HIGHEST:
index = 5;
break;
case THREAD_PRIORITY_ABOVE_NORMAL:
index = 4;
break;
case THREAD_PRIORITY_NORMAL:
index = 3;
break;
case THREAD_PRIORITY_BELOW_NORMAL:
index = 2;
break;
case THREAD_PRIORITY_LOWEST:
index = 1;
break;
case THREAD_PRIORITY_IDLE:
return threadPriorityMin;
default:
assert (0);
/*
* threadLowestPriorityLevelAbove ()
*/
epicsShareFunc threadBoolStatus epicsShareAPI threadLowestPriorityLevelAbove
(unsigned int priority, unsigned *pPriorityJustAbove)
{
unsigned magnitude = osdPriorityMagFromPriorityOSI ( priority );
threadBoolStatus status;
if ( magnitude < (osdPriorityStateCount-1) ) {
*pPriorityJustAbove = osiPriorityMagFromMagnitueOSD ( magnitude + 1u );
status = tbsSuccess;
}
else {
status = tbsFail;
}
return status;
}
osiPriority = index * (threadPriorityMax - threadPriorityMin);
osiPriority += (threadPriorityMax - threadPriorityMin)/2 + 1;
osiPriority /= osdPriorityStateCount;
osiPriority += threadPriorityMin;
/*
* threadHighestPriorityLevelBelow ()
*/
epicsShareFunc threadBoolStatus epicsShareAPI threadHighestPriorityLevelBelow
(unsigned int priority, unsigned *pPriorityJustBelow)
{
unsigned magnitude = osdPriorityMagFromPriorityOSI ( priority );
threadBoolStatus status;
return osiPriority;
if ( magnitude > 1u ) {
*pPriorityJustBelow = osiPriorityMagFromMagnitueOSD ( magnitude - 1u );
status = tbsSuccess;
}
else {
status = tbsFail;
}
return status;
}
/*
@@ -217,31 +271,26 @@ epicsShareFunc unsigned int epicsShareAPI threadGetStackSize (threadStackSizeCla
/*
* epicsWin32ThreadEntry()
*/
static DWORD WINAPI epicsWin32ThreadEntry (LPVOID lpParameter)
static int WINAPI epicsWin32ThreadEntry (LPVOID lpParameter)
{
win32ThreadParam *pParm = (win32ThreadParam *) lpParameter;
BOOL stat;
stat = TlsSetValue (tlsIndexWIN32, pParm);
if (!stat) {
return 0;
if (stat) {
(*pParm->funptr) (pParm->parm);
TlsSetValue (tlsIndexWIN32, 0);
}
(*pParm->funptr) (pParm->parm);
/*
* CAUTION: !!!! the thread id might continue to be used after its thread exits !!!!
* CAUTION: !!!! the thread id might continue to be used after this thread exits !!!!
*/
TlsSetValue (tlsIndexWIN32, 0);
CloseHandle (pParm->handle);
free (pParm->pName);
free (pParm);
return 1;
return (stat); /* this indirectly closes the thread handle */
}
/*
* threadCreate()
* threadCreate ()
*/
epicsShareFunc threadId epicsShareAPI threadCreate (const char *pName,
unsigned int priority, unsigned int stackSize, THREADFUNC pFunc,void *pParm)
@@ -257,25 +306,21 @@ epicsShareFunc threadId epicsShareAPI threadCreate (const char *pName,
return NULL;
}
}
pParmWIN32 = malloc ( sizeof (*pParmWIN32) );
if (pParmWIN32==NULL) {
pParmWIN32 = malloc ( sizeof (*pParmWIN32) + strlen (pName) + 1 );
if ( pParmWIN32 == NULL ) {
return NULL;
}
/* potential for fragmentation of pool here */
pParmWIN32->pName = malloc ( strlen (pName) + 1 );
if (!pParmWIN32->pName) {
free (pParmWIN32);
return NULL;
}
pParmWIN32->pName = (char *) (pParmWIN32 + 1);
strcpy (pParmWIN32->pName, pName);
pParmWIN32->funptr = pFunc;
pParmWIN32->parm = pParm;
pParmWIN32->isSuspended = 0;
pParmWIN32->handle = CreateThread (NULL, stackSize, epicsWin32ThreadEntry,
pParmWIN32, CREATE_SUSPENDED , &pParmWIN32->id);
if (pParmWIN32->handle==NULL) {
pParmWIN32->handle = (HANDLE) _beginthreadex (0, stackSize, epicsWin32ThreadEntry,
pParmWIN32, CREATE_SUSPENDED, &pParmWIN32->id);
if ( pParmWIN32->handle == 0 ) {
free (pParmWIN32);
return NULL;
}
@@ -284,14 +329,14 @@ epicsShareFunc threadId epicsShareAPI threadCreate (const char *pName,
bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority );
if (!bstat) {
CloseHandle ( pParmWIN32->handle );
free (pParmWIN32);
free ( pParmWIN32 );
return NULL;
}
wstat = ResumeThread (pParmWIN32->handle);
wstat = ResumeThread ( pParmWIN32->handle );
if (wstat==0xFFFFFFFF) {
CloseHandle (pParmWIN32->handle);
free (pParmWIN32);
CloseHandle ( pParmWIN32->handle );
free ( pParmWIN32 );
return NULL;
}
@@ -358,6 +403,19 @@ epicsShareFunc unsigned epicsShareAPI threadGetPriority (threadId id)
return threadGetOsiPriorityValue (win32ThreadPriority);
}
/*
* threadGetPriority ()
*/
epicsShareFunc unsigned epicsShareAPI threadGetPrioritySelf ()
{
int win32ThreadPriority;
win32ThreadPriority = GetThreadPriority ( GetCurrentThread () );
assert (win32ThreadPriority!=THREAD_PRIORITY_ERROR_RETURN);
return threadGetOsiPriorityValue (win32ThreadPriority);
}
/*
* threadSetPriority ()
*/
@@ -421,8 +479,9 @@ epicsShareFunc void epicsShareAPI threadSleep (double seconds)
* threadGetIdSelf ()
*/
epicsShareFunc threadId epicsShareAPI threadGetIdSelf (void)
{
return (threadId) TlsGetValue (tlsIndexWIN32);
{
win32ThreadParam *pParm = (win32ThreadParam *) TlsGetValue (tlsIndexWIN32);
return (threadId) pParm;
}
/*
@@ -542,3 +601,19 @@ epicsShareFunc void * epicsShareAPI threadPrivateGet (threadPrivateId id)
struct osdThreadPrivate *pPvt = (struct osdThreadPrivate *) id;
return (void *) TlsGetValue (pPvt->key);
}
#ifdef TEST_CODES
void testPriorityMapping ()
{
unsigned i;
for (i=threadPriorityMin; i<threadPriorityMax; i++) {
printf ("%u %d\n", i, threadGetOsdPriorityValue (i) );
}
for (i=0; i<osdPriorityStateCount; i++) {
printf ("%d %u\n", osdPriorityList[i], threadGetOsiPriorityValue(osdPriorityList[i]));
}
return 0;
}
#endif

View File

@@ -31,6 +31,8 @@ typedef enum {
threadStackSmall, threadStackMedium, threadStackBig
} threadStackSizeClass;
typedef enum {tbsFail, tbsSuccess} threadBoolStatus;
epicsShareFunc unsigned int epicsShareAPI threadGetStackSize(threadStackSizeClass size);
typedef int threadOnceId;
@@ -57,8 +59,13 @@ epicsShareFunc threadId epicsShareAPI threadCreate(const char *name,
epicsShareFunc void epicsShareAPI threadSuspendSelf(void);
epicsShareFunc void epicsShareAPI threadResume(threadId id);
epicsShareFunc unsigned int epicsShareAPI threadGetPriority(threadId id);
epicsShareFunc unsigned int epicsShareAPI threadGetPrioritySelf();
epicsShareFunc void epicsShareAPI threadSetPriority(
threadId id,unsigned int priority);
epicsShareFunc threadBoolStatus epicsShareAPI threadHighestPriorityLevelBelow
(unsigned int priority, unsigned *pPriorityJustBelow);
epicsShareFunc threadBoolStatus epicsShareAPI threadLowestPriorityLevelAbove
(unsigned int priority, unsigned *pPriorityJustAbove);
epicsShareFunc int epicsShareAPI threadIsEqual(threadId id1, threadId id2);
epicsShareFunc int epicsShareAPI threadIsSuspended(threadId id);
epicsShareFunc void epicsShareAPI threadSleep(double seconds);