Untitled
unknown
plain_text
a year ago
2.5 kB
12
Indexable
#include "q2tallyVotes.h"
#include "q2print.h"
void TallyVotes::wait() {
bench.wait(); // wait until signalled
while ( rand() % 2 == 0 ) { // multiple bargers allowed
try {
_Accept( vote || done ) { // accept barging callers
} _Else { // do not wait if no callers
} // _Accept
} catch( uMutexFailure::RendezvousFailure & ) {}
} // while
}
void TallyVotes::signalAll() { // also useful
while ( ! bench.empty() ) bench.signal(); // drain the condition
}
TallyVotes::Tour TallyVotes::vote ( unsigned int id, Ballot ballot ) {
if (voters < group) { // if in quorum failure state, immediately throw
_Throw Failed();
}
int currentTicket = ticket;
ticket++;
while(true) {
if (votersFinalized && currentTicket > currentTicketLimit) {
wait();
} else {
break;
}
}
VOTER_ENTER( group );
currentlyVoted++;
numPictures += ballot.picture; // update tally counts
numStatues += ballot.statue;
numGifts += ballot.giftshop;
printer.print(id, Voter::States::Vote, ballot);
if (currentlyVoted == 0) {
groupNumber++;
}
Tour t;
t.groupno = groupNumber;
if (currentlyVoted == group) { // everyone in the group has voted
// calculate the winner
if (numGifts >= numPictures && numGifts >= numStatues) {
destination = TallyVotes::TourKind::GiftShop;
} else if (numPictures >= numStatues) {
destination = TallyVotes::TourKind::Picture;
} else {
destination = TallyVotes::TourKind::Statue;
}
numGifts = 0; // reset values to 0 as we are done with the current tour
numPictures = 0;
numStatues = 0;
currentTicketLimit = currentTicket;
votersFinalized = true;
signalAll();
t.tourkind = destination;
printer.print(id, Voter::States::Complete, t);
} else {
printer.print(id, Voter::States::Block, currentlyVoted);
wait();
if (voters < group && !votersFinalized) {
_Throw Failed();
}
printer.print( id, Voter::States::Unblock, currentlyVoted - 1);
}
t.tourkind = destination;
currentlyVoted--;
if (currentlyVoted == 0) {
votersFinalized = false;
signalAll();
}
VOTER_LEAVE( group );
return Tour{destination, groupNumber};
}
void TallyVotes::done(
#if defined( TASK )
unsigned int id
#endif
) {
voters--;
if (voters < group) {
signalAll();
}
}Editor is loading...
Leave a Comment