Created
July 16, 2020 07:18
-
-
Save iljavs/4b07c602d3b39fa1c61ded9f1809388b to your computer and use it in GitHub Desktop.
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
#include <windows.h> | |
#include <stdio.h> | |
#include <time.h> | |
#define PRIME_DEFAULT_SIZE 64 | |
#define DEFAULT_MAX 4000000 | |
typedef struct _prime { | |
ULONG start; | |
ULONG range; | |
} prime; | |
typedef union _params { | |
prime p; | |
PVOID ret; | |
} params, * pparams; | |
PVOID xmalloc(size_t len) { | |
PVOID r = (PVOID)malloc(len); | |
if (r == NULL) { | |
printf("OOM\n"); | |
exit(0); | |
} | |
return r; | |
} | |
PVOID xrealloc(PVOID src, size_t len) { | |
PVOID dst = (PVOID)realloc(src, len); | |
if (dst == NULL) { | |
printf("OOM\n"); | |
exit(0); | |
} | |
return dst; | |
} | |
/* expect values > 2 */ | |
bool isPrime(ULONG num) { | |
bool flag = true; | |
if (!(num & 1)) return false; | |
for (ULONG i = 3; i <= num / 2; i++) { | |
if (num % i == 0) { | |
flag = false; | |
break; | |
} | |
} | |
return flag; | |
} | |
DWORD WINAPI PrimeProc(PVOID p) { | |
pparams pa = (pparams)p; | |
ULONG i = pa->p.start; | |
ULONG max = i + pa->p.range; | |
ULONG* primes = (ULONG *)xmalloc(PRIME_DEFAULT_SIZE * sizeof(ULONG)); | |
ULONG pindex = 0; | |
ULONG pmax = PRIME_DEFAULT_SIZE; | |
for (; i < max; i++) { | |
if (isPrime(i)) { | |
if (pindex == pmax) { | |
pmax *= 2; | |
primes = (ULONG *)xrealloc(primes, pmax * sizeof(ULONG)); | |
} | |
primes[pindex++] = i; | |
} | |
} | |
pa->ret = (PVOID)primes; | |
return pindex; | |
} | |
int main(int argc, char** argv) { | |
HANDLE handles[256]; | |
DWORD hcount; | |
params p[256]; | |
clock_t start, end; | |
if (argc < 2) { | |
printf("provide a threadcount (1-256)\n"); | |
exit(0); | |
} | |
hcount = atoi(argv[1]); | |
if (hcount < 1) { | |
printf("threadcount < 1, using 1\n"); | |
hcount++; | |
} | |
if (hcount > 256) { | |
printf("threadcount > 256, using 256\n"); | |
hcount = 256; | |
} | |
ULONG range = DEFAULT_MAX / hcount; | |
ULONG rest = DEFAULT_MAX % hcount; | |
DWORD i, j; | |
ULONG startnum = 3; | |
start = clock(); | |
for (i = 0; i < hcount; i++) { | |
p[i].p.start = startnum; | |
p[i].p.range = range; | |
if (i == hcount - 1) { // account for +- 3 | |
if (rest >= 3) | |
p[i].p.range += rest - 3; | |
if (rest == 2) | |
p[i].p.range -= 1; | |
if (rest == 1) | |
p[i].p.range -= 2; | |
if (!rest) | |
p[i].p.range -= 3; | |
} | |
startnum += range; | |
handles[i] = CreateThread(NULL, 0, &PrimeProc, &p[i], 0, NULL); | |
if (handles[i] == NULL) { | |
printf("CreateThread() failed (%u)\n", GetLastError()); | |
exit(0); | |
} | |
} | |
DWORD r = WaitForMultipleObjects(hcount, (const HANDLE *)&handles, 1, INFINITE); | |
end = clock(); | |
if (r == WAIT_TIMEOUT || r == WAIT_FAILED) { | |
printf("WaitForMultipleObjects() failed or timed out (%u)\n", GetLastError()); | |
exit(0); | |
} | |
printf("duration: ~%g seconds\n", (float)(end - start) / CLOCKS_PER_SEC); | |
ULONG pcount = 0; | |
for (DWORD i = 0; i < hcount; i++) { | |
ULONG nrsprime = 0; | |
r = GetExitCodeThread(handles[i], &nrsprime); | |
if (!r) { | |
printf("GetExitCodeThread() failed(%u)\n", GetLastError()); | |
exit(0); | |
} | |
ULONG* primes = (ULONG*)p[i].ret; | |
for (j = 0; j < nrsprime; j++) { | |
//printf("prime number: %u\n", primes[j]); | |
pcount++; | |
} | |
} | |
printf("number of primes found: %u\n", pcount); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment