/** changes the fork owner if it is dirty, and the other side * has requested for it. Fork must be locked. * Returns true if fork moved. false otherwise. */ inline bool advance_fork_state_on_lock(size_t forkid, vertex_id_type source, vertex_id_type target) { unsigned char currentowner = forkset[forkid] & OWNER_BIT; // edge_ids for the request bits unsigned char my_request_bit = request_bit(currentowner); unsigned char other_request_bit = request_bit(!currentowner); bool current_owner_is_eating = (currentowner == OWNER_SOURCE && philosopherset[source].state == EATING) || (currentowner == OWNER_TARGET && philosopherset[target].state == EATING); bool current_owner_is_hungry = (currentowner == OWNER_SOURCE && philosopherset[source].state == HUNGRY) || (currentowner == OWNER_TARGET && philosopherset[target].state == HUNGRY); // if the current owner is not eating, and the // fork is dirty and other side has placed a request if (current_owner_is_eating == false && (forkset[forkid] & DIRTY_BIT) && (forkset[forkid] & other_request_bit)) { // change the owner and clean the fork) forkset[forkid] = (!currentowner); if (current_owner_is_hungry) { forkset[forkid] |= my_request_bit; } return true; } return false; }
inline bool advance_fork_state_on_unlock(size_t forkid, vertex_id_type source, vertex_id_type target) { unsigned char currentowner = forkset[forkid] & OWNER_BIT; // edge_ids for the request bits unsigned char my_request_bit = request_bit(currentowner); unsigned char other_request_bit = request_bit(!currentowner); // if the current owner is not eating, and the // fork is dirty and other side has placed a request if ((forkset[forkid] & DIRTY_BIT) && (forkset[forkid] & other_request_bit)) { // change the owner and clean the fork) // keep my request bit if any forkset[forkid] = (forkset[forkid] & my_request_bit) | (!currentowner); return true; } return false; }
/** Places a request for the fork. Requires fork to be locked */ inline void request_for_fork(size_t forkid, bool nextowner) { forkset[forkid] |= request_bit(nextowner); }
/** Places a request for the fork. Requires fork to be locked */ inline void request_for_fork(size_t forkid, bool nextowner) { __sync_fetch_and_or(&forkset[forkid], request_bit(nextowner)); }