#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
typedef struct {
int balance;
pthread_mutex_t balance_mutex;
} bank_account;
typedef struct {
bank_account *from;
bank_account *to;
int amount;
} deposit_thr_args;
/* return negative on error */
int create_bank_account(bank_account **ba, int initial_amount) {
int ret;
bank_account *nba = malloc(sizeof(bank_account));
if (nba == NULL) {
return -1;
}
nba->balance = initial_amount;
ret = pthread_mutex_init(&nba->balance_mutex, NULL);
if (ret)
exit(ret);
*ba = nba;
return 0;
}
void *deposit(void *ptr) {
deposit_thr_args *args = (deposit_thr_args *)ptr;
pthread_mutex_lock(&(args->from->balance_mutex));
/* not enough balance to transfer */
if (args->from->balance < args->amount) {
pthread_mutex_unlock(&(args->from->balance_mutex));
return NULL;
}
pthread_mutex_lock(&(args->to->balance_mutex));
args->from->balance -= args->amount;
args->to->balance += args->amount;
pthread_mutex_unlock(&(args->from->balance_mutex));
pthread_mutex_unlock(&(args->to->balance_mutex));
return NULL;
}
int main() {
pthread_t thr1, thr2;
int err;
bank_account *ba1, *ba2;
err = create_bank_account(&ba1, 1000);
if (err < 0)
exit(err);
err = create_bank_account(&ba2, 1000);
if (err < 0)
exit(err);
deposit_thr_args *arg1 = malloc(sizeof(deposit_thr_args));
if (arg1 == NULL)
exit(-1);
deposit_thr_args *arg2 = malloc(sizeof(deposit_thr_args));
if (arg2 == NULL)
exit(-1);
arg1->from = ba1;
arg1->to = ba2;
arg1->amount = 100;
arg2->from = ba2;
arg2->to = ba1;
arg2->amount = 100;
/* perform the deposit */
err = pthread_create(&thr1, NULL, deposit, (void *)arg1);
if (err)
exit(err);
err = pthread_create(&thr2, NULL, deposit, (void *)arg2);
if (err)
exit(err);
pthread_exit(NULL);
return 0;
}
|