#include \"bank.h\" int numOfCustomers; // the number of customers of the bank i
ID: 3624637 • Letter: #
Question
#include "bank.h"
int numOfCustomers; // the number of customers of the bank
int numOfAccounts; // the number of accounts offered by the bank
int *available; // the amount available of each customer
int **maximum; // the maximum demand of each customer
int **allocation; // the amount currently allocated to each customer
int **need; // the remaining needs of each customer
pthread_mutex_t monitor = PTHREAD_MUTEX_INITIALIZER;
/*
Initialize the bank for a number of accounts and customers.
*/
void initBank(int avail[], int n, int m)
{
// numOfAccounts is the number of accounts offered by the bank
numOfCustomers = n;
numOfAccounts = m;
// initialize the accounts array
available = calloc(numOfAccounts, sizeof(int));
arraycpy(available, avail, numOfAccounts);
// create the array for storing the maximum demand by each customer
maximum = calloc(numOfCustomers, sizeof(int*));
allocation = calloc(numOfCustomers, sizeof(int*));
need = calloc(numOfCustomers, sizeof(int*));
}
/*
This function adds a customer to the bank system.
It records its maximum fund demand with the bank.
*/
void addBankCustomer(int customerNum, int maxDemand[])
{
maximum[customerNum] = calloc(numOfAccounts, sizeof(int));
arraycpy(maximum[customerNum], maxDemand, numOfAccounts);
allocation[customerNum] = calloc(numOfAccounts, sizeof(int));
// we start with zero allocated
need[customerNum] = calloc(numOfAccounts, sizeof(int*));
arraycpy(need[customerNum], maxDemand, numOfAccounts);
}
/*
Outputs the state of the bank; i.e., funds in each account of each customer
*/
void displayFunds(int array[])
{
printf("[");
for (int i = 0; i < numOfAccounts; i++)
printf("%3d ", array[i]);
printf("]");
}
void displayBankState()
{
printf(" %15s", "Available = ");
displayFunds(available);
printf(" %15s", "Allocation = ");
for (int i = 0; i < numOfCustomers; i++)
displayFunds(allocation[i]);
printf(" %15s", "Max = ");
for (int i = 0; i < numOfCustomers; i++)
displayFunds(maximum[i]);
printf(" %15s", "Need = ");
for (int i = 0; i < numOfCustomers; i++)
displayFunds(need[i]);
printf(" ");
}
/**
Determines whether granting a request results in leaving
the system in a safe state or not.
*/
BOOLEAN isSafeState (int customerNum, int request[])
{
return TRUE;
}
/*
Make a request for funds.
*/
BOOLEAN borrow(int customerNum, int request[])
{
BOOLEAN ret = TRUE;
if (pthread_mutex_lock(&monitor) != 0)
oops("Entering borrow", errno);
if (!isSafeState(customerNum,request)) {
//printfln("Customer # " + customerNum + " is denied.");
ret = FALSE;
}
else
// if it is safe, allocate the Funds to customer customerNum
for (int i = 0; i < numOfAccounts; i++)
{
available[i] -= request[i];
allocation[customerNum][i] += request[i];
need[customerNum][i] = maximum[customerNum][i] - allocation[customerNum][i];
}
if (pthread_mutex_unlock(&monitor) != 0)
oops("Exiting borrow", errno);
return ret;
}
/*
Deposit funds
*/
BOOLEAN payback(int customerNum, int release[])
{
if (pthread_mutex_lock(&monitor) != 0)
oops("Entering payment", errno);
BOOLEAN deny = FALSE;
for (int i = 0; (deny == FALSE) && (i < numOfAccounts); i++)
if (allocation[customerNum][i] < release[i])
deny = TRUE;
for (int i = 0; (deny == FALSE) && (i < numOfAccounts); i++)
{
available[i] += release[i];
allocation[customerNum][i] -= release[i];
need[customerNum][i] = maximum[customerNum][i] - allocation[customerNum][i];
}
// there may be some threads that can now proceed
if (pthread_mutex_unlock(&monitor) != 0)
oops("Exiting payment", errno);
return NOT(deny);
}
________________________________________________________________________________________
/**
* testSolvency.c
*
*/
#include "bank.h"
void readLine(FILE *, int[]);
void strToUpper(char **);
extern void displayFunds(int[]);
int numOfCustomers;
int numOfAccounts;
void simulateBank();
void initBankFromFile(char *);
int main(int argc, char *args[])
{
if (argc < 2)
{
printf("Usage: testSolvency <input file> ");
exit(-1);
}
// get the name of the input file
initBankFromFile(args[1]);
// run the simulation
simulateBank();
}
/*
In a loop, take input from the standard console until 'Q' or 'q' is entered.
Each input should have the following syntax:
{Q | ST | [GET | PAY] <customer number> {<account funds> ...}}
e.g. (for 3 accounts and with at least 2 customers):
ST
GET 1 3 2 1
PAY 1 1 0 1
Q
*/
void simulateBank()
{
// now loop reading requests to withdraw or deposit funds
int request[numOfAccounts];
char *inp = calloc(256, sizeof(int));
while (fgets(inp, 256, stdin) != 0)
{
if (strlen(inp) == 0)
continue;
// need a copy, since "line" will be used for tokenizing, so
// it will change until it gets NULL; we would not be able to re-use it
char *line = strdup(inp);
// get transaction type - withdraw (GET) or deposit (PAY) or ST (status)
line[strlen(line) - 1] = '';
char *trans = strsep(&line, " , ");
strToUpper(&trans); // so the case does not matter
printf(" REQUEST: %s", trans);
if (trans[0] == 'Q')
{
displayBankState();
exit(1);
}
else if (strcmp(trans, "ST") == 0)
displayBankState();
else
{
if ((strcmp(trans, "GET") != 0) && (strcmp(trans, "PAY") != 0))
{
printf(" Expected input: Q | ST | [GET | PAY] <customer number> <resource #1> <#2> <#3> ... ");
continue;
}
// get the customer number making the tranaction
int custNum = atoi(strsep(&line, " , "));
printf(" %d: ", custNum);
// get the resources involved in the transaction
for (int i = 0; i < numOfAccounts; i++)
request[i] = atoi(strsep(&line, " , "));
displayFunds(request);
// now check the transaction type
if (strcmp(trans, "GET") == 0)
{
if (borrow(custNum, request) == TRUE)
printf(" *APPROVED* ");
else
printf(" *DENIED* ");
}
else if (strcmp(trans, "PAY") == 0)
if (payback(custNum, request) == TRUE)
printf(" *APPROVED* ");
else
printf(" *DENIED* ");
}
}
}
/*
Read the state of the bank from a file.
The file format is as follows:
<num of customers> <num of accounts>
<initial state of accounts>
<max needs for each customer>
e.g.,
5 3
15 10 5
7,5,3
3,2,2
9,0,2
2,2,2
4,3,3
Any of ", " is a valid separator
*/
void initBankFromFile(char *inputFile)
{
FILE *file = fopen(inputFile, "r");
if (file == 0)
{
printf("Cannot open file %s for reading. ", inputFile);
exit(-1);
}
// now get the customers and accounts
int in[2];
readLine(file, in);
numOfCustomers = in[0];
numOfAccounts = in[1];
// the initial state of the accounts
int accountState[numOfAccounts];
readLine(file, accountState);
// create the bank
initBank(accountState, numOfCustomers, numOfAccounts);
int *maxDemand[numOfCustomers];
// read initial values for maximum array
int i;
for (i = 0; i < numOfCustomers; i++)
{
maxDemand[i] = calloc(numOfAccounts, sizeof(int));
readLine(file, maxDemand[i]);
addBankCustomer(i, maxDemand[i]);
}
}
/*
Read a line of values separated by a set of delimeters from a file into an array
*/
void readLine(FILE *file, int array[])
{
char *line = calloc(256, sizeof(int));
fgets(line, 256, file);
char *tok;
int i = 0;
while ((tok = strsep(&line, ", ")) != NULL)
if (strlen(tok) > 0)
array[i++] = atoi(tok);
}
/*
Transcode the string to upper case
*/
void strToUpper(char **s)
{
char *c;
for(c = *s; *c ; c++)
if (isascii(*c) && islower(*c))
*c = toupper(*c);
}
____________________________________________________________________________________
/*
* bank.h
*
*/
#ifndef _BANK_H_
#define _BANK_H_
#include <stdio.h>
#include <stdlib.h>
#define __USE_BSD
#include <string.h>
#include <errno.h>
#define __USE_SVID
#include <ctype.h>
#include <pthread.h>
//extern char *strdup (const char *s);
//extern char *strsep(char **stringp, const char *delim);
//extern int isascii(int c);
#define MAX_NUM_OF_CUSTOMERS 32
#define MAX_NUM_OF_ACCOUNT_TYPES 32
typedef int BOOLEAN;
#define TRUE 1
#define FALSE 0
#define NOT(x) (x == TRUE ? FALSE : TRUE)
#define oops(errmsg, errnum) { perror(errmsg); exit(errnum); }
#define arraycpy(a, b, n) {int i; for (i = 0; i < n; i++) a[i] = b[i];}
void initBank(int[], int, int);
void addBankCustomer(int, int[]);
void displayBankState();
BOOLEAN borrow(int, int[]);
BOOLEAN payback(int, int[]);
#endif