Created
November 17, 2015 23:46
-
-
Save 0ffffffffh/cf93ed82d86dffe8ddb8 to your computer and use it in GitHub Desktop.
Race condition test program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Race condition demo program. | |
//Written by Oguz Kartal | |
//Date: 11/17/2015 7:21 PM | |
#include <Windows.h> | |
#include <stdio.h> | |
#define NVA(i) ( (i+1) >= argc ) ? "" : argv[i+1] | |
#define ONOFFSTR(b) b ? "on" : "off" | |
#define TRY_FAIL_OPT_ARG(cmp, opt) if (cmp) { printf("Expected option argument for %s",opt); return 1; } | |
LONG sharedValue = 0; | |
typedef struct _workerInfo | |
{ | |
DWORD iteration; | |
LONG *pShared; | |
}workerInfo; | |
DWORD WINAPI workerMethod(void *p) | |
{ | |
workerInfo *pWi = (workerInfo *)p; | |
LONG *pVal = pWi->pShared; | |
DWORD iteration = pWi->iteration; | |
while (iteration-- > 0) | |
{ | |
(*pVal)++; | |
(*pVal)--; | |
} | |
return 0; | |
} | |
void startWorkers(DWORD id,DWORD workerCount, DWORD iterationPerWorker, BOOL simulateUniprocessor, BOOL coreAffinity) | |
{ | |
DWORD processorCount,affMask, processorId=0, dummy; | |
workerInfo wi; | |
SYSTEM_INFO sysInfo; | |
HANDLE *threads = NULL; | |
GetSystemInfo(&sysInfo); | |
processorCount = simulateUniprocessor ? 1 : sysInfo.dwNumberOfProcessors; | |
if (simulateUniprocessor && !coreAffinity) | |
coreAffinity = TRUE; | |
threads = (HANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HANDLE) * workerCount); | |
wi.iteration = iterationPerWorker; | |
wi.pShared = &sharedValue; | |
if (!threads) | |
{ | |
printf("handle list could not allocated!\n"); | |
return; | |
} | |
sharedValue = 0; | |
printf("\n=== Test#%d is staring ===\n", id); | |
for (int i = 0; i < workerCount;i++) | |
{ | |
threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)workerMethod, &wi, 0, &dummy); | |
if (coreAffinity) | |
{ | |
affMask = 1 << processorId; | |
if (processorId == processorCount - 1) | |
processorId = 0; | |
else | |
processorId++; | |
SetThreadAffinityMask(threads[i], affMask); | |
} | |
} | |
WaitForMultipleObjects(workerCount, (const HANDLE *)threads, TRUE, INFINITE); | |
for (int i = 0; i < workerCount; i++) | |
CloseHandle(threads[i]); | |
HeapFree(GetProcessHeap(), 0, threads); | |
printf("=== Test#%d finished. Expected Value: 0, Actual sharedValue : %d ===\n\n\n",id, sharedValue); | |
} | |
void pnOpt(const char *opt, const char *desc) | |
{ | |
printf("\t%s: %s\n", opt, desc); | |
} | |
void printHelp() | |
{ | |
printf("Race condition test program. Written by Oguz Kartal (Nov. 2015)\n"); | |
printf("usage: rcDemo [options]\n"); | |
printf("[options]\n"); | |
pnOpt("-w [N]","Create N concurrent worker thread(s)"); | |
pnOpt("-i [N]", "N iteration(s) per worker"); | |
pnOpt("-su", "Simulate uniprocessor"); | |
pnOpt("-wa", "Distribute worker threads fairly between each core (-su option overrides this)"); | |
pnOpt("-tc [N]", "Repeat the test N times"); | |
} | |
int main(int argc, char **argv) | |
{ | |
int workerCount, iterCount, testCount = 1; | |
BOOL simUni = FALSE, setAff = FALSE; | |
int i; | |
if (argc < 2) | |
{ | |
printf("Missing paramters\n\n"); | |
printHelp(); | |
return 1; | |
} | |
for (i = 1; i < argc; i++) | |
{ | |
if (!stricmp(argv[i], "-w")) | |
{ | |
workerCount = atoi(NVA(i)); | |
TRY_FAIL_OPT_ARG(workerCount <= 0, "-w"); | |
i++; | |
} | |
else if (!stricmp(argv[i], "-i")) | |
{ | |
iterCount = atoi(NVA(i)); | |
TRY_FAIL_OPT_ARG(iterCount <= 0, "-i"); | |
i++; | |
} | |
else if (!stricmp(argv[i], "-tc")) | |
{ | |
testCount = atoi(NVA(i)); | |
TRY_FAIL_OPT_ARG(testCount <= 0, "-tc"); | |
i++; | |
} | |
else if (!stricmp(argv[i], "-su")) | |
simUni = TRUE; | |
else if (!stricmp(argv[i], "-wa")) | |
setAff = TRUE; | |
} | |
printf("Test will be running using %d Worker Threads with %d iteration per worker.\n", workerCount, iterCount); | |
printf("Uniprocessor simulation is %s, and Worker distribution is %s\n\n", ONOFFSTR(simUni), ONOFFSTR(setAff)); | |
for (i = 0; i < testCount; i++) | |
{ | |
startWorkers(i+1, workerCount, iterCount, simUni, setAff); | |
} | |
printf("All done"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment