Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Sun Jul 24 2022 18:24:28 by
1.7.2