Skip to content

Instantly share code, notes, and snippets.

@iljavs
Created July 16, 2020 07:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iljavs/4b07c602d3b39fa1c61ded9f1809388b to your computer and use it in GitHub Desktop.
Save iljavs/4b07c602d3b39fa1c61ded9f1809388b to your computer and use it in GitHub Desktop.
#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