void mcs_lock(mcs_lock_t *l, mcs_node_t *me) { //-------------------------------------------------------------------- // initialize my queue node //-------------------------------------------------------------------- me->next = 0; //-------------------------------------------------------------------- // initialization must complete before anyone sees my node //-------------------------------------------------------------------- enforce_store_to_rmw_order(); //-------------------------------------------------------------------- // install my node at the tail of the lock queue. // determine my predecessor, if any. //-------------------------------------------------------------------- mcs_node_t *predecessor = fas(&(l->tail), me); //-------------------------------------------------------------------- // if I have a predecessor, wait until it signals me //-------------------------------------------------------------------- if (predecessor) { //------------------------------------------------------------------ // prepare to block until signaled by my predecessor //------------------------------------------------------------------ me->blocked = true; //------------------------------------------------------------------ // blocked field must be set before linking behind my predecessor //------------------------------------------------------------------ enforce_store_to_store_order(); predecessor->next = me; // link behind my predecessor while (me->blocked); // wait for my predecessor to clear my flag //------------------------------------------------------------------ // no reads or writes in the critical section may occur until my // flag is set //------------------------------------------------------------------ enforce_load_to_access_order(); } else { //------------------------------------------------------------------ // no reads or writes in the critical section may occur until after // my fetch-and-store //------------------------------------------------------------------ enforce_rmw_to_access_order(); } }
void multi_reset_lock_free(unsigned int num_loops,unsigned long amount,vector<double> obj_no){ //For lock-free implementation //so it can be used to determine number of retrial loops //obj_no specifies which objects to set values unsigned int tmp_size=obj_no.size(); unsigned int loop_itr=1; //Holds loop iteration number unsigned int obj_indx=0; unsigned int itr_per_obj=num_loops<tmp_size?1:num_loops/tmp_size; while(loop_itr<num_loops){ //Traverse through "free_value"s specified by obj_no. In each iteration set one of them to amount fas(&(m_free_value_ptr[(int)(obj_no[obj_indx])]),amount); if(loop_itr%itr_per_obj==0 && num_loops-loop_itr>itr_per_obj){ obj_indx++; obj_indx=obj_indx>tmp_size?tmp_size:obj_indx; } loop_itr++; } }
vector<unsigned long long> multi_reset_lock_free(unsigned int num_loops,unsigned long amount,vector<double> obj_no,double wr_per){ /* * For lock-free implementation. obj_no specifies which objects to set values. wr_per is "write" * percentage. 1-wr_per is read percentage. Return vector contains number of success access to * object, number of failure access to object, and time for failure access. */ unsigned int tmp_size=obj_no.size(); unsigned int loop_itr=1; //Holds loop iteration number unsigned int obj_indx=0; unsigned long tmp_res; vector<unsigned long long> fin_res, med_res; //final and intermediate result vectors fin_res.push_back(0); //initial number of success access to object fin_res.push_back(0); //initial number of failed access to object fin_res.push_back(0); //initial time for failed access to object unsigned int itr_per_obj=num_loops<tmp_size?1:num_loops/tmp_size; while(loop_itr<num_loops){ //Traverse through "free_value"s specified by obj_no. In each iteration set one of them to amount if((loop_itr%100)/100.0 < wr_per){ //write operation med_res=fas(&(m_free_value_ptr[(int)(obj_no[obj_indx])]),amount); fin_res[1]+=med_res[0]; fin_res[2]+=med_res[1]; } else{ //read operation tmp_res=m_free_value_ptr[(int)(obj_no[obj_indx])]; } if(loop_itr%itr_per_obj==0 && num_loops-loop_itr>itr_per_obj){ obj_indx++; } loop_itr++; obj_indx=obj_indx>tmp_size?tmp_size:obj_indx; } fin_res[0]=num_loops; return fin_res; }