Diana St Louis / Mbed 2 deprecated lab9_4

Dependencies:   mbed-rtos mbed

Committer:
dstlouis
Date:
Thu Mar 20 08:43:48 2014 +0000
Revision:
0:d95c16be6bc4
lab9-4 deadlock condition example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dstlouis 0:d95c16be6bc4 1 #include "mbed.h"
dstlouis 0:d95c16be6bc4 2 #include "rtos.h"
dstlouis 0:d95c16be6bc4 3
dstlouis 0:d95c16be6bc4 4 //if you want to expose the deadlock, uncomment the DEADLOCK define
dstlouis 0:d95c16be6bc4 5 #define DEADLOCK
dstlouis 0:d95c16be6bc4 6
dstlouis 0:d95c16be6bc4 7 //if you want to fix the deadlock by having the mutex lock timeout, uncomment the DEADLOCK_FIX define
dstlouis 0:d95c16be6bc4 8 #define DEADLOCK_FIX
dstlouis 0:d95c16be6bc4 9
dstlouis 0:d95c16be6bc4 10 // I recommend running with the following order
dstlouis 0:d95c16be6bc4 11 // 1. do not define any macro to see normal execution
dstlouis 0:d95c16be6bc4 12 // 2. define DEADLOCK to see program hang
dstlouis 0:d95c16be6bc4 13 // 3. define DEADLOCK and DEADLOCK_FIX to see the hang fixed
dstlouis 0:d95c16be6bc4 14
dstlouis 0:d95c16be6bc4 15 typedef struct account{
dstlouis 0:d95c16be6bc4 16 double balance;
dstlouis 0:d95c16be6bc4 17 int id;
dstlouis 0:d95c16be6bc4 18 } Account;
dstlouis 0:d95c16be6bc4 19
dstlouis 0:d95c16be6bc4 20 // Globals
dstlouis 0:d95c16be6bc4 21 //two accounts
dstlouis 0:d95c16be6bc4 22 Account personA;
dstlouis 0:d95c16be6bc4 23 Account personB;
dstlouis 0:d95c16be6bc4 24 //pointers to those accounts
dstlouis 0:d95c16be6bc4 25 Account * personA_ptr;
dstlouis 0:d95c16be6bc4 26 Account * personB_ptr;
dstlouis 0:d95c16be6bc4 27 //mutexes for the two accounts
dstlouis 0:d95c16be6bc4 28 Mutex personA_mutex;
dstlouis 0:d95c16be6bc4 29 Mutex personB_mutex;
dstlouis 0:d95c16be6bc4 30
dstlouis 0:d95c16be6bc4 31 // function: withdraw
dstlouis 0:d95c16be6bc4 32 // inputs: Account pointer, double amount to withdraw
dstlouis 0:d95c16be6bc4 33 // description: subtracts input amount from the Account's balance
dstlouis 0:d95c16be6bc4 34 void withdraw (Account * person, double amount){
dstlouis 0:d95c16be6bc4 35 person->balance -= amount;
dstlouis 0:d95c16be6bc4 36 printf("Balance withdraw: %f from id %d\n", person->balance, person->id);
dstlouis 0:d95c16be6bc4 37 }
dstlouis 0:d95c16be6bc4 38
dstlouis 0:d95c16be6bc4 39 // function: deposit
dstlouis 0:d95c16be6bc4 40 // inputs: Account pointer, double amount to deposit
dstlouis 0:d95c16be6bc4 41 // description: adds input amount to the Account's balance
dstlouis 0:d95c16be6bc4 42 void deposit(Account * person, double amount){
dstlouis 0:d95c16be6bc4 43 person->balance += amount;
dstlouis 0:d95c16be6bc4 44 printf("Balance deposit: %f from id %d\n", person->balance, person->id);
dstlouis 0:d95c16be6bc4 45 }
dstlouis 0:d95c16be6bc4 46
dstlouis 0:d95c16be6bc4 47 // function: transfer
dstlouis 0:d95c16be6bc4 48 // inputs: From Account mutex, To Account mutex, From Account pointer, To Account pointer, double amount to transfer
dstlouis 0:d95c16be6bc4 49 // description: protects access to each account using correspoinding mutex
dstlouis 0:d95c16be6bc4 50 // withdraws amount from From Account and deposits amount to To Account
dstlouis 0:d95c16be6bc4 51 void transfer(Mutex f_m, Mutex t_m, Account * from, Account* to, double amount){
dstlouis 0:d95c16be6bc4 52 #ifdef DEADLOCK_FIX
dstlouis 0:d95c16be6bc4 53 f_m.lock(500);
dstlouis 0:d95c16be6bc4 54 #else
dstlouis 0:d95c16be6bc4 55 f_m.lock();
dstlouis 0:d95c16be6bc4 56 #endif
dstlouis 0:d95c16be6bc4 57
dstlouis 0:d95c16be6bc4 58 //putting a wait between grabing the locks allows the higher priority task to come in and grab the other lockk
dstlouis 0:d95c16be6bc4 59 #ifdef DEADLOCK
dstlouis 0:d95c16be6bc4 60 Thread::wait(5000);
dstlouis 0:d95c16be6bc4 61 #endif
dstlouis 0:d95c16be6bc4 62
dstlouis 0:d95c16be6bc4 63 #ifdef DEADLOCK_FIX
dstlouis 0:d95c16be6bc4 64 t_m.lock(500);
dstlouis 0:d95c16be6bc4 65 #else
dstlouis 0:d95c16be6bc4 66 t_m.lock();
dstlouis 0:d95c16be6bc4 67 #endif
dstlouis 0:d95c16be6bc4 68
dstlouis 0:d95c16be6bc4 69 withdraw(from, amount);
dstlouis 0:d95c16be6bc4 70 deposit(to, amount);
dstlouis 0:d95c16be6bc4 71 t_m.unlock();
dstlouis 0:d95c16be6bc4 72 f_m.unlock();
dstlouis 0:d95c16be6bc4 73 }
dstlouis 0:d95c16be6bc4 74
dstlouis 0:d95c16be6bc4 75 // thread: AtoB
dstlouis 0:d95c16be6bc4 76 // description: transfers 500 from A to B, prints balance after transfer
dstlouis 0:d95c16be6bc4 77 void AtoB(void const *args) {
dstlouis 0:d95c16be6bc4 78 transfer(personA_mutex, personB_mutex, personA_ptr, personB_ptr, 500);
dstlouis 0:d95c16be6bc4 79 printf("Balance A (AtoB): %f\n", personA_ptr->balance);
dstlouis 0:d95c16be6bc4 80 printf("Balance B (AtoB): %f\n", personB_ptr->balance);
dstlouis 0:d95c16be6bc4 81 }
dstlouis 0:d95c16be6bc4 82
dstlouis 0:d95c16be6bc4 83 // thread: BtoA
dstlouis 0:d95c16be6bc4 84 // description: transfers 200 from B to A, prints balance after transfer
dstlouis 0:d95c16be6bc4 85 void BtoA(void const *args) {
dstlouis 0:d95c16be6bc4 86 transfer(personB_mutex, personA_mutex, personB_ptr, personA_ptr, 200);
dstlouis 0:d95c16be6bc4 87 printf("Balance A (BtoA): %f\n", personA_ptr->balance);
dstlouis 0:d95c16be6bc4 88 printf("Balance B (BtoA): %f\n", personB_ptr->balance);
dstlouis 0:d95c16be6bc4 89 }
dstlouis 0:d95c16be6bc4 90
dstlouis 0:d95c16be6bc4 91 int main () {
dstlouis 0:d95c16be6bc4 92 printf("\n\nStart new transaction\n");
dstlouis 0:d95c16be6bc4 93
dstlouis 0:d95c16be6bc4 94 //populate values for Account personA, set pointer
dstlouis 0:d95c16be6bc4 95 personA_ptr = &personA;
dstlouis 0:d95c16be6bc4 96 personA_ptr->id = 1;
dstlouis 0:d95c16be6bc4 97 personA_ptr->balance = 1000;
dstlouis 0:d95c16be6bc4 98
dstlouis 0:d95c16be6bc4 99 //populate values for Account personB, set pointer
dstlouis 0:d95c16be6bc4 100 personB_ptr = &personB;
dstlouis 0:d95c16be6bc4 101 personB_ptr->id = 2;
dstlouis 0:d95c16be6bc4 102 personB_ptr->balance = 1000;
dstlouis 0:d95c16be6bc4 103
dstlouis 0:d95c16be6bc4 104 //start threads
dstlouis 0:d95c16be6bc4 105 Thread thread1(AtoB);
dstlouis 0:d95c16be6bc4 106 Thread thread2(BtoA);
dstlouis 0:d95c16be6bc4 107
dstlouis 0:d95c16be6bc4 108 thread1.set_priority(osPriorityNormal);
dstlouis 0:d95c16be6bc4 109 //second thread needs to have a higher priority than the first thread to crate the deadlock condition
dstlouis 0:d95c16be6bc4 110 thread2.set_priority(osPriorityHigh);
dstlouis 0:d95c16be6bc4 111
dstlouis 0:d95c16be6bc4 112 while (true){
dstlouis 0:d95c16be6bc4 113 }
dstlouis 0:d95c16be6bc4 114
dstlouis 0:d95c16be6bc4 115 }