/*
Science and technology promotion license applied.
(c) Zhikai Wang/ www.heteroclinic.net 2013
*/
/* 
Introduction:
Race Condition Random Seeder Release is a tool aiming to create random seeds for random generators. It ulilizes modern computer systems' high frequency CPU clock and multitasking in paralell features. By creating man-made race condition, we retrieve a volatile boolean value that threads race upon. The values retrieved thus form a bit-bundle representing a numerical value.
In this release R-2.0, we no longer utilize any mem* ops, but utilze well-implemted ADTs. The aim is to return a Bitset or std::string, so the users can parse the bit-bundle to the built-in numberical types.
This pratice seems to increase the chance of survival of this program.
Again, you find some key parameters to tune with by studying the source code.
This program due to its nature will not be of high performance. It is suggested to be used as a seeder program for other random generators, e.g. linear congruential random generator etc.
*/
/*
How to run (Cygwin/Linux/UNIX) in Shell console:
wget www.heteroclinic.net/attached/RaceConditionRandomSeederR2d0BitsetImpl.cpp
g++ -o RaceConditionRandomSeederR2d0BitsetImpl.exe RaceConditionRandomSeederR2d0BitsetImpl.cpp -lpthread
./RaceConditionRandomSeederR2d0BitsetImpl.exe
*/
#ifndef __RACECONDITIONRANDOMSEEDER
#define __RACECONDITIONRANDOMSEEDER
#include <deque>
#include <pthread.h>
#include <iostream>
#include <string.h>
#include <bitset>
#include <limits>
#include <unistd.h> // for usleep
#endif
typedef std::numeric_limits< unsigned long long > ulllimit;
std::deque<pthread_t  *> racers;
std::deque<int > ret_racers;
volatile bool shared = false;
volatile bool halted = false;
void * racer( void *ptr );
const unsigned int racer_sleep_value = 2;
const unsigned int anchor_sleep_value = 2;
int main () {
 
        unsigned  int noofthreads = 32;
        unsigned  int bitstorun = 32;
        unsigned int start_interval =1000 ;//us
        unsigned int start_interval2 =1000 ;//us
 
        int i = 0;
        for (i = 0; i<noofthreads; i++) {
                pthread_t  * tmp_pt = new pthread_t();
                racers.push_back(tmp_pt);
                usleep ( start_interval);
                ret_racers.push_back(pthread_create( tmp_pt, NULL, racer, NULL));
        }
 
        usleep ( start_interval);
        unsigned int runs = 32;
 
        std::bitset<32> data (0);
        int l1 = 0;
        int l2 = 0;
        for (l1= 0; l1<128; l1++) {
             for (l2= 0; l2<32; l2++) {
                 if ( shared)
                     data.flip(l2);
 
                usleep(anchor_sleep_value);
             }
             std::cout<< data<<std::endl;
        }
 
        halted = true;
 
        for (i = 0; i<noofthreads; i++) {
                 pthread_join( *racers.front(),NULL);
                 racers.pop_front();
        }
        for (std::deque<int >::const_iterator iter = ret_racers.begin();
                iter != ret_racers.end(); iter++)
                //std::cout<<(*iter)<<std::endl;
                ;//do nothing
 
        return 0;
}
 
void *racer( void *ptr )
{
         while (!halted) {
                shared=!shared;
                usleep(racer_sleep_value);
         }
}