-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbank.c
123 lines (100 loc) · 2.6 KB
/
bank.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include "error.h"
#include "bank.h"
#include "branch.h"
#include "account.h"
#include "report.h"
/*
* allocate the bank structure and initialize the branches.
*/
Bank*
Bank_Init(int numBranches, int numAccounts, AccountAmount initalAmount,
AccountAmount reportingAmount,
int numWorkers)
{
Bank *bank = malloc(sizeof(Bank));
if (bank == NULL) {
return bank;
}
sem_init(&(bank->checker), 0, 1);
sem_init(&(bank->transferer), 0, 1);
bank->count = numWorkers;
bank->numWorkers = numWorkers;
bank->sems = malloc(sizeof(sem_t) * bank->numWorkers);
for (int i=0; i<bank->numWorkers; i++){
sem_init(&(bank->sems[i]), 0, 0);
}
Branch_Init(bank, numBranches, numAccounts, initalAmount);
Report_Init(bank, reportingAmount, numWorkers);
return bank;
}
/*
* get the balance of the entire bank by adding up all the balances in
* each branch.
*/
int
Bank_Balance(Bank *bank, AccountAmount *balance)
{
assert(bank->branches);
AccountAmount bankTotal = 0;
for (unsigned int branch = 0; branch < bank->numberBranches; branch++) {
sem_wait(&((bank->branches[branch]).branchLocker));
AccountAmount branchBalance;
int err = Branch_Balance(bank,bank->branches[branch].branchID, &branchBalance);
if (err < 0) {
for (unsigned int i=0; i<branch; i++){
sem_post(&((bank->branches[i]).branchLocker));
}
return err;
}
bankTotal += branchBalance;
}
*balance = bankTotal;
for (unsigned int branch = 0; branch < bank->numberBranches; branch++){
sem_post(&((bank->branches[branch]).branchLocker));
}
return 0;
}
/*
* tranverse and validate each branch.
*/
int
Bank_Validate(Bank *bank)
{
assert(bank->branches);
int err = 0;
for (unsigned int branch = 0; branch < bank->numberBranches; branch++) {
int berr = Branch_Validate(bank,bank->branches[branch].branchID);
if (berr < 0) {
err = berr;
}
}
return err;
}
/*
* compare the data inside two banks and see they are exactly the same;
* it is called in BankTest.
*/
int
Bank_Compare(Bank *bank1, Bank *bank2)
{
int err = 0;
if (bank1->numberBranches != bank2->numberBranches) {
fprintf(stderr, "Bank num branches mismatch\n");
return -1;
}
for (unsigned int branch = 0; branch < bank1->numberBranches; branch++) {
int berr = Branch_Compare(&bank1->branches[branch],
&bank2->branches[branch]);
if (berr < 0) {
err = berr;
}
}
int cerr = Report_Compare(bank1, bank2);
if (cerr < 0)
err = cerr;
return err;
}