value Pvm_trecv(value tid, value msgtag, value sec, value usec) { int res; struct timeval t; if (sec < 0 || usec < 0) { t.tv_sec = Int_val(sec); t.tv_usec = Int_val(usec); res = pvm_trecv(Int_val(tid), Int_val(msgtag), &t); } else res = pvm_trecv(Int_val(tid), Int_val(msgtag), NULL); if (res<0) TreatError(res); return(Val_int(res)); }
int treceive_msg(int who, int what, struct timeval *timeout) { int r_bufid; PVM_FUNC(r_bufid, pvm_trecv(who, what, timeout)); return(r_bufid); }
static void find_tree_manager(const int my_tid, int &tm_tid) { struct pvmtaskinfo *taskp = 0; int ntask = 0; pvm_tasks(0, &ntask, &taskp); int * tids = new int[ntask]; int i, k; for (i = 0, k = 0; i < ntask; ++i) { if (taskp[i].ti_ptid != 0) continue; // has a parent, can't be the TM if (taskp[i].ti_tid == my_tid) continue; // self // Otherwise it could be the TM (might be a console...) tids[k++] = taskp[i].ti_tid; } if (tm_tid != 0) { // Check that the given tid is among the candidates for (i = 0; i < k; ++i) if (tids[i] == tm_tid) break; if (i == k) stop("No TM candidate has the given tid... Aborting.\n"); } else { // Broadcast a query to the candidates pvm_initsend(PvmDataRaw); pvm_mcast(tids, k, BCP_ARE_YOU_TREEMANAGER); // Wait for an answer struct timeval tout = {15, 0}; int bufid = pvm_trecv(-1, BCP_I_AM_TREEMANAGER, &tout); if (bufid == 0) stop("No TM candidates replied within 30 seconds... Aborting.\n"); int bytes = 0, msgtag = 0; pvm_bufinfo(bufid, &bytes, &msgtag, &tm_tid); } delete[] tids; }
main() { GHashTable* skiers_weights = g_hash_table_new(g_str_hash, g_str_equal); GQueue *waiting_req_q1 = g_queue_new(); GQueue *waiting_req_q2 = g_queue_new(); int first_lift_free, second_lift_free; int mytid, mstrtid, myind, number_of_skiers, *tids, first_lift_capacity, second_lift_capacity, i, phase, local_clock; time_t t; char slave_name[NAMESIZE]; char diag[200]; struct state_info info; mytid = pvm_mytid(); srand(time(NULL) + mytid); gethostname(slave_name, NAMESIZE); pvm_joingroup(GROUP); get_initial_values(&mstrtid, &number_of_skiers, &tids, &skiers_weights, &first_lift_capacity, &second_lift_capacity); info.mstrtid = mstrtid; first_lift_free = first_lift_capacity; second_lift_free = second_lift_capacity; int *my_weight_ptr = g_hash_table_lookup(skiers_weights, &mytid); int my_weight = *my_weight_ptr; int all_skiers_weight = 0; for(i=0; i<number_of_skiers; i++) { int *lookup = g_hash_table_lookup(skiers_weights, &tids[i]); all_skiers_weight += *lookup; } all_skiers_weight -= my_weight; sprintf(diag, "sum of all other skiers' weights = %d", all_skiers_weight); diag_msg(mstrtid, mytid, diag); i=0; while (tids[i] != mytid) { i++; } pvm_initsend(PvmDataDefault); pvm_pkint(&mytid, 1, 1); pvm_pkstr(slave_name); int *wat_to_send = g_hash_table_lookup(skiers_weights, &mytid); pvm_pkint(wat_to_send, 1, 1); pvm_send(mstrtid, MSG_SLV); // bariera local_clock = 0; pvm_barrier(GROUP, number_of_skiers); int time_to_wait; // main loop diag_msg(mstrtid, mytid, "entering main loop"); while (1) { int can_enter_lift = 0; int chosen_lift = -1; int accepts_received = 0; int my_request_timestamp = -1; info.accepts_received = &accepts_received; info.my_request_timestamp = &my_request_timestamp; phase = PHASE_DOWNHILL; struct timeval timeout; random_timeout(&timeout, 3, 10); struct timeval start_time; gettimeofday(&start_time, NULL); struct timeval elapsed; elapsed.tv_sec = 0; elapsed.tv_usec = 0; sprintf(diag, "entered %s, time=%zu.%zu", stringify(phase), timeout.tv_sec, timeout.tv_usec); diag_msg(mstrtid, mytid, diag); while (1) { int bufid = pvm_trecv(-1, -1, &timeout); if (bufid) { // diag_msg(mstrtid, mytid, "Got message in PHASE_DOWNHILL"); struct msg incoming_msg; unpack(&incoming_msg); int *sender_weight = g_hash_table_lookup(skiers_weights, &incoming_msg.sender_tid); // handle the message accordingly prepare_info(&info, mytid, &local_clock, phase, &chosen_lift, &can_enter_lift, &first_lift_free, &second_lift_free, incoming_msg, waiting_req_q1, waiting_req_q2); info.skiers_weights = skiers_weights; handle_message(incoming_msg, info); } // break the loop if time elapsed is more than the timeout, else wait for another message struct timeval current_time; gettimeofday(¤t_time, NULL); timeval_subtract(&elapsed, ¤t_time, &start_time); if (elapsed.tv_sec * 1000000 + elapsed.tv_usec >= timeout.tv_sec * 1000000 + timeout.tv_usec) break; else timeval_subtract(&timeout, &timeout, &elapsed); } // want to go up diag_msg(mstrtid, mytid, ""); phase = PHASE_WAIT_REQUEST; // choose the lift (1 or 2) // determine if we can fit on the lift (based on our knowledge from the accepts we had sent) sprintf(diag, "entered PHASE_WAIT_REQUEST, weight=%d, LIFT_1=%d, LIFT_2=%d",my_weight,first_lift_free,second_lift_free); diag_msg(mstrtid, mytid, diag); if (my_weight > first_lift_free && my_weight > second_lift_free) { // no lift for us // wait for RELEASE messages until we can fit in the lift // meanwhile: handle all incoming messages, responding accordingly (ALWAYS respond with accepts) while (1) { sprintf(diag, "no space in lifts, weight=%d, LIFT_1=%d, LIFT_2=%d",my_weight,first_lift_free,second_lift_free); diag_msg(mstrtid, mytid, diag); int bufid = pvm_recv(-1, -1); struct msg incoming_msg; unpack(&incoming_msg); prepare_info(&info, mytid, &local_clock, phase, &chosen_lift, &can_enter_lift, &first_lift_free, &second_lift_free, incoming_msg, waiting_req_q1, waiting_req_q2); info.skiers_weights = skiers_weights; handle_message(incoming_msg, info); // now check if we should break the loop and go to the next phase! if (chosen_lift == LIFT_1 || chosen_lift == LIFT_2) { sprintf(diag, "weight=%d, LIFT_1=%d, LIFT_2=%d, choosing %s", my_weight, first_lift_free, second_lift_free, stringify(chosen_lift)); diag_msg(mstrtid, mytid, diag); // broadcast a request with our chosen lift and go to (*) bcast_request_msg(info); break; } } } else { // if there is a fitting lift if (my_weight <= first_lift_free && my_weight > second_lift_free) { // can only go to first lift chosen_lift = LIFT_1; } else if (my_weight > first_lift_free && my_weight <= second_lift_free) { // can only go to second lift chosen_lift = LIFT_2; } else { // can go to either lift - worst fit if (first_lift_free > second_lift_free) chosen_lift = LIFT_1; else if (first_lift_free < second_lift_free) chosen_lift = LIFT_2; else // equal chosen_lift = (rand() % 2 == 1) ? LIFT_1 : LIFT_2; } info.my_lift_number = &chosen_lift; info.mytid = mytid; info.local_clock = &local_clock; info.skiers_weights = skiers_weights; // broadcast a request with our chosen lift and go to (*) bcast_request_msg(info); // sprintf(diag,"So I am here just before broadcasting REQUEST and I choose lift %d and in info %d",chosen_lift, *info.my_lift_number); sprintf(diag, "weight=%d, LIFT_1=%d, LIFT_2=%d, choosing %s", my_weight, first_lift_free, second_lift_free, stringify(chosen_lift)); diag_msg(mstrtid, mytid, diag); } sprintf(diag, "*** chosen_lift=%s", stringify(chosen_lift)); // waiting for accepts (*) // wait for enough accepts or just as much as required to be sure that we can get in // meanwhile: handle all incoming messages, responding accordingly (not send back accept only to those with worse priority that can't fit together with us) // diag_msg(mstrtid, mytid, "entering PHASE_WAIT_ACCEPTS"); phase = PHASE_WAIT_ACCEPTS; int pending = all_skiers_weight; info.pending_accepts_sum = &pending; sprintf(diag, "entered PHASE_WAIT_ACCEPTS, lift=%s", stringify(chosen_lift)); diag_msg(mstrtid, mytid, diag); while (1) { int bufid = pvm_recv(-1, -1); struct msg incoming_msg; unpack(&incoming_msg); prepare_info(&info, mytid, &local_clock, phase, &chosen_lift, &can_enter_lift, &first_lift_free, &second_lift_free, incoming_msg, waiting_req_q1, waiting_req_q2); handle_message(incoming_msg, info); // check if there are enough amount of acceptes - can break the loop and go to the critical section if (can_enter_lift) { break; } } // random waiting up to the hill - critical section phase = PHASE_CRITICAL; random_timeout(&timeout, 3, 10); gettimeofday(&start_time, NULL); elapsed.tv_sec = 0; elapsed.tv_usec = 0; sprintf(diag, "entered PHASE_CRITICAL, lift=%s, time=%zu.%zu", stringify(chosen_lift), timeout.tv_sec, timeout.tv_usec); diag_msg(mstrtid, mytid, diag); while (1) { int bufid = pvm_trecv(-1, -1, &timeout); if (bufid) { // unpack the received message struct msg incoming_msg; // int msgtag = -1, sender_tid = -1, lift_number = -1, timestamp = -1; unpack(&incoming_msg); // handle the message accordingly prepare_info(&info, mytid, &local_clock, phase, &chosen_lift, &can_enter_lift, &first_lift_free, &second_lift_free, incoming_msg, waiting_req_q1, waiting_req_q2); handle_message(incoming_msg, info); } // break the loop if time elapsed is more than the timeout, else wait for another message struct timeval current_time; gettimeofday(¤t_time, NULL); timeval_subtract(&elapsed, ¤t_time, &start_time); if (elapsed.tv_sec * 1000000 + elapsed.tv_usec >= timeout.tv_sec * 1000000 + timeout.tv_usec) break; else timeval_subtract(&timeout, &timeout, &elapsed); } // release - broadcast the RELEASE message to all others info.mytid = mytid; info.local_clock = &local_clock; info.my_lift_number = &chosen_lift; bcast_release_msg(info); // send all the requests stored in the queue (mcast automatically clears it) mcast_accept_msg(info); } pvm_exit(); }
int update_kolejka(){ int tid_rycerza; int czasid_rycerza; int typ_wiadomosci; //pthread_mutex_lock(&sem_recv); //SendMessagetoMaster("PRZED MESSAGE"); //Odbieramy if(pvm_trecv(-1, MSG_CZASID, &timeout) > 0){ //pvm_recv(-1,MSG_CZASID); pvm_upkint(&typ_wiadomosci,1,1); pvm_upkint(&tid_rycerza,1,1); pvm_upkint(&czasid_rycerza,1,1); //pthread_mutex_unlock(&sem_recv); //SendMessagetoMaster("START MESSAGE"); if(typ_wiadomosci == CONFIRM){ //SendMessagetoMaster("Przyszla wiadomosc od rycerza do rycerza: CONFIRM"); ile_odpowiedzialo ++ ; if(ile_odpowiedzialo == RYCERZE-1){ wszyscy_odpowiedzieli = 1 ; ile_odpowiedzialo = 0 ; //SendMessagetoMaster("WSZYSCY: CONFIRM"); } //Update update_rycerz(tid_rycerza,czasid_rycerza); } else if (typ_wiadomosci == REQUEST){ //SendMessagetoMaster("Przyszla wiadomosc od rycerza do rycerza: REQUEST"); //Update update_rycerz(tid_rycerza,czasid_rycerza); //SendMessagetoMaster("Po update REQUEST"); //Wysylamy pvm_initsend(PvmDataDefault); int typ = CONFIRM ; pvm_pkint(&typ,1,1); pvm_pkint(&tid_rycerza,1,1); int moj_czasid = getCzasId(mytid); pvm_pkint(&moj_czasid,1,1); pvm_send(tid_rycerza, MSG_CZASID); //SendMessagetoMaster("PO WYSLANIU CONFIRM"); } else{ SendMessagetoMasterTyp("WTF ? Co to za typ_wiadomosci ?",typ_wiadomosci); } //SendMessagetoMaster("END MESSAGE"); if(wszyscy_odpowiedzieli == 1){ return 1 ; }else{ return 0 ; } } else{ return 0 ; } }
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; }