int main(int argc, char *argv[]) { printf("Threaded Ticket Seller - Project 3\n"); // Garbage seller is used to hold persons that // have been processed by the other sellers // we have to wait on possible frustrated users // threads have cleared or they may crash when their // data is freed garbage = createSeller(HIGH, 11); // finish creation of the concert hall hall.isSoldOut = FALSE; hall.hasStarted = FALSE; hall.lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(hall.lock,NULL); pthread_mutex_init(&outputLock,NULL); if (argc == 2) { if (argv[1][0] == 'T') { // do self test printf("Self Test\n"); mkTest(); printf("Self test succeeded\n"); exit(0); } int N = atoi(argv[1]); printf("Run with %d customers per ticket seller\n", N); //Create Sellers Seller *allSellers[NUM_SELLERS]; allSellers[0] = createSeller(HIGH, 0); int i; for (i = 1; i < 4; i++) { allSellers[i] = createSeller(MEDIUM, i); } for(i = 1; i < 7; i++){ allSellers[i+3] = createSeller(LOW, i + 3); } //declare person pointer Person *p; int sellerNum; //create thread when adding person to the Seller que pthread_t personThreadId[NUM_SELLERS*N]; //create thread for putting people into concert hall pthread_t sellerThreadId[NUM_SELLERS]; pthread_t timerTID; pthread_create(&timerTID,NULL,&timer,NULL); for (sellerNum = 0; sellerNum < NUM_SELLERS; sellerNum++) { pthread_create(&sellerThreadId[sellerNum], NULL, &sellTickets, (void *) allSellers[sellerNum]); for(i = 0; i < N; i++) { p = createPerson(allSellers[sellerNum]); //p->arrival = 0; pthread_create(&personThreadId[sellerNum*N+i], NULL, &addPerson, (void *) p); } } closeDoorsIn60Minutes(); waitForSellersToFinish(allSellers,NUM_SELLERS); } else { printf("Usage:\n"); printf("threadSeller [T|number]\n"); printf(" T - run self test without any threading\n"); printf(" number - number of customers per ticket seller\n"); printf(" full threaded simulation\n"); } printf("Exiting threadSeller\n"); return 0; }
int main(int argc, char* argv[]) { struct Seatmap* map = (struct Seatmap*)malloc(sizeof(struct Seatmap)); // initialize the seatmap initialize_seatmap(map); map->mutex = &mutex; map->cond = &cond; // create the buyers time_t t; const int NUM_BUYERS = atoi(argv[1]); srand((unsigned) time(&t)); // set up the random number generator // create buyer queues. these are for the sellers. struct Buyer* buyers[NUM_SELLERS][NUM_BUYERS]; struct BuyerQueue* bqs[NUM_SELLERS]; struct Seller* sellers[NUM_SELLERS]; // probably should move this out of main, for clarity // also sorting the array on input would be nice. for(int i = 0; i < NUM_SELLERS;i++) { int ordinal; // number for sellers. char priority; // set the priority of the seller and buyer if(i == 0) { priority = 'H'; ordinal = 1; }else if(i < 4) { priority = 'M'; ordinal = i; }else{ priority = 'L'; ordinal = i -3; } char seller_name[4] = ""; seller_name[0] = priority; char cord[2]; sprintf(cord,"%d",ordinal); strcat(seller_name,cord); for(int j=0;j<NUM_BUYERS;j++) { int arrival_time = (int) rand() % 60; buyers[i][j] = createBuyer(priority, seller_name, j, arrival_time); } // here we create a BuyerQueue and put it in the list of BuyerQueues. // these will be handed to the seller as the seller is started. void* curr = buyers[i]; bqs[i] = init_BuyerQueue(curr, NUM_BUYERS); printBuyerQueue(bqs[i]); // creating seller struct sellers[i] = createSeller(priority, ordinal, bqs[i], map); }; print_seatmap(map); // start the sellers // pass in the seller struct. // hold the sellers from running until they are all created. pthread_t tids[NUM_SELLERS]; // spawn threads for(int i = 0; i < NUM_SELLERS; i++) { struct Seller* next = sellers[i]; pthread_t cur; pthread_create(&cur, NULL, sell, next); tids[i] = cur; } sleep(2); wakeup_all_seller_threads(); // wait for all seller threads to exit for (int i = 0 ; i < NUM_SELLERS ; i++) { pthread_t cur = tids[i]; pthread_join(cur, NULL); } // all threads are dead. printf report print_seatmap(map); for(int i = 0;i < NUM_SELLERS;i++) { // for each seller, print the customers who did not get tickets. struct Seller* s = sellers[i]; printf("Report for seller %s:\n", s->name); printf("Seller %s has %d customers who did not get tickets.\n",s->name, s->q->count); printf("Seller %s has %d customers who got tickets.\n",s->name, s->q->head); } printf("exiting\n"); fflush(stdout); // no more threads exit return(0); }
void mkTest() { printf(" Seller\n"); srand(0); Seller *s; s = createSeller(HIGH, 1); assert(checkT(s->price==HIGH,"Seller is HIGH")); assert(checkT(s->que==NULL,"Seller starts with empty que")); assert(checkN(s->lastRow,1,"HIGH seller starts in row 1")); free(s); s = createSeller(MEDIUM, 1); assert(checkN(s->lastRow,5,"MEDIUM seller starts in row 5")); free(s); s = createSeller(LOW, 1); assert(checkN(s->lastRow,10,"LOW seller starts in row 10")); printf(" Person\n"); Person *p = createPerson(s); assert(checkN(p->arrival,43,"p->arrival")); assert(checkT(s==p->seller,"checkT")); assert(checkT((p->next==p->prev) && (p->prev==p),"p is self referential")); // add person to seller // we need 4 people to test que management // for our testing set arrival to 0 and do not thread printf(" Add Person\n"); int i; for(i=0; i<4;i++) { p=createPerson(s); p->arrival = 0; addPerson(p); } assert(checkN(s->que->id,1,"First customer id")); assert(checkN(s->que->next->id,2,"Second customer id")); assert(checkN(s->que->next->next->id,3,"Third customer id")); assert(checkN(s->que->next->next->next->id,4,"Fourth/Last customer id")); assert(checkN(s->que->next->next->next->next->id,4,"Fifth customer id (tail points to self")); assert(checkT(s->que->inQ==TRUE,"First customer id")); assert(checkT(s->que->next->inQ==TRUE,"Second customer id")); assert(checkT(s->que->next->next->inQ==TRUE,"Third customer id")); assert(checkT(s->que->next->next->next->inQ==TRUE,"Fourth/Last customer id")); printf(" Remove Person\n"); // test removals p = removePerson(s->que);// remove person 1 assert(checkN(p->id,1,"First person on que removed")); assert(checkN(s->que->id,2,"First person on que now number 2")); p = removePerson(s->que->next); // remove person 3 assert(checkN(p->id,3,"Second(middle) person on que removed")); assert(checkN(s->que->id,2,"First person on que now number 2")); assert(checkN(s->que->next->id,4,"Second person should now be #4")); p = removePerson(s->que->next); // remove person 4 assert(checkN(p->id,4,"Second(tail) person on que removed")); assert(checkN(s->que->id,2,"First person on que now number 2")); assert(checkN(s->que->id,s->que->next->id,"Only one person left on que #2")); assert(checkT((p->next==p->prev) && (p->prev==p),"p(2) is self referential")); p = removePerson(s->que);// remove person 2 (single person left) assert(checkN(p->id,2,"Last person on que removed")); assert(checkT(s->que==NULL,"Seller que now empty")); p = removePerson(s->que);// remove person from empty que assert(checkT(p==NULL,"NULL pointer expected")); // printf(" getSeat()\n"); p=createPerson(s); // current low price seller p->id = 42; // check if row full algorithm even works assert(checkT(!isRowFull(&hall,8),"Is row 8 full NO")); printf(" LOW\n"); getSeat(&hall,p,LOW); // first call to low assigns 10,10 Person *cp = hall.seats[10][10]; assert(checkT(cp!=NULL,"Seat 10,10 occupied")); assert(checkN(cp->id,42,"Customer 42 has the seat")); printf(" HIGH\n"); p->seller->lastRow=1; getSeat(&hall,p,HIGH); // first call to low assigns 1,1 cp = hall.seats[1][1]; assert(checkT(cp!=NULL,"Seat 1,1 occupied")); assert(checkN(cp->id,42,"Customer 42 has the seat")); printf(" MEDIUM\n"); p->seller->lastRow=5; getSeat(&hall,p,MEDIUM); // first call to low assigns 5,10 cp = hall.seats[5][10]; assert(checkT(cp!=NULL,"Seat 5,10 occupied")); assert(checkN(cp->id,42,"Customer 42 has the seat")); p->seller->lastRow=3; getSeat(&hall,p,MEDIUM); // first call to low assigns 3,10 cp = hall.seats[3][10]; assert(checkT(cp!=NULL,"Seat 3,10 occupied")); assert(checkN(cp->id,42,"Customer 42 has the seat")); p->seller->lastRow=6; getSeat(&hall,p,MEDIUM); // first call to low assigns 6,1 cp = hall.seats[6][1]; assert(checkT(cp!=NULL,"Seat 6,1 occupied")); assert(checkN(cp->id,42,"Customer 42 has the seat")); // need non-threaded test for sellTickets method // non-threaded test for frustratedPerson() printf(" frustratedPerson()\n"); s = createSeller(HIGH,103); p=createPerson(s); p->arrival=0; addPerson(p); frustratedPerson(p); assert(checkT(s->que==NULL,"Person has left the building")); }