int Process::process_packets(Thread *thread) { int flag; MPI_Status status; MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag) { bool net_changed = false; for(;;) { int msg_size; MPI_Get_count(&status, MPI_BYTE, &msg_size); char *buffer = (char*) malloc(msg_size); // FIXME: alloca for small packets MPI_Recv(buffer, msg_size, MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); /* Now we have to be sure that all thread messages are processed and we know about all nets */ thread->process_thread_messages(); net_changed |= process_packet(thread, status.MPI_SOURCE, status.MPI_TAG, buffer); MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (!flag) break; } TraceLog *tracelog = thread->get_tracelog(); if (net_changed && tracelog) { tracelog->event_end(); } return 1; } return 0; }
void Process::process_service_message(Thread *thread, ServiceMessage *smsg) { switch (smsg->type) { case CA_SM_QUIT: CA_DLOG("SERVICE CA_SM_QUIT on process=%i thread=%i\n", get_process_id(), thread->get_id()); if(net == NULL) { CA_DLOG("Quitting not created net on process=%d\n", get_process_id()); net_is_quit = true; } too_early_message.clear(); quit(); break; case CA_SM_NET_CREATE: { CA_DLOG("SERVICE CA_SM_NET_CREATE on process=%i thread=%i\n", get_process_id(), thread->get_id()); ServiceMessageNetCreate *m = (ServiceMessageNetCreate*) smsg; if(net_is_quit) { CA_DLOG("Stop creating quit net on process=%i thread=%i\n", get_process_id(), thread->get_id()); too_early_message.clear(); net_is_quit = false; break; } spawn_net(m->def_index, false); if(too_early_message.size() > 0) { std::vector<EarlyMessage>::const_iterator i; for (i = too_early_message.begin(); i != too_early_message.end(); i++) { process_packet(thread, i->from_process, CA_TAG_TOKENS, i->data); } if (too_early_message.size() > 0) { TraceLog *tracelog = thread->get_tracelog(); if (tracelog) { tracelog->event_end(); } } too_early_message.clear(); } break; } case CA_SM_WAKE: { CA_DLOG("SERVICE CA_SM_WAKE on process=%i thread=%i\n", get_process_id(), thread->get_id()); start(false); clear(); #ifdef CA_MPI MPI_Barrier(MPI_COMM_WORLD); #endif break; } case CA_SM_EXIT: CA_DLOG("SERVICE CA_SM_EXIT on process=%i thread=%i\n", get_process_id(), thread->get_id()); too_early_message.clear(); free(smsg); exit(0); } }