#include #include #include #include #include #include #include #define NUM_ACCOUNTS 8 #define NUM_TELLERS 128 #define TRANSACTIONS_PER_TELLER 1000 // Monetary value in cents typedef long currency; void sprintf_currency(char *buffer, currency c) { if (c < 0) { c = -c; sprintf(buffer, "-"); buffer += sizeof(char); } sprintf(buffer, "$%ld.%.2ld", c / 100, c % 100); } void printf_currency(currency c) { if (c < 0) { c = -c; printf("-"); } printf("$%ld.%.2ld", c / 100, c % 100); } // Accounts (shared resource) typedef struct account { int account_id; currency balance; int transaction_count; pthread_mutex_t lock; // Account access mutex } account; void deposit(account *acc, currency amount) { pthread_mutex_lock(&acc->lock); // CRITICAL SECTION BEGIN acc->balance += amount; acc->transaction_count++; // CRITICAL SECTION END pthread_mutex_unlock(&acc->lock); } // Global account array account accounts[NUM_ACCOUNTS]; // Teller threads pthread_t tellers[NUM_TELLERS]; typedef struct teller_args { int teller_id; currency total; } teller_args; void *teller_thread(void *arg) { teller_args *args = (teller_args *)arg; int id = args->teller_id; currency total = 0; unsigned int seed = time(NULL) + pthread_self(); for (int i = 0; i < TRANSACTIONS_PER_TELLER; i++) { // Deposit or withdraw random currency amount from $0 to $1000 currency random_amount = ((long)rand_r(&seed)) % 100000; char *operation; currency random_amount_i = random_amount; if (rand_r(&seed) % 2) { random_amount_i = -random_amount; operation = "Withdrawing"; } else { operation = "Depositing"; } int random_acc = rand_r(&seed) % NUM_ACCOUNTS; deposit(&accounts[random_acc], random_amount_i); // Display result of transaction char buffer[8]; sprintf_currency(buffer, random_amount); printf("Thread %u: %s %s into account %u\n", id, operation, buffer, random_acc); total += random_amount_i; } args->total = total; return NULL; } int main() { // Initialize all accounts with 0 balance for (int i = 0; i < NUM_ACCOUNTS; i++) { accounts[i] = (account){.account_id = i, .balance = 0}; pthread_mutex_init(&accounts[i].lock, NULL); } // Initialize tellers teller_args args[NUM_TELLERS]; for (int i = 0; i < NUM_TELLERS; i++) { args[i] = (teller_args){.teller_id = i}; pthread_create(&tellers[i], NULL, teller_thread, &args[i]); } // Wait for all threads to finish currency expected_total = 0; for (int i = 0; i < NUM_TELLERS; i++) { pthread_join(tellers[i], NULL); expected_total += args[i].total; } currency actual_total = 0; for (int i = 0; i < NUM_ACCOUNTS; i++) { actual_total += accounts[i].balance; } printf("Total balance: "); printf_currency(actual_total); printf("\nExpected total: "); printf_currency(expected_total); printf("\n"); return 0; }