#define DELAY_COUNT 20
#define CACHE_LINE_SIZE 64
void CALLBACK Worker(PTP_CALLBACK_INSTANCE, PVOID, PTP_WORK);
int workerDelay = DELAY_COUNT;
DWORD tid[256]={0,};
__declspec(align(CACHE_LINE_SIZE))
typedef struct _THARG{
SRWLOCK SRWL;
int threadNumber;
unsigned int tasksToComplete;
unsigned int tasksComplete;
} THARG;
int _tmain(DWORD argc, LPTSTR argv[])
{
int nThread, iThread;
HANDLE* pWorkObjects;
SRWLOCK srwl;
unsigned int tasksPerThread, totalTasksComplete;
THARG ** pThreadArgsArray, *pThreadArg;
TP_CALLBACK_ENVIRON cbe;
BOOL traceFlag = FALSE;
nThread = _ttoi(argv[1]);
tasksPerThread = _ttoi(argv[2]);
InitializeSRWLock(&srwl);
pWorkObjects = malloc ( nThread * sizeof(PTP_WORK));
pThreadArgsArray = malloc ( nThread * sizeof(THARG*));
InitializeThreadpoolEnvironment(&cbe);
for ( iThread = 0; iThread < nThread; iThread++ )
{
pThreadArg = (pThreadArgsArray[iThread] = _aligned_malloc(sizeof(THARG), CACHE_LINE_SIZE));
pThreadArg->threadNumber = iThread;
pThreadArg->tasksToComplete = tasksPerThread;
pThreadArg->tasksComplete = 0;
pThreadArg->SRWL = srwl;
pWorkObjects[iThread] = CreateThreadpoolWork(Worker, pThreadArg, &cbe);
SubmitThreadpoolWork(pWorkObjects[iThread]);
}
for(iThread=0; iThreadtasksComplete);
_tprintf(_T("Tasks completed by thread %5d: %6d\n"), iThread, tid[iThread]);
totalTasksComplete += pThreadArg->tasksComplete;
_aligned_free((pThreadArg));
}
free (pThreadArgsArray);
_tprintf(_T("TotalWork performed : %d\n"), totalTasksComplete);
return 0;
}
void CALLBACK Worker(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
THARG *threadArgs;
threadArgs = (THARG*) Context;
tid[threadArgs->threadNumber] = GetCurrentThreadId();
while(threadArgs->tasksComplete < threadArgs->tasksToComplete){
delay_cpu(workerDelay);
AcquireSRWLockExclusive(&(threadArgs->SRWL));
(threadArgs->tasksComplete)++;
ReleaseSRWLockExclusive(&(threadArgs->SRWL));
}
return;
}