#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <thread>
#include "boundbuf.h"
using namespace std;
/*
* Find the first n primes by simple elimination using a single worker
* thread. This is not very efficient; intended as a base for something
* more interesting.
*/
/* Queue of possible primes to eliminate. */
BoundedBuffer<int> cand_q;
/* Queue of results. */
struct result {
int cand;
bool divisor_found;
result(int c = 0, bool df = false) { cand = c; divisor_found = df; }
};
BoundedBuffer<result> result_q;
/* See if a number has a divisor. Assumes num is odd, since we just skip those
in the main algorithm. So we assume 2 is not a factor. */
bool has_divisor(int num)
{
int max = num / 3;
for(int i = 3; i <= max; ++i)
if(num % i == 0) return true;
return false;
}
/* This is the candidate processor thread. */
void eliminator()
{
while(true)
{
// Read a candidate.
int cand;
cand_q.dequeue(cand);
if(cand < 0) break;
// Compute a response.
result res(cand, has_divisor(cand));
// Send it back.
result_q.enqueue(res);
}
}
/* Output the next number. Arranges them in 10 per row. */
void output(int n)
{
static const int LINE_SIZE = 12;
static int linecount = 0;
if(linecount >= LINE_SIZE) {
cout << endl;
linecount = 0;
} else if(linecount > 0)
cout << " ";
cout << setw(5) << n;
++linecount;
}
int main(int argc, char **argv)
{
int count = 200;
if(argc > 1) count = atoi(argv[1]);
// Start a worker thread.
thread worker(eliminator);
output(2);
count--;
for(int n = 3; true; n += 2) {
// Send a candidate.
cand_q.enqueue(n);
// Get hte result, and display if prime.
result r;
result_q.dequeue(r);
if(!r.divisor_found) {
output(n);
if(--count <= 0) break;
}
}
cout << endl;
// Shut down the worker.
cand_q.enqueue(-1);
worker.join();
}