Den stora andledningen till upg3A:s nedfall är det faktum att de två trådarna försöker att ta de två mutexarna i
olika ordning (rad 17-18 tråd1, rad 28-29 tråd2). Detta medför en stor risk att varje tråd håller i 1
av låsen och försöker sedan ta det andra låset, dvs deadlock uppstår.
Man vill i regel att alla trådar försöker låsa mutexarna i samma ordning. 
Så i detta fallet så skulle detta innebära att man i upg3A försöker låsa mutexen "m1"
först i båda trådarna. Om denna lilla ändringen i vilken ordning de låser mutexarna i skulle ske så 
skulle upgA fungera väldigt mycket bättre.

Upg3b utför även den, denna farliga lås-ordningen. Men sättet man löst problemet på i detta program är att man
först låser det första låset (m1 för tråd 1, m2 för tråd 2) och sedan gör man en if sats som kollar om
låsningen av den andra tråden lyckas (trylock). Om låsningen lyckas så utför man den logik som skall
göras när en tråd har båda låsen (sätta thread till 1 eller 2) och sedan släpper man låsen.
Om trylock på det andra låset skulle misslyckas så släpper man den mutex man redan kontrollerar
och sedan försöker man igen.

En av vilkoren för att deadlock skall kunna uppstå är "No preemtion" detta betyder att en tråd som håller
en mutex inte kan tvingas släppa den. Det uppg3b gör är att den motverkar att deadlock uppstår
genom att frivilligt släppa sin egen mutex om den märker att den inte lyckas låsa båda.
Man kan se det som att trådarna har en inbyggd själv-preemtion. 

En bugg i den tentauppgiften vi fått är att om man kollar på rad 18 och 31 i uppg3b så står det
if(pthread_mutex_trylock(&mi) där i=1 eller 2. Så utför den logik som skall utföras om tråden
låst båda mutexarna. 
Om en mutex låses med pthread_mutex_trylock() så returnerar den 0, annars returnerar den en int
som indikerar fel eller misslyckad låsning. Detta innebär att if(pthread_mutex_trylock(&mi)
som finns med i tentauppgiften inte kommer att gå in i if satsen om den lyckas låsa det
andra låset den försöker ta. 
Utan detta kommer ske:
Tråden kommer att låsa sitt första lås, sedan låsa sitt andra lås, 
sedan låsa upp sitt första lås, sedan försöka ta sitt första lås igen, och när detta lyckas kommer den göra 
pthread_mutex_trylock() igen när tråden redan håller i det andra låset, detta kommer
då att misslyckas och därmed inte returna 0, vilket leder till att den går in i if satsen.

Denna bugg skulle åtgärdas genom att ändra if(pthread_mutex_trylock(mi)) till
if(!pthread_mutex_trylock(mi)) på raderna 18 och 31 i uppg3b.


Johan Wedin 199604277534
