Diana St Louis / Mbed 2 deprecated lab9_4

Dependencies:   mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 
00004 //if you want to expose the deadlock, uncomment the DEADLOCK define
00005 #define DEADLOCK 
00006 
00007 //if you want to fix the deadlock by having the mutex lock timeout, uncomment the DEADLOCK_FIX define
00008 #define DEADLOCK_FIX 
00009 
00010 // I recommend running with the following order
00011 // 1. do not define any macro to see normal execution
00012 // 2. define DEADLOCK to see program hang
00013 // 3. define DEADLOCK and DEADLOCK_FIX to see the hang fixed
00014 
00015 typedef struct account{
00016         double balance;
00017         int id;
00018 } Account;
00019 
00020 // Globals
00021 //two accounts
00022 Account personA;
00023 Account personB;
00024 //pointers to those accounts
00025 Account * personA_ptr;
00026 Account * personB_ptr;
00027 //mutexes for the two accounts
00028 Mutex personA_mutex;
00029 Mutex personB_mutex;
00030 
00031 // function: withdraw
00032 // inputs: Account pointer, double amount to withdraw
00033 // description: subtracts input amount from the Account's balance
00034 void withdraw (Account * person, double amount){
00035            person->balance -= amount;
00036            printf("Balance withdraw: %f from id %d\n", person->balance, person->id);
00037         }
00038 
00039 // function: deposit
00040 // inputs: Account pointer, double amount to deposit
00041 // description: adds input amount to the Account's balance    
00042 void deposit(Account * person, double amount){
00043            person->balance += amount;
00044            printf("Balance deposit: %f from id %d\n", person->balance, person->id);
00045         }
00046         
00047 // function: transfer
00048 // inputs: From Account mutex, To Account mutex, From Account pointer, To Account pointer, double amount to transfer
00049 // description: protects access to each account using correspoinding mutex
00050 //              withdraws amount from From Account and deposits amount to To Account
00051 void transfer(Mutex f_m, Mutex t_m, Account * from, Account* to, double amount){ 
00052 #ifdef DEADLOCK_FIX
00053     f_m.lock(500);
00054 #else
00055     f_m.lock();
00056 #endif
00057 
00058 //putting a wait between grabing the locks allows the higher priority task to come in and grab the other lockk
00059 #ifdef DEADLOCK 
00060     Thread::wait(5000);
00061 #endif 
00062 
00063 #ifdef DEADLOCK_FIX
00064     t_m.lock(500);
00065 #else
00066     t_m.lock();
00067 #endif
00068     
00069     withdraw(from, amount);
00070     deposit(to, amount);
00071     t_m.unlock();
00072     f_m.unlock();
00073 }
00074 
00075 // thread: AtoB
00076 // description: transfers 500 from A to B, prints balance after transfer
00077 void AtoB(void const *args) {
00078     transfer(personA_mutex, personB_mutex, personA_ptr, personB_ptr, 500);
00079     printf("Balance A (AtoB): %f\n", personA_ptr->balance);
00080     printf("Balance B (AtoB): %f\n", personB_ptr->balance);
00081 }
00082 
00083 // thread: BtoA
00084 // description: transfers 200 from B to A, prints balance after transfer
00085 void BtoA(void const *args) {
00086     transfer(personB_mutex, personA_mutex, personB_ptr, personA_ptr, 200);
00087     printf("Balance A (BtoA): %f\n", personA_ptr->balance);
00088     printf("Balance B (BtoA): %f\n", personB_ptr->balance);
00089 }
00090 
00091 int main () {
00092     printf("\n\nStart new transaction\n");
00093 
00094     //populate values for Account personA, set pointer
00095     personA_ptr = &personA;
00096     personA_ptr->id = 1;
00097     personA_ptr->balance = 1000;
00098     
00099     //populate values for Account personB, set pointer
00100     personB_ptr = &personB;
00101     personB_ptr->id = 2;
00102     personB_ptr->balance = 1000;
00103 
00104     //start threads
00105     Thread thread1(AtoB);
00106     Thread thread2(BtoA);   
00107     
00108     thread1.set_priority(osPriorityNormal);
00109     //second thread needs to have a higher priority than the first thread to crate the deadlock condition
00110     thread2.set_priority(osPriorityHigh);
00111     
00112     while (true){
00113     }
00114     
00115 }