//------------------------------------------------------------------------------ int pop(Workers& workers) { assert(workers.size() > 0); std::set< worker_info >::iterator back = --workers.end(); const int ret = back->id(); workers.erase(back); return ret; }
//------------------------------------------------------------------------------ //if worker already present remove it and re-insert it in the right //position void push(Workers& workers, int id) { Workers::iterator it = std::find_if(workers.begin(), workers.end(), [id](const worker_info& wi){ return wi.id() == id; }); if(it != workers.end()) workers.erase(it); workers.insert(worker_info(id)); }
//------------------------------------------------------------------------------ //elements are ordered from highest to lowest //1) find the first element which has a time > expiration time //2) remove all elements from that element to last element is set void purge(Workers& workers, const duration& cutoff) { typedef Workers::iterator WI; WI start = std::find_if( workers.begin(), workers.end(), [&cutoff](const worker_info& wi) { return std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::steady_clock::now() - wi.timestamp() ) > cutoff; }); if(start == workers.end()) return; workers.erase(start, workers.end()); }
inline unit_t getCount() const throw() { unit_t count = 0; for(size_t i=workers.size();i>0;--i) { count += workers[i]->count; } return count; }
void testThreads (int const threadCount) { String s; s << "threadCount = " << String (threadCount); beginTestCase (s); TestCallback cb (threadCount); Workers w (cb, "Test", 0); expect (w.getNumberOfThreads () == 0); w.setNumberOfThreads (threadCount); expect (w.getNumberOfThreads () == threadCount); for (int i = 0; i < threadCount; ++i) w.addTask (); // 10 seconds should be enough to finish on any system // bool signaled = cb.finished.wait (10 * 1000); expect (signaled, "timed out"); w.pauseAllThreadsAndWait (); int const count (cb.count.get ()); expectEquals (count, 0); }
inline explicit Simulation(const size_t np, const size_t nw, const double delta_lambda) : delta_lam(delta_lambda), delta_tau(delta_lam*delta_lam), workers(nw,as_capacity), running(), waiting(), ran( ) { ran.reseed( Randomized::Bits::Simple() ); for(size_t i=np;i>0;--i) { running.push_back( new Particle() ); } for(size_t i=nw;i>0;--i) { const Worker::Pointer pW( new Worker() ); workers.push_back(pW); } }
void saveXYZ( ios::ostream &fp ) const { unsigned np = 0; const size_t nw = workers.size(); for(size_t i=nw;i>0;--i) { np += workers[i]->running.size; } fp("%u\n", np); fp("\n"); for(size_t i=nw;i>0;--i) { for(const Particle *p=workers[i]->running.head;p;p=p->next) { const char *id = "H"; if(p->kind) id = "Li"; fp("%s %g %g %g\n",id,p->r.x,p->r.y,p->r.z); } } }
inline void setup() throw() { // gather particles const size_t nw = workers.size(); running.merge_back(waiting); for(size_t i=nw;i>0;--i) { running.merge_back(workers[i]->running); running.merge_back(workers[i]->waiting); } core::merging<Particle>::sort(running, Particle::compareByAddress, NULL); // initialize them for(Particle *p=running.head;p;p=p->next) { p->r.x = -Box.x/2 + Box.x * ran(); p->r.y = -Box.y/2 + Box.y * ran(); p->r.z = -Box.z * ran(); p->status = Particle::InReservoir; p->kind = 0; p->inReservoir(); } // dispatch particles const size_t np = running.size; for(size_t i=0;i<nw;++i) { size_t offset = 0; size_t length = np; parallel::basic_split(i,nw, offset, length); Worker &w = *workers[i+1]; while(length-->0) { w.running.push_back(running.pop_front()); } //std::cerr << "#running[" << i+1 << "]=" << w.running.size << std::endl; } }
//------------------------------------------------------------------------------ int main(int argc, char** argv) { if(argc < 3) { std::cout << "usage: " << argv[0] << " <frontend address> <backend address>" << std::endl; return 0; } const char* FRONTEND_URI = argv[1]; const char* BACKEND_URI = argv[2]; const int MAX_REQUESTS = 100; //create communication objects void* context = zmq_ctx_new(); assert(context); void* frontend = zmq_socket(context, ZMQ_ROUTER); assert(frontend); void* backend = zmq_socket(context, ZMQ_ROUTER); assert(backend); assert(zmq_bind(frontend, FRONTEND_URI) == 0); assert(zmq_bind(backend, BACKEND_URI) == 0); //workers ordered queue Workers workers; int worker_id = -1; int client_id = -1; int rc = -1; std::vector< char > request(0x100, 0); std::vector< char > reply(0x100, 0); int serviced_requests = 0; //loop until max requests servided while(serviced_requests < MAX_REQUESTS) { zmq_pollitem_t items[] = { {backend, 0, ZMQ_POLLIN, 0}, {frontend, 0, ZMQ_POLLIN, 0}}; //remove all workers that have not been active for a //time > expiration interval //XXX TODO: TEST purge(workers, EXPIRATION_INTERVAL); //XXX //poll for incoming requests: if no workers are available //only poll for workers(backend) since there is no point //in trying to service a client request without active //workers rc = zmq_poll(items, workers.size() > 0 ? 2 : 1, TIMEOUT); if(rc == -1) break; //data from workers if(items[0].revents & ZMQ_POLLIN) { assert(zmq_recv(backend, &worker_id, sizeof(worker_id), 0) > 0); assert(zmq_recv(backend, 0, 0, 0) == 0); assert(zmq_recv(backend, &client_id, sizeof(client_id), 0) > 0); //add worker to list of available workers push(workers, worker_id); assert(workers.size() > 0); //of not a 'ready' message forward message to frontend //workers send 'ready' messages when either if(client_id != WORKER_READY) { int seq_id = -1; assert(zmq_recv(backend, 0, 0, 0) == 0); rc = zmq_recv(backend, &seq_id, sizeof(seq_id), 0); assert(rc > 0); rc = zmq_recv(backend, &reply[0], reply.size(), 0); assert(rc > 0); zmq_send(frontend, &client_id, sizeof(client_id), ZMQ_SNDMORE); zmq_send(frontend, 0, 0, ZMQ_SNDMORE); zmq_send(frontend, &seq_id, sizeof(seq_id), ZMQ_SNDMORE); zmq_send(frontend, &reply[0], rc, 0); ++serviced_requests; } } //request from clients if(items[1].revents & ZMQ_POLLIN) { int seq_id = -1; //receive request |client id|<null>|request id|data| zmq_recv(frontend, &client_id, sizeof(client_id), 0); zmq_recv(frontend, 0, 0, 0); rc = zmq_recv(frontend, &seq_id, sizeof(seq_id), 0); assert(rc > 0); const int req_size = zmq_recv(frontend, &request[0], request.size(), 0); assert(req_size > 0); //take worker from list and forward request to it worker_id = pop(workers); assert(worker_id > 0); zmq_send(backend, &worker_id, sizeof(worker_id), ZMQ_SNDMORE); zmq_send(backend, 0, 0, ZMQ_SNDMORE); zmq_send(backend, &client_id, sizeof(client_id), ZMQ_SNDMORE); zmq_send(backend, 0, 0, ZMQ_SNDMORE); zmq_send(backend, &seq_id, sizeof(seq_id), ZMQ_SNDMORE); zmq_send(backend, &request[0], req_size, 0); } const int hb = HEARTBEAT; //capturing HEARTBEAT directly generates //a warning because the lambda function should //not capture a variable with non-automatic //storage //send heartbeat request to all workers: workers reply to such request //with a 'ready' message std::for_each(workers.begin(), workers.end(), [backend, hb](const worker_info& wi) { const int id = wi.id(); zmq_send(backend, &id, sizeof(id), ZMQ_SNDMORE); zmq_send(backend, 0, 0, ZMQ_SNDMORE); zmq_send(backend, &hb, sizeof(hb), 0); }); } zmq_close(frontend); zmq_close(backend); zmq_ctx_destroy(context); return 0; }
int main(int argc, const char **argv) { set_mySubSystem( "TEST_LOG_WRITER", SUBSYSTEM_TYPE_TOOL ); // initialize to read from config file myDistro->Init( argc, argv ); config(); // Set up the dprintf stuff... dprintf_set_tool_debug("test_log_writer", 0); set_debug_flags(NULL, D_ALWAYS); bool error = false; GlobalOptions opts; error = opts.parseArgs( argc, argv ); if ( error ) { fprintf( stderr, "Command line error\n" ); exit( 1 ); } # if defined(UNIX) signal( SIGTERM, handle_sig ); signal( SIGQUIT, handle_sig ); signal( SIGINT, handle_sig ); # endif int num_events = 0; int sequence = 0; Workers *workers; workers = new Workers( opts ); Worker *worker = workers->createWorkers( ); if ( error ) { fprintf( stderr, "Failed to create workers\n" ); exit( 1 ); } if ( worker ) { if ( workers->numChildren() ) { delete workers; workers = NULL; } const WorkerOptions &wopts = worker->getOptions(); TestLogWriter writer( *worker, wopts ); int max_proc = wopts.getProc() + wopts.getNumProcs() - 1; for( int proc = wopts.getProc(); ( (wopts.getNumProcs() < 0) || (proc <= max_proc) ); proc++ ) { writer.setGlobalProc( proc ); error = writer.WriteEvents( num_events, sequence ); if ( error || global_done ) { break; } } } if ( workers && workers->numChildren() ) { printf( "About to wait for workers\n" ); global_workers = workers; error = workers->waitForWorkers( 0 ); if ( workers->numErrors() ) { error = true; } global_workers = NULL; delete workers; } if ( error && (opts.Verbose(VERB_ERROR) ) ) { fprintf(stderr, "test_log_writer FAILED\n"); } else if ( opts.Verbose(VERB_INFO) ) { printf( "wrote %d events\n", num_events ); printf( "global sequence %d\n", sequence ); } return (int) error; }
int cmpSalary (Workers x,Workers y) { return (x.getSalary()- y.getSalary()); }
int cmpExperience (Workers x,Workers y) { return (x.getExperience()- y.getExperience()); }
int cmpDate (Workers x,Workers y) { return (372*(x.getDate().getYear()-1)+31*(x.getDate().getMonth()-1)+x.getDate().getDay())- (372*(y.getDate().getYear()-1)+31*(y.getDate().getMonth()-1)+y.getDate().getDay()); }
int cmpSurname (Workers x, Workers y) { return x.getSurname()<y.getSurname()?-1:(x.getSurname()>y.getSurname()?1:0); }