1 static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/thread.doc,v 1.11 1997/02/21 19:50:51 drh Exp $";
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "assert.h"
5 #include "fmt.h"
6 #include "thread.h"
7 #include "chan.h"
8 struct args {
9 	Chan_T c;
10 	int n, last;
11 };
source(void * cl)12 int source(void *cl) {
13 	struct args *p = cl;
14 	int i = 2;
15 	if (Chan_send(p->c, &i, sizeof i))
16 		for (i = 3; Chan_send(p->c, &i, sizeof i); )
17 			i += 2;
18 	return EXIT_SUCCESS;
19 }
filter(int primes[],Chan_T input,Chan_T output)20 void filter(int primes[], Chan_T input, Chan_T output) {
21 	int j, x;
22 	for (;;) {
23 		Chan_receive(input, &x, sizeof x);
24 		for (j = 0; primes[j] != 0 && x%primes[j] != 0; j++)
25 			;
26 		if (primes[j] == 0)
27 			 if (Chan_send(output, &x, sizeof x) == 0)
28 				break;
29 	}
30 	Chan_receive(input, &x, 0);
31 }
sink(void * cl)32 int sink(void *cl) {
33 	struct args *p = cl;
34 	Chan_T input = p->c;
35 	int i = 0, j, x, primes[256];
36 	primes[0] = 0;
37 	for (;;) {
38 		Chan_receive(input, &x, sizeof x);
39  		for (j = 0; primes[j] != 0 && x%primes[j] != 0; j++)
40 			;
41 		if (primes[j] == 0) {
42 			if (x > p->last)
43 				break;
44 			Fmt_print(" %d", x);
45 			primes[i++] = x;
46 			primes[i] = 0;
47 			if (i == p->n)
48 				{
49 					p->c = Chan_new();
50 					Thread_new(sink, p, sizeof *p, NULL);
51 					filter(primes, input, p->c);
52 					return EXIT_SUCCESS;
53 				}
54 		}
55 	}
56 	Fmt_print("\n");
57 	Chan_receive(input, &x, 0);
58  	return EXIT_SUCCESS;
59 }
main(int argc,char * argv[])60 int main(int argc, char *argv[]) {
61 	struct args args;
62 	Thread_init(1, NULL);
63 	args.c = Chan_new();
64 	Thread_new(source, &args, sizeof args, NULL);
65 	args.n    = argc > 2 ? atoi(argv[2]) : 5;
66 	args.last = argc > 1 ? atoi(argv[1]) : 1000;
67 	Thread_new(sink,   &args, sizeof args, NULL);
68 	Thread_exit(EXIT_SUCCESS);
69 	return EXIT_SUCCESS;
70 }
71