//Lab 8 //Condition Variables and Scheduling #include #include #include pthread_mutex_t bank_mutex; //Add output statements to the code and record your output. Then modify the //code to remove the condition variable and record your output. Finally, add //the condition variable back to the code. pthread_cond_t zero_balance_cv; static double account_balance; //What happens when you increase the number of deposits and withdrawls //to 1000? static const int NUM_DEPOSITS = 100; static const int NUM_WITHDRAWLS = 100; //What happens when you increase the number of threads to 10 //for deposit and withdrawl threads? static const int NUM_DEPOSIT_THREADS = 1; static const int NUM_WITHDRAWL_THREADS = 1; //Deposit threads should always be able to add funds to the //account void * deposit(void * tid) { int i = 0; for(i = 0; i < NUM_DEPOSITS; i++) { pthread_mutex_lock(&bank_mutex); //Add between 100 and 200 dollars to the account. //What happens if you change this to 1 to 100 dollars? account_balance += rand()%101 + 100; //Signal the condition variable to indicate that the account has a positive //balance. if(account_balance > 0) pthread_cond_signal(&zero_balance_cv); pthread_mutex_unlock(&bank_mutex); } pthread_exit(NULL); } void * withdraw(void * tid) { int i = 0; for(i = 0; i < NUM_WITHDRAWLS; i++) { pthread_mutex_lock(&bank_mutex); //Withdraw between 1 and 100 dollars from the account. //Ensure that the account is never overdrawn int withdrawl_amount = rand()%100 + 1; while(withdrawl_amount > account_balance) { pthread_cond_wait(&zero_balance_cv, &bank_mutex); } //Withdraw funds from the bank. account_balance -= withdrawl_amount; pthread_mutex_unlock(&bank_mutex); } pthread_exit(NULL); } int main(int argc, char ** argv) { account_balance = 0.0; printf("The starting balance is $%.2lf\n", account_balance); pthread_attr_t attr; pthread_attr_init(&attr); //Initialize thread attributes. //What happens when you change the scheduling policy? Try //SCHED_FIFO and SCHED_OTHER. Read the man pages and online and //explain what these do. pthread_attr_setschedpolicy(&attr, SCHED_RR); //Set scheduling policy as //round robin. pthread_mutex_init(&bank_mutex, NULL); pthread_attr_init(&attr); pthread_t deposits[NUM_DEPOSIT_THREADS]; pthread_t withdrawls[NUM_WITHDRAWL_THREADS]; int i; for(i = 0; i < NUM_DEPOSIT_THREADS; i++) pthread_create(&deposits[i], &attr, deposit, (void *) i); for(i = 0; i < NUM_WITHDRAWL_THREADS; i++) pthread_create(&withdrawls[i], &attr, withdraw, (void *) i+NUM_DEPOSIT_THREADS); for(i = 0; i < NUM_DEPOSIT_THREADS; i++) pthread_join(deposits[i], NULL); for(i = 0; i < NUM_WITHDRAWL_THREADS; i++) pthread_join(withdrawls[i], NULL); printf("The remaining balance is $%.2lf\n", account_balance); pthread_mutex_destroy(&bank_mutex); pthread_cond_destroy(&zero_balance_cv); pthread_attr_destroy(&attr); return 0; }