CS3502/project1/phase3/phase3.c
2025-10-09 22:18:56 -04:00

105 lines
2.5 KiB
C

#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define NUM_ACCOUNTS 5
#define NUM_TRANSFERS 5
// 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;
// Global account array
account accounts[NUM_ACCOUNTS];
// Threads
pthread_t transfers[NUM_TRANSFERS];
typedef struct transfer_args {
int transfer_id;
account *from;
account *to;
currency amount;
} transfer_args;
void *transfer_thread(void *arg) {
transfer_args *args = (transfer_args *)arg;
int id = args->transfer_id;
account *from = args->from;
account *to = args->to;
currency amount = args->amount;
pthread_mutex_lock(&from->lock);
printf("Thread %u: Locked account %d\n", id, from->account_id);
usleep(100); // Delay to account for other threads
pthread_mutex_lock(&to->lock);
printf("Thread %u: Locked account %d\n", id, to->account_id);
from->balance -= amount;
to->balance += amount;
from->transaction_count++;
to->transaction_count++;
printf("Thread %u: Unlocked account %u\n", id, from->account_id);
printf("Thread %u: Unlocked account %u\n", id, to->account_id);
pthread_mutex_unlock(&to->lock);
pthread_mutex_unlock(&from->lock);
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 transfers
transfer_args args[NUM_TRANSFERS];
for (int i = 0; i < NUM_TRANSFERS; i++) {
args[i] = (transfer_args){.transfer_id = i,
.from = &accounts[i % NUM_ACCOUNTS],
.to = &accounts[(i + 1) % NUM_ACCOUNTS],
.amount = 1000};
pthread_create(&transfers[i], NULL, transfer_thread, &args[i]);
}
// Wait for all threads to finish
for (int i = 0; i < NUM_TRANSFERS; i++) {
pthread_join(transfers[i], NULL);
}
return 0;
}