/* * Perform the nightly report. Is called by every worker for each report period. workerNum is * the worker making the call. Returns -1 on error, 0 otherwise. */ int Report_DoReport(Bank *bank, int workerNum) { Report *rpt = bank->report; assert(rpt); Y; // Acquire the report's lock to look at how many calls to DoReport have been made pthread_mutex_lock(&lock); rpt->reportCalls = rpt->reportCalls + 1; // Wait for all of the workers to call _DoReport while((rpt->reportCalls % numWorkers) != 0) { pthread_cond_wait(&cond,&lock); /* * Only the last worker will "do the report" * Rest will wait till the last worker calls doReport and then exit rightaway */ // Release the lock pthread_mutex_unlock(&lock); return 0; } // The last worker needs to tabulate all of transfer logs done by the // individual workers into the bank's report joinReports(rpt); if (rpt->numReports >= MAX_NUM_REPORTS) { pthread_mutex_unlock(&lock); // We've run out of report storage for the bank return -1; } /* * Store the overall bank balance for the report. */ int err = Bank_Balance(bank, &rpt->dailyData[rpt->numReports].balance); Y; int oldNumReports = rpt->numReports; Y; rpt->numReports = oldNumReports + 1; Y; // Wake up all of the workers pthread_cond_broadcast(&cond); // Release the lock pthread_mutex_unlock(&lock); return err; }
/* * Perform the nightly report. Is called by every worker for each report period. workerNum is * the worker making the call. Returns -1 on error, 0 otherwise. */ int Report_DoReport(Bank *bank, int workerNum) { Report *rpt = bank->report; assert(rpt); Y; if (rpt->numReports >= MAX_NUM_REPORTS) { // We've run out of report storage for the bank return -1; } /* * Store the overall bank balance for the report. */ int err = Bank_Balance(bank, &rpt->dailyData[rpt->numReports].balance); Y; int oldNumReports = rpt->numReports; Y; rpt->numReports = oldNumReports + 1; Y; return err; }