int dsm_send_msg(int nodefd, dsm_message_t *msg) { binn *obj; obj = binn_object(); binn_object_set_int32(obj, DSM_MSG_KEY_TYPE, msg->type); switch (msg->type) { case CONNECT: binn_object_set_int32(obj, DSM_MSG_KEY_BITNESS, msg->connect_args.bitness); binn_object_set_int32(obj, DSM_MSG_KEY_PAGESIZE, msg->connect_args.pagesize); break; case CONNECT_ACK: binn_object_set_int16(obj, DSM_MSG_KEY_BITNESS, msg->connect_ack_args.bitness_ok); binn_object_set_int16(obj, DSM_MSG_KEY_PAGESIZE, msg->connect_ack_args.pagesize_ok); binn_object_set_int32(obj, DSM_MSG_KEY_PAGECOUNT, msg->connect_ack_args.page_count); break; case LOCKPAGE: binn_object_set_int32(obj, DSM_MSG_KEY_PAGEID, msg->lockpage_args.page_id); binn_object_set_int16(obj, DSM_MSG_KEY_RIGHTS, msg->lockpage_args.access_rights); break; case INVALIDATE: binn_object_set_int32(obj, DSM_MSG_KEY_PAGEID, msg->invalidate_args.page_id); break; case INVALIDATE_ACK: binn_object_set_int32(obj, DSM_MSG_KEY_PAGEID, msg->invalidate_ack_args.page_id); break; case GIVEPAGE: binn_object_set_int32(obj, DSM_MSG_KEY_PAGEID, msg->givepage_args.page_id); binn_object_set_int16(obj, DSM_MSG_KEY_RIGHTS, msg->givepage_args.access_rights); binn_object_set_blob(obj, DSM_MSG_KEY_DATA, msg->givepage_args.data, dsm_g->mem->pagesize); break; case SYNC_BARRIER: binn_object_set_int16(obj, DSM_MSG_KEY_BARRIER, msg->sync_barrier_args.slave_to_wait); case BARRIER_ACK: break; case TERMINATE: break; default: log("Unknown message type to send !\n"); return -1; } if(dsm_send(nodefd, binn_ptr(obj), binn_size(obj)) < 0) { log("Could not send to node %d message type: %d\n", nodefd, msg->type); return -1; } binn_free(obj); return 0; }
void commit_comes(int sessionfd, const char* msg, int RW){ long pageaddr = *(long*)msg; block_signal(SIGALRM); // printf(" invalidation responce at %lx\n", pageaddr); q_dta_t* the_queue = &req_queues[addr_to_pagenum (dsm_heaptop, pageaddr, dsm_pagesize)]; if (RW == QUEUE_WRITE){ memcpy((void*)pageaddr, msg + sizeof(long), dsm_pagesize); assert(the_queue->update_pending); if (the_queue->listlen){ if (the_queue->num_parallel_readers){ for (int i = 0;i < the_queue->num_parallel_readers;i++){ int posval = the_queue->fd_queue[(i + the_queue->currhead) % (2*NumNode)]; dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pageaddr,ABS(posval)); } }else{ dsm_send(0, dsm_pagesize, SERVER_PAGE, (char*)pageaddr, ABS(queue_top(the_queue))); } } } the_queue->update_pending = 0; unblock_signal(SIGALRM); }
/* * This function executes in signal handler context */ static void timerhandler(int whatever){ // printf("timer tick\n"); if (clock_state == TIMER_STOPPED) return; long invalbuf[NUM_PAGES]; int numinval = 0; int posval; clock_stop(); for (int i = 0; i < NumNode; ++i){ numinval = 0; for (int curr = activehead, last = curr;curr != -1; last = curr,curr = req_queues[curr].next_active){ if (curr == activehead){ last = curr; } if (curr_owners[curr] != i){ continue; } q_dta_t* the_queue = &(req_queues[curr]); if (the_queue->update_pending){ continue; } if (!the_queue->num_writers) continue; if (popped[curr]) continue; //better be true assert(the_queue->num_writers); qaddr = pagenum_to_addr(dsm_heaptop, curr, dsm_pagesize); int sessionfd = pop_queue(the_queue); popped[curr] = 1; if (!READ_REQ(sessionfd)){ the_queue->num_writers--; //was writing; need to wait for update if (the_queue->listlen && !the_queue->num_writers){ for (int i = 0;i < the_queue->listlen;i++){ the_queue->num_parallel_readers++; } } the_queue->update_pending = 1; }else{ if (the_queue->num_parallel_readers > 0){ //read requests granted before any writers came along //always at front of queue the_queue->num_parallel_readers --; } if (the_queue->listlen && !the_queue->num_parallel_readers){ int nextsessionfd = queue_top(the_queue); dsm_send(0, dsm_pagesize, SERVER_PAGE,(char*)pagenum_to_addr(dsm_heaptop,curr,dsm_pagesize) , ABS(nextsessionfd)); } } if ((!the_queue->listlen) || ABS(queue_top(the_queue)) != nid_to_sessionfd[i]){ invalbuf[numinval++] = curr * dsm_pagesize + dsm_heaptop; } if (the_queue->listlen){ //transfer ownership int tmp; posval = queue_top(the_queue); curr_owners[curr] = (short)(long)hash_get((void*)(long)ABS(posval),sessionfd_to_nid,&tmp); assert(tmp); }else{ curr_owners[curr] = -1; } if (!the_queue->num_writers){ if (the_queue->listlen){ the_queue->q_state = QUEUE_READERS; }else{ the_queue->q_state = QUEUE_EMPTY; } //take off the active list if (curr == last){ //delete from head activehead = req_queues[curr].next_active; }else{ req_queues[last].next_active = req_queues[curr].next_active; curr = last; } } } //TODO: send invalidation message to client if (numinval) { //printf("about to send %d inv to %d\n",numinval, nid_to_sessionfd[i]); dsm_send(0, sizeof(long)*numinval,SERVER_INVALIDATE, (char*)invalbuf, nid_to_sessionfd[i]); } } if (activehead != -1){ clock_start(); } our_memset (popped, 0, sizeof(char)*NUM_PAGES); //printf("END timer tick\n"); }
void queue_for_page(int sessionfd, long pagenum, int RW){ block_signal(SIGALRM); q_dta_t* the_queue = &(req_queues[pagenum]); assert(the_queue->num_parallel_readers <= the_queue->listlen); int make_active = 0; qaddr = pagenum_to_addr(dsm_heaptop, pagenum, dsm_pagesize); add_to_queue(RW*sessionfd, the_queue); if (RW == QUEUE_READ){ switch (the_queue->q_state){ case QUEUE_EMPTY: { int found; curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found); assert(found); the_queue->q_state = QUEUE_READERS; if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } the_queue->num_parallel_readers = 1; break; } case QUEUE_WRITERS: { break; } case QUEUE_READERS: { if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } the_queue->num_parallel_readers++; break; } default:break; } }else{ the_queue->num_writers ++; switch (the_queue->q_state){ case QUEUE_EMPTY: { int found; curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found); assert(found); the_queue->q_state = QUEUE_WRITERS; make_active = 1; if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } break; } case QUEUE_WRITERS: { break; } case QUEUE_READERS: { the_queue->q_state = QUEUE_WRITERS; make_active = 1; break; } default:break; } } if (make_active){ req_queues[pagenum].next_active = activehead; activehead = pagenum; clock_start(); } unblock_signal(SIGALRM); }