/******* ** ** To compile: pcc sieve.pc -o sieve.seq -ff ** Adapted for PARSEC 10-9-97 by Monnica Terwilliger ** *******/ #include #include /********************************************************************** ** ** Sieve of Eratosthenes ** ** This program implements the Sieve Of Eratosthenes algorithm to ** generate prime numbers from a sequence of consecutive natural ** numbers [2..N]. ** ** The entities used: ** (1) driver: Initiate the program and generate the ** sequence of consecutive natural numbers. ** (2) sieve: Each instance of sieve entity stands ** for a prime number. ** ** The program terminates when no message is in transit. ** **********************************************************************/ #define DEFAULT_NUMBER 1000 message Number {int number; }; entity sieve(int); void sieve::set_and_print_myprime(int *my_prime_ptr); /********** ** ** DRIVER: 1. Take an command-line argument specifying the maximum ** natural number n. If no argument provided, n=1000 by default. ** 2. Create the first sieve entity ** 3. Generate the sequence of consecutive natural numbers and send ** to the first sieve. ** **********/ entity driver(int argc, char **argv) { int i, n = DEFAULT_NUMBER; ename first; if(argc >1) /* Get the maximum number */ n = atoi(argv[1]); first = new sieve(1) ; /* Create the first entity */ for(i = 2 ; i <= n; ++i) { /* Generate the number messages */ send Number {i} to first; } } /********** ** ** SIEVE: The first message contains the prime number ** represented by the current instance of sieve entity. ** ** The entity then creates another instance of sieve and ** enters a loop. In the loop. the entity accepts all ** subsequent numbers from its creator and pass only ** those numbers not a multiple of its prime number. ** **********/ entity sieve(int myid) stacksize( 1000000U) /******* ~~~~~~~~~~~~~~~~~~~~ ** Here is the stacksize. 1000000U is the amount of stacksize in unsigned ** integer. This version may work slower than ordinary version, but ** every instance of entity sieve will have stacksize of 1M. There may be a ** warning if system stack does not support all of total stacksizes. ** **********/ { message Number new_number; /* Expected message type*/ ename next_sieve; /* Child's id */ int my_prime; /* My prime number */ receive (Number tmp) { new_number = tmp; } /* First message has */ /* my prime number */ set_and_print_myprime(&my_prime); /* Set myprime */ next_sieve = new sieve (myid+1); /* Create child */ for(;;) receive (Number number) /* A new number!! */ { if(number.number % my_prime) /* Multiple of myprime? */ send number to next_sieve; /* If not, pass to the */ } /* the child. */ } /*** *** This function set and print the prime number of the *** associated entity 'sieve'. *** *** Referencing to variables defined in entity 'sieve': *** int myid; *** message Number new_number; *** int my_prime; *** ***/ void sieve::set_and_print_myprime(int *my_prime_ptr) { *my_prime_ptr = new_number.number; printf("Sieve number %d is for prime number %d\n",myid, new_number.number); }