-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathc_primes.c
85 lines (74 loc) · 2.14 KB
/
c_primes.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Compile with:
export CFLAGS="-g -Wall -O3 --std=c11 -pthread -latomic"
export LDLIBS="-lm"
make c_primes
*/
#include <stdio.h>
#include <stdatomic.h>
#include <stdlib.h> //malloc
#include <stdbool.h>
#include <pthread.h>
#include <math.h> //sqrt
typedef struct {
long int *plist;
long int length;
long int max;
} prime_s;
int add_a_prime(_Atomic prime_s *pin, long int new_prime){
prime_s p = atomic_load(pin);
p.length++;
p.plist = realloc(p.plist, sizeof(long int) * p.length);
if (!p.plist) return 1;
p.plist[p.length-1] = new_prime;
if (new_prime > p.max) p.max = new_prime;
atomic_store(pin, p);
return 0;
}
typedef struct{
long int i;
_Atomic prime_s *prime_list;
pthread_mutex_t *mutex;
} test_s;
void* test_a_number(void *vin){
test_s *in = vin;
long int i = in->i;
prime_s pview;
do {
pview = atomic_load(in->prime_list);
} while (pview.max*2 < i);
bool is_prime = true;
for (int j=0; j < pview.length && pview.plist[j] <= sqrt(i); j++)
if (!(i % pview.plist[j])){
is_prime = false;
break;
}
if (is_prime){
pthread_mutex_lock(in->mutex);
int retval = add_a_prime(in->prime_list, i);
if (retval) {printf("Too many primes.\n"); exit(0);}
pthread_mutex_unlock(in->mutex);
}
return NULL;
}
int main(){
prime_s inits = {.plist=NULL, .length=0, .max=0};
_Atomic prime_s prime_list = ATOMIC_VAR_INIT(inits);
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
int thread_ct = 3;
test_s ts[thread_ct];
pthread_t threads[thread_ct];
add_a_prime(&prime_list, 2);
long int max = 1e6;
for (long int i=3; i< max; i+=thread_ct){
for (int t=0; t < thread_ct && t+i < max; t++){
ts[t] = (test_s) {.i = i+t, .prime_list=&prime_list, .mutex=&m};
pthread_create(threads+t, NULL, test_a_number, ts+t);
}
for (int t=0; t< thread_ct && t+i <max; t++)
pthread_join(threads[t], NULL);
}
prime_s pview = atomic_load(&prime_list);
for (int j=0; j < pview.length; j++)
printf("%li\n", pview.plist[j]);
}