value Pvm_probe(value tid,value msgtag) { int res=pvm_probe(Int_val(tid),Int_val(msgtag)); if (res<0) TreatError(res); return(Val_int(res)); }
/// user function:add a new query to a pipeline of filters. Called by user manager runs this. /// \param layout System Layout. /// \param work Buffer with a Unit of Work (UoW) /// \param workSize Unit of Work Size (UoW) /// \return Zero on success, -1 on error. int appendWork(Layout *layout, void *work, int workSize) { #ifdef NO_BARRIER // sends work for each filter pvm_initsend(PvmDataRaw); // First tell that is a mensage of WORK int msgType = MSGT_WORK; pvm_pkint(&msgType, 1, 1); //then attach the work to it pvm_pkbyte((char *)work, workSize, 1); // for each filter, send his work for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); // sends work to all filters of this set pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } #else int i; int totalEows = 0, numEowsReceived; #ifdef ATTACH int totalAttachedFilters = 0; #endif int reconf = 0 /** should we reconfigure? */, remainingReconfs = 0; //how many times should we try? #ifdef VOID_INST #ifdef BMI_FT char instDir[MAX_IDIR_LENGTH]; sprintf(instDir, "%s/", INST_DIR); for (i=0; i < layout->numFilters-1; i++) { if (strlen(instDir) >= (MAX_IDIR_LENGTH - 3)) { //dont want to overflow this array fprintf(stderr, "%s %d: warning, instrumentation directory name too big, truncating to %s\n", __FILE__, __LINE__, instDir); break; } sprintf(instDir, "%s%d-", instDir, layout->filters[i]->filterPlacement.numInstances); } sprintf(instDir, "%s%d", instDir, layout->filters[layout->numFilters-1]->filterPlacement.numInstances); char managerLogFile[MAX_IDIR_LENGTH+20]; sprintf(managerLogFile, "%s/manager.time", instDir); FILE *fp = fopen(managerLogFile, "w"); struct timeval tv; struct timezone tz; //not used //get the time gettimeofday(&tv, &tz); if(fp != NULL) fprintf(fp, "1 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif #endif //before sending, we check if we received any filter error int bufid = pvm_probe(-1, MSGT_FERROR); if (bufid != 0) { int bytes, tag, tid; char *msg; pvm_bufinfo(bufid, &bytes, &tag, &tid); msg = (char*)malloc(bytes+1); pvm_recv(tid, MSGT_FERROR); pvm_upkbyte(msg, bytes, 1); msg[bytes] = '\0'; fprintf(stderr, "Manager.c: Error, received death notification\n"); fprintf(stderr, "Manager.c: %s\n", msg); free(msg); killAllFilters(layout); exit(-1); } printf("Manager.c: starting work...\n"); // number of EOWs we expect to receive for(i = 0; i < layout->numFilters; i++) { totalEows += layout->filters[i]->filterPlacement.numInstances; #ifdef ATTACH if(layout->filters[i]->attached) { totalAttachedFilters += layout->filters[i]->filterPlacement.numInstances; } // TODO:TOSCO::: if(layout->filters[i]->attach) return 0; #endif } //we stay in this loop while we have to reconfigure //usually, this will be only one time, unless a we get some reconf message do { // sends work for each filter pvm_initsend(PvmDataRaw); int msgType; #ifdef VOID_FT if(!reconf) { #endif // First tell that is a mensage of WORK msgType = MSGT_WORK; #ifdef VOID_FT } else { // one fault has occurred msgType = MSGT_FT; } #endif pvm_pkint(&msgType, 1, 1); //then attach the work to it pvm_pkbyte((char *)work, workSize, 1); reconf = 0; //we are optimistic, always expect to not reconfigure // for each filter, send his work for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); // sends work to all filters of this set pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } /* TaskIdList *finalTaskIdList = NULL, *currentTaskIdList; int filtersThatUseTasks = 0; // Manager receives filter's terminated tasks list for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH // if this filter is of the attached // type i dont need worry about use Task // if(layout->filters[i]->attached)continue; #endif for(j = 0; j < pFilterP->numInstances; j++) { int instanceUseTasks = -1; // Get is this filter use tasks pvm_recv(pFilterP->tids[j], 0); pvm_upkint(&instanceUseTasks, 1, 1); layout->filters[i]->useTasks = instanceUseTasks; #ifdef VOID_FT if (instanceUseTasks) { currentTaskIdList = (TaskIdList *)unpackTaskIdList(); // Para fazer intersecao, gerente ordenar? as listas de tarefas recebidas e utilizar? a fun??o meet() do CrazyMiner/ID3. qsort(currentTaskIdList->vetor, currentTaskIdList->size, sizeof(int), compareTaskId); if(finalTaskIdList == NULL) { finalTaskIdList = currentTaskIdList; } else { // Manager makes the intersection of all finished tasks lists finalTaskIdList = taskIdListIntersection(finalTaskIdList, currentTaskIdList); taskIdListDestroy(currentTaskIdList); } } #endif } // for if (layout->filters[i]->useTasks) filtersThatUseTasks++; } // Gerente devolve resultado das intersecoes para todas as instancias de todos os filtros. for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH // if this filter is of the attached // type i dont need worry about use Task //TODO if(layout->filters[i]->attached)continue; #endif int needForwardTaskMessages = 1; if (filtersThatUseTasks < 2) needForwardTaskMessages = 0; #ifdef VOID_FT if (layout->filters[i]->useTasks) { // Send if they should forward task messages // and pigback :-) the final task id list pvm_initsend(PvmDataDefault); pvm_pkint(&needForwardTaskMessages, 1, 1); packTaskIdList(finalTaskIdList); pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } else { #endif // Only send if they should forward task messages pvm_initsend(PvmDataDefault); pvm_pkint(&needForwardTaskMessages, 1, 1); pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); #ifdef VOID_FT } #endif } taskIdListDestroy(finalTaskIdList); */ //now we receive the EOWs numEowsReceived = 0; //now we expect to receive EOW or errors while(numEowsReceived < totalEows) { //we are open to receive anything from anyone here //all messages to the manager should be tagged, so we now their type int szMsg = -1; int inst_tid = -1; int msgTag = -1; int bufid = pvm_recv(-1, -1); pvm_bufinfo(bufid, &szMsg, &msgTag, &inst_tid); switch (msgTag) { case (MSGT_EOW): { //received EOW, expect this usually int instance = -1; FilterSpec *pFilter = NULL; getFilterByTid(layout, inst_tid, &pFilter, &instance); if ((pFilter != NULL) && (instance != -1)) { printf("Manager.c: EOW received from %s, instance %d\n", pFilter->name, instance); } else { fprintf(stderr, "Manager.c: unknown EOW received! Shouldnt get here!\n"); } numEowsReceived++; break; } case (MSGT_AEXIT): case (MSGT_FERROR): { //someone called dsExit or system error at the filter side //common cause for this are library not found, wrong initscritpt etc char *message = (char*)malloc(sizeof(char)*szMsg+1); pvm_upkbyte(message, szMsg, 1); message[szMsg] = '\0'; //the filter and the instance FilterSpec *fp = NULL; int instance = -1; getFilterByTid(layout, inst_tid, &fp, &instance); if (msgTag == MSGT_AEXIT) { printf("Manager.c: Filter %s, instance %d(tid %x) called dsExit: %s\n", fp->name, instance, inst_tid, message); } else { printf("Manager.c: Filter %s error, instance %d(tid %x) called exit: %s\n", fp->name, instance, inst_tid, message); } free(message); // kill all instances killAllFilters(layout); exit(-1); break; } //task exited or host crashed case (MSGT_TEXIT): case (MSGT_HDEL): { //we only reconfigure a fixed number of times if (remainingReconfs <= 0) { //max number of reconfigurations reached... aborting fprintf(stderr, "Manager.c: max reconfigurations reached, aborting...\n"); fflush(stderr); fprintf(stdout, "Manager.c: max reconfigurations reached, aborting...\n"); fflush(stdout); reconf = 0; // kill all instances which might be alive killAllFilters(layout); exit(-1);; } #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "2 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif remainingReconfs--; reconf = 1; // In case of pvm notification, inst_tid will be t80000000 int notifiesRecv = 1; // We are receiving the first death notification int deadFilterTid = -1; FilterSpec *pFilter = NULL; int instanceDead = -1; // Get the tid and name of the dead filter int info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); //discover which filter died getFilterByTid(layout, deadFilterTid, &pFilter, &instanceDead); if((pFilter != NULL) && (instanceDead != -1)) { if (msgTag == MSGT_TEXIT) { fprintf(stderr, "Manager.c: filter %s: instance %d (tid t%x) of %d is dead!!!\n", pFilter->name, instanceDead, deadFilterTid, pFilter->filterPlacement.numInstances); } else { fprintf(stderr, "Manager.c: filter %s: instance %d (tid t%x) of %d machine's crashed!!!\n", pFilter->name, instanceDead, deadFilterTid, pFilter->filterPlacement.numInstances); } } printf("Manager.c: starting reconfiguration\n"); // kill all filters in the pipeline killAllFilters(layout); if (msgTag == MSGT_HDEL) { //int his case, host died, so we must change layout replaceCrashedHost(layout, pFilter, instanceDead); } #ifdef ATTACH if (pFilter->attached) { // In this case, all filters that were killed have to notify // their dead. notifiesRecv = 0; } #endif //Flush the streams //receive all messages which are about to arrive till we get the death notification //pvm order should garantee this #ifdef ATTACH while (notifiesRecv < (totalEows - totalAttachedFilters)) { #else while (notifiesRecv < totalEows) { #endif int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_TEXIT); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received notification (tag %d) about pvm tid t%x death\n", newMsgTag, deadFilterTid); notifiesRecv++; } #ifdef ATTACH if(pFilter->attached) { notifiesRecv = 1; } else { notifiesRecv = 0; } // Receive all EOW messages from the attached filters. while(notifiesRecv < totalAttachedFilters) { int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_EOW); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received EOW (tag %d) from pvm tid t%x\n", newMsgTag, inst_tid); notifiesRecv++; } #endif // probes for remaining machine crash notifications while (pvm_probe(-1, MSGT_HDEL) > 0) { int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_HDEL); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received notification (tag %d) about pvm tid t%x machine's crash\n", newMsgTag, deadFilterTid); // Replace the died host FilterSpec *pCrashedFilter = NULL; int crashedInstance = -1; getFilterByTid(layout, deadFilterTid, &pCrashedFilter, &crashedInstance); replaceCrashedHost(layout, pCrashedFilter, crashedInstance); } #ifdef BMI_FT updateAllFiltersFaultStatus(layout, FAULT_OTHER_FILTER_INST); pFilter->faultStatus = instanceDead; #endif //spawn all filters again spawnAllFilter(layout); #ifdef ATTACH // Verifies if the dead filter is an attached. If yes, spawn it. if(pFilter->attached == 1) { spawnOneAttachedInstance(layout, pFilter, instanceDead); } #endif resetStreams(layout); //resend the data sendFiltersData(layout); //start all over again numEowsReceived = 0; #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "3 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif break; } #ifdef VOID_TERM // One filter instance detected local termination case (MSGT_LOCALTERM): { int localTermTag; // filter instance local termination tag pvm_upkint(&localTermTag, 1, 1); verifyGlobalTermination(inst_tid, localTermTag); break; } #endif default: { fprintf(stderr, "Manager.c: error receiving EOW, unknown tag!!!\n"); } } //end switch message tag if((msgTag == MSGT_TEXIT) || (msgTag == MSGT_HDEL)) { // work should be sent again break; } } //end receiving eows } while(reconf == 1); //leave this loop if we will not reconfigure #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "4 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif printf("Manager.c: Work ended\n\n"); return 0; #endif } /// Finalize a Void pipeline. Only manager runs this. int finalizeDs(Layout *layout) { #ifdef NO_BARRIER #else int i; // Envia eof para todos os filtros // Primeiro envia se eh work (WORK) ou EOF (END_OF_FILTER) pvm_initsend(PvmDataRaw); int tipo_msg = MSGT_EOF; pvm_pkint(&tipo_msg, 1, 1); //sends the EOF message for all instances of the filter for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH if(layout->filters[i]->attach) continue;// this filter cant not receive a EOF because // it needs still runnig #endif pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } destroyLayout(layout); pvm_exit(); return 0; #endif }
IPstream::IPstream ( const int fromProcNo, const label bufSize, streamFormat format, versionNumber version ) : Pstream(bufSize), Istream(format, version), fromProcNo_(fromProcNo), messageSize_(0) { setOpened(); setGood(); int bufid, tag, tid; // If the buffer size is not specified then probe the incomming message if (!bufSize) { // Probe read buffer until message arrives. while (!(bufid = pvm_probe(procID(fromProcNo_), msgType()))); // When the message arrives find its size pvm_bufinfo(bufid, &messageSize_, &tag, &tid); // Resize buffer to message size buf_.setSize(messageSize_); } // Read message into buffer if ( pvm_precv ( procID(fromProcNo_), msgType(), buf_.begin(), buf_.size(), PVM_BYTE, &tid, &tag, &messageSize_ ) != PvmOk ) { FatalErrorIn("IPstream::IPstream(const int fromProcNo)") << "pvm_precv cannot receive incomming message" << ::abort; } // Check size of message read if (messageSize_ > buf_.size()) { FatalErrorIn("IPstream::IPstream(const int fromProcNo)") << "buffer (" << buf_.size() << ") not large enough for incomming message (" << messageSize_ << ')' << ::abort; } }
int main(int argc, char* argv[]) { // Timeout for Message Receive struct timeval tmout; tmout.tv_usec=100; tmout.tv_sec=0; // Size for Data Packets int data_size; // Numer of running tasks int curcount; // Check if all data sent bool finished; // TID of host to send data int slave_tid; // Data Buffer for outgoing messages int buff; // Read the frequency list read_freq_list(FREQ_LIST_FILE); // Total number of Data Elements int data_count=freq_count; // Current possition in the array int current_data=0; // Store master-id in PVM { int master_id=pvm_mytid(); pvm_delete((char *) "master",0); pvm_insert((char *)"master",0,master_id); // Parameters for Spawn char *params[2]={(char *) "1", NULL}; char *slave=(char *) "matcher_slave"; int tids[HOST_COUNT]; int spawncount=pvm_spawn(slave,params,PvmTaskDefault,NULL,HOST_COUNT,tids); } // Get number of current tasks pvm_tasks(0,&curcount,NULL); finished=false; do { // Check for error if (pvm_probe(-1,MSG_SLAVE_ERROR)) { char error[32]; int err_no=0; pvm_recv(-1,MSG_SLAVE_ERROR); pvm_upkint(&slave_tid,1,1); pvm_upkint(&err_no,1,1); printf("Fehler in Slave %d Code %d\n",slave_tid,err_no); } // Send Data or End-Of-Data else if(pvm_trecv(-1,MSG_SLAVE_READY,&tmout)>0) { pvm_upkint(&slave_tid,1,1); // No more data if (finished) { pvm_initsend(PvmDataDefault); pvm_send(slave_tid,MSG_MASTER_EOD); } // Send data packet else { buff=pvm_initsend(PvmDataDefault); if (data_count>=PACK_SIZE) data_size=PACK_SIZE; else data_size=data_count; data_count-=data_size; pvm_pkint(&data_size,1,1); for(int ct=0;ct<data_size;ct++) { // Store the data in the buffer if (current_data<=freq_count) { pvm_pkstr(freq_list[current_data]->word.getValue()); pvm_pkulong(&(freq_list[current_data]->count),1,1); current_data++; } } pvm_initsend(PvmDataDefault); pvm_send(slave_tid,MSG_MASTER_DATA); printf("Send %d sets of %d to %d\n",data_size,data_count,slave_tid); if (data_count==0) finished=true; } } // Receive Result else if (pvm_probe(-1,MSG_SLAVE_RESULT)) { if (pvm_trecv(-1,MSG_SLAVE_RESULT,&tmout)>0) { pvm_upkint(&slave_tid,1,1); // Number of elements pvm_upkint(&data_size,1,1); for (int ct=0;ct<data_size;ct++) { unsigned long res1=0; unsigned long res2=0; // Read the result data /* to fill */ // pvm_upkulong(&res1,1,1); // pvm_upkulong(&res2,1,1); // printf("Result %llu\n",(unsigned long long int)res2*ULONG_MAX+res1); } PvmDataDefault pvm_send(slave_tid,MSG_MASTER_EXIT); } } pvm_tasks(0,&curcount,NULL); } while(curcount>2); pvm_exit(); return 0; }
render_frame() { pixel Pixel_colour ; /* pixel colour values */ int X_counter ; /* X axis counter */ int Y_counter ; /* Y axis counter */ int Block_counter ; /* block section counter */ int Worker_counter ; /* counter for the number of workers done */ double Block_angle ; /* angle between blocks */ viewer Viewpoint ; /* the viewpoint of the user */ /* copy the users viewpoint into the working variable */ Viewpoint.X=User.X ; Viewpoint.Y=User.Y ; Viewpoint.Z=User.Z ; Viewpoint.X_angle=User.X_angle ; Viewpoint.Y_angle=User.Y_angle ; Viewpoint.Z_angle=User.Z_angle ; /* set up the ray angles */ Block_angle=(X_view_angle/User_view.X_size)*Pixel_buffer_width ; Viewpoint.Z_angle=Viewpoint.Z_angle-(X_view_angle/2)-((1/360)*2*M_PI) ; for (Block_counter=0;Block_counter<Number_of_workers;Block_counter++) { /* send out work to worker */ pvm_initsend (PvmDataDefault) ; pvm_pkdouble(&Viewpoint.X,1,1); pvm_pkdouble(&Viewpoint.Y,1,1) ; pvm_pkdouble(&Viewpoint.Z,1,1) ; pvm_pkdouble(&Viewpoint.X_angle,1,1) ; pvm_pkdouble(&Viewpoint.Y_angle,1,1) ; pvm_pkdouble(&Viewpoint.Z_angle,1,1) ; pvm_send (Worker_tids[Block_counter],WORK) ; /* set the viewpoint for the next one */ Viewpoint.Z_angle=Viewpoint.Z_angle+Block_angle ; } /* end of for loop */ /* finished sending the data */ /* set the number of workers finished to zero */ Worker_counter=0 ; /* get the data back */ while ( Worker_counter < Number_of_workers) { for (Block_counter=0;Block_counter<Number_of_workers;Block_counter++) { if (pvm_probe (Worker_tids[Block_counter],DATA)) /* wait for reply */ { pvm_recv (Worker_tids[Block_counter],DATA) ; pvm_upkbyte (Pixel_buffer,Pixel_buffer_size,1) ; /* increment the counter for the number of workers that have finished */ Worker_counter=Worker_counter+1 ; /* copy the pixel to the image buffer */ for (X_counter=0 ; X_counter<Pixel_buffer_width ; X_counter++ ) { for (Y_counter=0; Y_counter<User_view.Y_size ; Y_counter++ ) { /* copy pixel data */ Image_buffer [(Y_counter*User_view.X_size*3)+ (X_counter*3)+ (Block_counter*Pixel_buffer_width*3)+ 0] = Pixel_buffer[(Y_counter*Pixel_buffer_width*3)+ (X_counter*3)+ 0] ; Image_buffer[(Y_counter*User_view.X_size*3)+ (X_counter*3)+ (Block_counter*Pixel_buffer_width*3)+ 1] = Pixel_buffer[(Y_counter*Pixel_buffer_width*3)+ (X_counter*3)+ 1] ; Image_buffer[(Y_counter*User_view.X_size*3)+ (X_counter*3)+ (Block_counter*Pixel_buffer_width*3)+ 2] = Pixel_buffer[(Y_counter*Pixel_buffer_width*3)+ (X_counter*3)+ 2] ; /* end Y loop */ } /* end X loop */ } } /* end the if */ } /* end the while loop */ /* end drawing code */ } /* copy the data to the window */ glDrawPixels(User_view.X_size,User_view.Y_size,GL_RGB, GL_UNSIGNED_BYTE,Image_buffer) ; /* flush the graphics pipeline */ glFlush(); }