Skip to content

Instantly share code, notes, and snippets.

@doug65536
Created July 31, 2013 11:37
Show Gist options
  • Save doug65536/6121289 to your computer and use it in GitHub Desktop.
Save doug65536/6121289 to your computer and use it in GitHub Desktop.
#include <iostream>
#include "util_pcqueue.h"
#ifdef WITH_BOOST
#include <boost/atomic.hpp>
#define Atomic boost
#elif __cplusplus >= 201103L
#include <atomic>
#define Atomic std
#else
#error Do not know how to use atomic on this compiler, enable boost
#endif
class AtomicRand
{
Atomic::atomic<int> state;
public:
const int rand_max = (std::numeric_limits<int>::max)();
AtomicRand()
: state(0)
{
}
/* returns a pseudo-random number between 0 and rand_max */
int rand()
{
int new_state;
int old_state = state.load(Atomic::memory_order_relaxed);
do {
new_state = old_state * 1103515245 + 12345;
} while (!state.compare_exchange_weak(old_state, new_state, Atomic::memory_order_release));
return (int)((unsigned)new_state >> 1);
}
int seed(int value)
{
state.store(value, Atomic::memory_order_release);
}
};
template<typename T>
class ProducerConsumerTest
{
ProducerConsumer<T> queue;
public:
ProducerConsumerTest()
{
queue.set_limit(1000000);
}
void producer(bool delay)
{
for (int i = 0; i < 1000000; ++i) {
if (delay && rand())
queue.push(i);
}
queue.push_complete();
}
void consumer(bool delay)
{
int i;
while (queue.pop(i));
}
};
int main()
{
ProducerConsumerTest<int> test;
for (int variation = 0; variation < 4; ++variation) {
thread producer_thread(function_bind(&ProducerConsumerTest<int>::producer, &test, (variation & 1)!=0));
thread consumer_thread(function_bind(&ProducerConsumerTest<int>::consumer, &test, (variation & 2)!=0));
consumer_thread.join();
producer_thread.join();
std::cout << "Variation " << variation << " complete" << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment