6.270 Advanced C Lecture Notes
6.270 Advanced C Lecture Notes
6.270 Advanced C Lecture Notes
6.270Ad ancedCCo
I aacG ek n
eNo e
Mpig apn
Vle au
Ades drs .. . 4 3 2 1
a---
0
2
Table2.1:Memo la o fo imple a iable Whatifinadditionwecreateanewvariableoftypeuint16_t?Inthiscasethecompilerwill allocate16bitsofmemory(2bytes)tostorethevariable. Ifourcodelookslike un8ta=4 it_ ; un1_ b=1; it6t 7 Ourmemorymapwilllookliketable2.2.Noticethatbeoccupiestobytesinthememorytable. Thehigherorderbyteiszeroforourexamplevalueof17.Avalueof256forexamplewillhave theMSB(mostsignificantbit)equalto1,andtheLSB(lestsignificantbit)equalto1aswell.If youareconfusedbythis,consultWikipidia(http://en.wikipedia.org/wiki/Binary_numeral_syste Mpig apn Vle au Ades drs .. . 7 6 5 4 3 as b lo b---a--0 1 7 4 2 1 0
Table2.2:T o a iable
A a
Arraysletyoustoreacollectionofidenticalvariablesandletyouaccessthemwithasubscript (squarebracketsinc).Iwillstartoffwithanexample. #nld <oo. icue jysh itueu({ n stp) } vi pitie(it_ mns]{ od rnMnsun8t ie[) un8ti it_ ; fr( =0 i<6 i+ { o i ; ; +) pit(Mn #dhs% rsucs\"irsucsi) rnf"ie % a d eore n,,eore[]; } } it uanvi) n mi(od{ un8trsucs6 ={01,,,,} /Awyt "ntaie a ary it_ eore[] 1,05427; / a o iiilz" n ra pitie(eore) rnMnsrsucs; } OTU UPT Mn # hs1 rsucs ie 0 a 0 eore Mn # hs1 rsucs ie 1 a 0 eore Mn # hs5rsucs ie 2 a eore Mn # hs4rsucs ie 3 a eore Mn # hs2rsucs ie 4 a eore Mn # hs ie 5 a rsucs eore
CodeSample2.1
Mpig apn
Vle au
Ades drs .. . 7 6
7 2
5 4
4 5 1 0 1 0
3 2 1 0
Poin e Pointersaresimplyvariablesthatinsteadofstoringanumberorcharacter,theypointto anothervariable.Theiractualvalueistheaddressofanothervariableinmemory,orifyouare notcareful,somearbitrarylocationinmemorythatyouprobablyshouldn'taccess.Whywould oneeverwanttousepointersinthefirstplace?Howaboutanexample?Let ssayyouhavetwo variables,aandb,whicheachstoretheminenumberyouwanttogominenext.Nowlet ssay thatyoudiscoverthatoneoftheminesisdepleted,soyouwanttoswapaandb,soyouwill visitadifferentminefirst.Ifyouthinkaboutthisforawhile,youmightcomeupwithasolution likethis: #include<joyos.h> itueu({ n stp) } ituan) n mi({ un8tmn_ =4 it_ iea ; un8tmn_ =7 it_ ieb ; pit(Mn a %\" mn_) rnf"ie : dn, iea; pit(Mn b %\" mn_) rnf"ie : dn, ieb; /sapn pr /wpig at un8ttm =mn_; it_ ep ieb mn_ =mn_; ieb iea mn_ =tm; iea ep
pit(Mn b %\" mn_) rnf"ie : dn, ieb; } OTU: UPT Mn a 4 ie : Mn b ie : Sapd wpe: Mn a ie : Mn b 4 ie : Cd Sml .:BscSapn oe ape ai wpig
Thisworksfine,andswapsthevaluesofaandb.Whatifyouwanttoperformswapsinseveral partsofyourcode.Goodcodingpracticesaysyoushouldn'trepeatyourself,andthatyou shouldgroupyourcodeintofunctions.Let'sgoaheadanddothat.Let'sthrowtheswapping codeintoafunctionandcallitfromumain. #include<joyos.h> itueu({ n stp) } vi sa(n a itb{ od wpit , n ) /sapn pr /wpig at un8ttm =mn_; it_ ep ieb mn_ =mn_; ieb iea mn_ =tm; iea ep } ituan) n mi({ un8tmn_ =4 it_ iea ; un8tmn_ =7 it_ ieb ; pit(Mn a %\" mn_) rnf"ie : dn, iea; pit(Mn b %\" mn_) rnf"ie : dn, ieb;
sa(,) wpab;
pit(Sapd\"; rnf"wpe:n) pit(Mn a %\" mn_) rnf"ie : dn, iea; pit(Mn b %\" mn_) rnf"ie : dn, ieb; } OTU: UPT Mn a 4 ie : Mn b ie : Sapd wpe: Mn a 4 ie : Mn b ie : CodeSample2.3:Inco ec ap,ande ampleoflocal a iable .
Woah!Itdidn'twork?Whynot?Well,thiswouldbeagoodtimetointroducetheideaof passbyvalue.Whenafunctioniscalled,thearguments(inthiscasea,andb)areactually copiedintolocalcopiesassessableonlytothefunction(inthiscaseswap).Changingthemhas noaffecttothevariablesofcaller,orareathatcalledthefunction.Thisisbecausetheyscopeof thevariablesisdifferent.Inumain,amapstoaparticularaddress.Oncetheprogramisrunning swap,aisnowpointingtoadifferentlocationinmemory.Agoodwaytorememberthisisthat everynestedblockofcurlybrackethastheabilitytomakenewmappingstovariables.For example: #include<joyos.h> itueu({ n stp) } intumain(){ ita=4 n ; i() /awy tu f1{ /las re ita=7 n ; pit(A %\" a; rnf": dn, ) } pit(A %\"a; rnf": dn,)
8
Here'sasimpleexampleofusingpointers: #include<joyos.h> itueu({ n stp) } intumain(){ ita=4 n ; it*apr n _t; apr=&; _t a / pitrnmsaesfie wt _t b cneto / one ae r ufxd ih pr y ovnin /Pitapra a (e aprt te"drs o"a /on _t t . St _t o h ades f ) /pita /rn /st"h vleo wa"aprpitrpit /e te au f ht _t one ons /a t 7 /t o pit(a %\"a; rnf": dn,) }
9
/pitotaaan /rn u gi
OTU: UPT A 4 : A : CodeSample2.5 Whatisgoingonhere? Thefirstunfamiliarlineisthedeclarationofthepointera_ptr: it*apr n _t; / pitrnmsaesfie wt _t b cneto / one ae r ufxd ih pr y ovnin
Thislinecreatesanintpointer.Heretheasteriskistheonlydifferencefromcreatinganint variable. Thenextlineisalsounfamiliar: apr=&; _t a /Pitapra a (e aprt te"drs o"a /on _t t . St _t o h ades f )
Thislinecanbereadas"setthevalueofa_ptrtothe"addressof"thevariablea.Theampersand iseasiertounderstandifyoureaditoutloudas"theaddressof."Theampersandoperatoris sometimescalledthereferencingoperator,asitgetsareference,orpointertoaavariable. Thenextnewlineis: *_t =7 apr ; /st"h vleo wa"aprpitrpit /e te au f ht _t one ons
10
Mpig apn
Vle au
Ades drs .. . 7 6 5 4
3 2 apr _t a 0 1 0 1 0
Pointerscanbeusedasargumentstofunctions.Let'sgobackandtrytomaketheinfamous swapfunctionagain,thistimewithpointers. #include<joyos.h> itueu({ n stp) } vi sa(n *,it*) od wpit a n b{ /sapn pr /wpig at un8ttm =*ieb /ep=te"h vlepitdt b"mn_ it_ ep m n _ ;/ t m h te au one o y ieb *ieb=*iea mn_ mn_; *iea=tm; mn_ ep /"h vleo"mn_ ="h vleo"mn_ /te au f ieb te au f iea /"h vleo"mn_ =tm /te au f iea ep
11
} ituan) n mi({ un8tmn_ =4 it_ iea ; un8tmn_ =7 it_ ieb ; pit(Mn a %\" mn_) rnf"ie : dn, iea; pit(Mn b %\" mn_) rnf"ie : dn, ieb; sa(a&) wp&,b;
pit(Sapd\"; rnf"wpe:n) pit(Mn a %\" mn_) rnf"ie : dn, iea; pit(Mn b %\" mn_) rnf"ie : dn, ieb; } OTU: UPT Mn a 4 ie : Mn b ie : Sapd wpe: Mn a ie : Mn b 4 ie : CodeSample2.6:S cce f lS ap.U ingpoin e a a g men .
13
Poin erAri hme ic Ifyouhavebeenpayingalotofattentiontowhatisgoingon,youmightrealizethatsince pointersreallystoretheaddressesofothervariables,itisconceivabletomodifythevalueofa pointer,"byhand",tomakeitpointatanewaddress.Forexample,youcouldmakeitpointto address0xFFEEBB,whichisacriticaljoyosvariable.Youcanthenmodifyit,causeahorrible crash,andlosethecompetition.Oryoucandosomecleverthings. Let'ssayyoucreateanarrayofuint8_ts,andcreateapointertothefirstitem,likeso: un8tmns5 ={,,,,} it_ ie[] 12345; un8t*frtmn =&ie[] / pitrt tefrtmn it_ is_ie mns0; / one o h is ie Nowlet'sincrementthevalueoffirst_mine. frtmn +1 /iceetfrtmn is_ie =; /nrmn is_ie Keepinmindthatweareadjustingfist_mine'svalue,notthevalueofthevariableitpointsto (noticethelackofasterisks).Thishastheeffectofchangingwhatfirst_minepointsto.
Mpig apn
Vle au
Ades drs .. . 7 6
Mpig apn
Vle au
Ades drs .. . 7 6
frtmn 0 is_ie mns4 ie[] mns3 ie[] mns2 ie[] mns1 ie[] mns0 ie[] 5 4 3 2 1
5 4 3 2 1 0
frtmn 1 is_ie mns4 ie[] mns3 ie[] mns2 ie[] mns1 ie[] mns0 ie[] 5 4 3 2 1
5 4 3 2 1 0
14
Asyoucanseeabove,incrementingthepointermakesitpointtothenextvalueinthearray. Note:Ifthedatatypeofthepointeristwobytes,incrementingthepointerbyonemakeitpoint twobytesaheadinmemory,tothenextvalue.Forexample,ifourpointerwasauint16_t, incrementingitbyonewouldmakeitpointtwobytesaheadinmemory. #nld <oo. icue jysh vi pitie(it_ mns]{ od rnMnsun8t ie[) un8ti it_ ; fr( =0 i<5 i+ { o i ; ; +) pit(Mn #dhs% rsucs\"irsucsi) rnf"ie % a d eore n,,eore[]; } } itueu({ n stp) } ituan) n mi({ un8tmns5 ={,,,,} it_ ie[] 12345; pitie(ie) rnMnsmns; un8t*frtmn =&ie[] / pitrt tefrtmn it_ is_ie mns0; / one o h is ie frtmn +1 /iceetfrtmn is_ie =; /nrmn is_ie *first_mine=17 printf("\n") printMines(mine) } OTU UPT Mn # hs1rsucs ie 0 a eore Mn # hs2rsucs ie 2 a eore Mn # hs3rsucs ie 2 a eore Mn # hs4rsucs ie 3 a eore Mn # hs5rsucs ie 4 a eore Mn # hs1rsucs ie 0 a eore
15
//changevalueofthe2ndmineto17
Mn # hs1 rsucs ie 2 a eore Mn # hs3rsucs ie 2 a eore Mn # hs4rsucs ie 3 a eore Mn # hs5rsucs ie 4 a eore CodeSample2.8:Poin e A i hme ic F nc ionPoin e Pointerscanalsopointatfunctions.Thiscanbeusefulifyouwanttocreateafunctionthatwill callanotherfunctionatsomepoint.Thebestwaytoexplainthisiswithanexample,butfirst,the syntax: rtr_ye( nm)(rs euntp * ae ag) Sotomakeafunctionthathasoneargumentthatisafunctionreturningauint8_t,andtakingina uint8_tasanargument,youwoulddosoasfollows: vi fo un8t( br (it_)) od o( it_ * a) un8t { br5; a() } Ajoyosexample,fromJesseMoeller's2010lectureisaperfectexampleofagooduseof functionpointers. vi DUtlvi (Ato)) od oni(od *cin(, un8t(SoCniin(, it_ *tpodto)) un1_ edtm) it6t n_ie { wie(ie<edtm & !tpodto() hl tm n_ie & SoCniin){ Ato( cin) } } /clstefnto poie t fowt teagmn 4 /al h ucin rvdd o o ih h ruet
16
Thisfunctioncouldbecalledinavariateofwaystoperformusefulroboticactivities.For example: DUtl&owr,&iWl,50; oni(Frad Htal 0) DUtl&akad &iWl,50; oni(Bcwr, Htal 0) DUtl&owr,&eroo,50 oni(Frad NaRbt 0) Thesethreecallspassinthe"addressof"Forward,HitWall,Backwards,andNearRobot,which areallregularfunctions,allowingDoUntiltocallthem.
17
Structs,shortforstructuresareanadvanceddatatypeavailableinc.Theyenablegroup severalvariablestogetherintoasinglestructureforeaseofcodeclarity,aswellasgetting aroundtheproblemofasinglereturnvalue. Tocreateanewstructdatatype,youusethefollowingsyntax: src src_ae tut tutnm{ vrtp vr; a_ye a1 vrTp vr; a_ye a2 //t /ec } ; Forexample: src pit tut on{ dul x obe ; dul y obe ; } ; Tocreateavariableofyournewlycreatedtype,treats r c s r c _ a e asanyother tut tutnm variabletype.Forexample: src pitoii; tut on rgn Toaccessmembersofastruct,usethedotoperator.Forexample: oii. =0 rgnx ; oii. =0 rgny ; /ntc tesmcln I' iprat /oie h eioo. ts motn
18
Mpig apn
Vle au
Ades drs .. . 7 6 5
oii. rgny
4 3 2 0 1 0
c memo la o
#nld <oo. icue jysh #nld <ahh icue mt. src pit tut on{
1
Askanorganizeraboutthis.It'snotexactlytrue. 19
dul x obe ; dul y obe ; } ; tpdfsrc pitPit yee tut on on; dul dsacBtenonsPita Pitb{ obe itneewePit(on , on ) dul d =(. -bx *(. -bx + obe 2 ax .) ax .) (. -by *(. -by; ay .) ay .) rtr sr(2; eun qtd) } itueu({ n stp) } it uanvi) n mi(od{ Pitoii; on rgn oii. =0 rgnx ; oii. =0 rgny ; Pitmn; on ie mn. =30 iex 0; mn. =40 iey 0; dul dsac =dsacBtenonsoii,ie; obe itne itneewePit(rgnmn) pit(Dsac i %2"dsac) rnf"itne s .f,itne;
} OTU UPT Dsac i 500 itne s 0.2 /Etmtdase.Wl vr sihl dpnigo /siae nwr il ay lgty eedn n /sz o texycodntsi tesrc /ie f h , oriae n h tut
20
CodeSample2.9:U ing
c inf nc ion .
Ifyouexaminethecodeabove,onethingmightjumpoutatyou.Whatisthistypdefstatement? Typedefs,orTypeDefinitionlet'stheprogrammercreateasymbolicrepresentationofanew datatype.Withoutit,thedistanceBetweenPointsfunctionwouldneedthebeginlikethis: dul dsacBtenonssrc pita src pitb{ obe itneewePit(tut on , tut on ) /ec /t Byusingatypedef,weareassigningPointtothevalueof"structpoint",andfromthereon,using typingPointisthesameastypingstructpoint. Note:Thecapitalizationisastylisticchoiceanddoesnotmattertechnically,butconsistencyis important.
Simila i ie Be
eenA a
andPoin e
Arraysarereallyjustpointerstoblocksofmemorylargeenoughtostoreallthevalues.Read thatprevioussentenceagain.Whywouldthisbeso?ThemainreasonCwasdesignedthisway wastoimproveperformance.Ifwehaveanarrayof100itemsandneedtomovethatdata aroundallovertheplace,forexample,whencallingafunction,ourcodecangetprettyslow. Thissimilaritycanbeexplainedwithafewexamples. un8tdt[]={01} it_ aa2 1,0; Frombefore,theunderstandisthateachnamearray_name[index]pointstothecorresponding element.Thisistrue,butabitmisleading.Whatishappeninginternallyisthatthevariable,in thisexample,data,isreallyapointertothefirstiteminthearray.Accessingd t [ ] a a 1 ,is equivalenttolookingatthethepointertothefirstitem,jumpingforwardbyoneitem,andthen accessingthevalue.Infact,data[1]isinternallythesameasa*(data+1). Note:Acompilermightcomplainifyoudothis,asitisadangerouspathyouarewalkingon.It's importanttobeawareofwhatyouaredoing,anditisthecompiler'sjobtowarningyouwhenyou aredoingriskythings.
21
Mpig apn
Vle au
Ades drs .. . 7 6 5
1 0 1 0 vrfo a_o ll os dt aa 3
4 3 2 1 0
Table2.9:Realmemo la o Note:Ifthisisjustreallyhurtingyourbrain,don'tworryaboutittoomuch.It'snotvitalto successfulcode.Noticethatdatacontainsthevalue3,thatisitpointstomemorylocationthree, thestartofthearray.d t [ ] a a 1 accessesthedataatanoffsetof1fromthestartofthearray, sincethepointer/arraydatatypeisonebytewide,andweareaccessingindex1.Ifitwerean arrayofu i t 6 t accessingd t [ ] nn1_, a a 1 willaccessdataatanoffsetofdata_width*1,or2*1, sinceu n 1 _ variablestakeuptwobytesofstorage.Keepinmindthatthefirstlocationofan it6t arraymaybelocatedanywhereinmemory,eitherrightafterthepointer(data),orsomearbitray locationthatthecompilerfoundconvenient. #nld <oo. icue jysh itueu({ n stp) } vi pitie(it_ mns]{ od rnMnsun8t ie[) un8ti it_ ; fr( =0 i<2 i+ { o i ; ; +) pit(Mn #dhs% rsucs\"irsucsi) rnf"ie % a d eore n,,eore[];
22
} } it uanvi) n mi(od{ un8trsucs6 ={01,,,,} /Awyt "ntaie a ary it_ eore[] 1,05427; / a o iiilz" n ra pitie(rsucs0) rnMns&eore[]; pit(--\) rnf"--n; pitie(rsucs1) rnMns&eore[]; un8t*tidmn =&eore[] it_ hr_ie rsucs2; pit(--\) rnf"--n; pitie(hr_ie; rnMnstidmn) } OTU UPT Mn # hs1 rsucs ie 0 a 0 eore Mn # hs1 rsucs ie 1 a 0 eore --Mn # hs1 rsucs ie 0 a 0 eore Mn # hs5rsucs ie 1 a eore --Mn # hs5rsucs ie 0 a eore Mn # hs4rsucs ie 1 a eore
CodeSample2.10:A a
a e eall poin e ?
Poin e oS
#nld <ahh icue mt. #nld <oo. icue jysh src pit tut on{ dul x obe ; dul y obe ; } ; tpdfsrc pitPit yee tut on on; dul dsacBtenonsPit*,Pit*) obe itneewePit(on a on b{ dul d =(()x-*b.)*(()x-*b.)+/<-rs! obe 2 *a. ()x *a. ()x /-Gos (-y-a y *(-y-a y; b - ) b - ) rtr sr(2; eun qtd) } itueu({ n stp) } it uanvi) n mi(od{ Pitoii; on rgn oii. =0 rgnx ; oii. =0 rgny ; Pitmn; on ie mn. =30 iex 0; mn. =40 iey 0; dul dsac =dsacBtenons&rgn&ie; obe itne itneewePit(oii,mn) pit(Dsac i %2"dsac) rnf"itne s .f,itne; /<-ncr /- ie
} CodeSample2.10:Poin e o c
Almosteverythinginthiscodeshouldlookfamiliar,exceptforonestatementthatspanstwo lines:
24
dul d =(a. -(b.)*(a. -(b.)+/<-rs! obe 2 *)x *)x *)x *)x /-Gos (-y-a y *(-y-a y; b - ) b - ) /<-ncr /- ie
25
Threading
Inasentence,threadingletsyourunmultiplefunctionsatthesametime.Itisusefulif,for example,youwanttohaveonefunctionresponsiblefordrivingstraightanddoingthePIDloop, andanotherfordecidingwheretonavigateto,andyouwantthesefunctiontorunatthesame time. TheHapyboardcanreallyonlyrunonebitofcodeatthesametime,sothreadingisawayto havejoyoschopyourfunctionsintolittlebits,andrunafewbitsofone,thenswitchover,and runafewbitsofanotherfunction,andsoon.Thisisamazinglyuseful,andsometimesabit dangerous. Let'sputdangeraside,andlearnthebasicsofthreading.Threading,asmentionedearlier,lets youruntwofunctionsatthesametime.Eachconcurrentfunctioniscalledathread.Injoyos, youcreateathreadbycallingthecreate_threadfunction #nld <ahh icue mt. #nld <oo. icue jysh itnvgto_op) n aiainlo({ fr;) o(;{ pit(AaigNvgto gons\"; rnf"mzn aiain odesn) dly50; ea(0) yed) il(; } } itueu({ n stp) } it uanvi) n mi(od{ cet_hed&aiainlo,SAKDFUT 0 "i_hed) raetra(nvgto_op TC_EAL, , pdtra"; fr;) o(;{ pit(Uan!\"; rnf"mi!!n) dly50; ea(0) yed) il(; } } /wi 50m /at 0 s /tl jysti tra i dn frnw /el oo hs hed s oe o o
26
OTU:(eut myvr,a jysmyco u yu fntosdfeety UPT Rsls a ay s oo a hp p or ucin ifrnl) Uan! mi!! Uan! mi! AaigNvgto gons mzn aiain odes AaigNvgto gons mzn aiain odes Uan! mi!! ec.. t... CodeSample2.11:Ba icTh eading:
That'sprettymuchallthereistoit.Atthemoment,theonlypartyouwouldchangeasa contestantisthepointertothefunctionyouwanttorun,anditsname.Ifyouareconfusedabout theampersand,flipbackafewpages,andreviewpointersandfunctionpointers.Whatyouare doingistellingthec e t _ h e d functionyouwantittomakeathreadwithyourfunction,in raetra thiscasen v g t o _ o p a i a i n l o ,tellingittousethenormalamountofmemoryforthestack 2,giving itaname,andsettingitsprioritytozero. Sha ingda abe een h ead
Onceyouhavewrittenafewthreads,youprobablywanttoallowthemtocommunicate.The simplestwaytodothisiswhatiscalledsharedmemory.Itmightsoundabitscare,butit'seasy aspie.Allyouneedtodoiscreateavariableoutside,and"above"thefunctionsyouwantto sharedata.Thisvariableisnow"global"tothetwofunctions.Nowyoucanchangethisvaluein onefunction,andhavetheotherfunctionactonthischangedvalue.Hereisareallysimple example: #nld <ahh icue mt. #nld <oo. icue jysh usge ln cutr=0 nind og one ; itudtr) n pae({ fr;) o(;{ cutr=cutr+; one one 1 dly10) ea(00; } }
2
Askanorganizeraboutthestack.It'snotimportantthatyouunderstandit,butifyouareinterestedin computerarchitecture,it'sacoolthingtolearnabout. 27
itueu({ n stp) } it uanvi) n mi(od{ cet_hed&pae,SAKDFUT 0 "pae tra"; raetra(udtr TC_EAL, , udtr hed) fr;) o(;{ pit(Vle %dn,one) /pittevleo tecutr rnf"au: l\"cutr; /rn h au f h one dly50; ea(0) yed) il(; } } /wi 12ascn /at / eod
OTU:(eut myvr,a jysmyco u yu fntosdfeety UPT Rsls a ay s oo a hp p or ucin ifrnl) Vle 0 au: Vle 0 au: Vle 1 au: Vle 1 au: Vle 2 au: Vle 2 au: Vle 3 au: Vle 3 au: ..ec ..t
CodeSample2.12:Sha ingDa a Lock Locksareafeatureofjoyosthatmakesiteasierformultiplethreadstonotclobbershareddata. Themainproblemthatcanoccurwhenyousharedatawithoutlocks,isthatonethreadcan writesomedatatoalargevariable(anarrayofresourcequantitiesforexample),behalfway thoughwriting,whenitisinterruptedbyjoyos,whichdecideditwastimetorunanotherthread. Nowthearraycontainssomenewvalues,andsomeoldvalues,whichcanbeaproblem. Anotherexampleiswhentwothreadsshareapointstructthatcontainsanxandymember,as follows:
28
src pit tut on{ itx n ; ity n ; } ; Letssaythatonethread(navigation)isresponsibletopicktargetstodriveto,andanother thread(driving)isresponsibletocontrolthemotorstoactuallygetthere.Imaginethatvigation threadhasjustdecidetoupdatethetarget.Itscodemightlooksomewhatlikethis: .. . tre. =nwx agtx e_; tre. =nwy agty e_; Rightafteritupdatesthevalueofx,itmightbeinterruptedbyjoyos,leavingacompletely incorrectcoordinateinthetargetvariable.Thisproblemisknownasaracecondition. Note:Joyosdoesn'tnecesarychopcodeintobits,linebyline.Sometimesalinewillbebroken upintoseveralsmallerpieces,andtherefor,theexecutionofalinemightbeinterrupted.The smallest,indivisible,anduninterpretableoperationsarecalledatomic.3 Sohowcanwesolvethisproblem? Howaboutafarfetchmetaphor:FiveMITstudentsshareanapartmentwithonebathroomthat canNOTbephysicallylocked.Toavoidtheinevitableembarrassingsituationwhenonestudent walksinonanother,theyagreeonspecialprotocol.Theydecidetoleaveapadlockinaboxon thedoor,andtakeitwhenenteringthebathroom.Theyallagreethatwhenthepadlockhasbeen acquired,someoneisusing,andwillnotenter.Whentheoccupantleavesthebathroom,they releasecontrolofthepadlock,andplaceitbackinitsbox. Joyoshasafeaturethatbehavesalmostidentically.Interestinglyenough,thisfeaturesisknown aslocks.Tousethem,youfirstmustcreateandinitializethem.Afterthat,thefunctiona q i e cur takesthelock,andr l a e e e s releasesthelock.Whenalockisacquired,nootherthreadcan acquireit.Anattempttocalla q i e c u r whenitisalreadyacquiredwillblock,thatis,justsitthere untilthelockisreleasedbytheotherthread. Syntax: src lc lc_ae /cet telc ojc tut ok oknm; /rae h ok bet
Ifyouareinterestedinthis,askanorganizer. 29
ii_oksrc lc *k cntca *nm) /iiilz tesrc ntlc(tut ok , os hr ae; /ntaie h tut aqiesrc lc *k; cur(tut ok ) rlaesrc lc *k; ees(tut ok ) /aqietelc /cur h ok /rlaetelc /ees h ok
Forexample: src lc btro_ok tut ok ahomlc; /cet telc ojc /rae h ok bet
ii_ok&ahomlc,"ahomPdok) /iiilz tesrc ntlc(btro_ok Btro alc"; /ntaie h tut aqie&ahomlc) cur(btro_ok; rlae&ahomlc) ees(btro_ok; /aqietelc /cur h ok /rlaetelc /ees h ok
Thissolvestheproblem,butonlyifwearecarefulaboutusinglocks.Keepinmindthatlocksare notmagical.Theydon'tpreventreadingandwritingofvariables,butareaconvenientwayto readandwritevariablessafelyfrommultiplethreads.However,lockspresentsomenew challenges.Let'sswitchbackthethebuildingofMITstudents.Let'ssayonestudentpicksup thepadlock,walksintothebathroom,pullsoutaparachuteandjumpsoutthewindow,and forgetsthepadlockinthebathroom.Thebathroomisnolongeroccupied,andissafetoenter, butthelockismissing.Otherstudentswillnotenterthebathroom,thinkingit'soccupied.Even theparachuterwillnotenterthebathroom(heisalittlethickskulled,hedidjustjumpouta bathroomwindow),ashetothinksitisoccupied.Thisisatypeofdeadlock. InC,thiskindofdeadlockwilloccurifyouforgettoreleasealockbeforereturningfroma function,forexample. Thereisoneotherthingtowatchoutfor.Let'sreturnonceagaintothebuildingofcrazy students.Theyalsohaveonlyonetelephoneline,butmultiplephones.Excitedbythesuccess oftheirbathroomlocksystem,andterrifiedoflisteninginonother'sconversations,theydecide toimplementoneforthetelephoneaswell.Theyplaceasmallplasticphonemodelinabox,and callitthephonelock.Somestudentsliketotalkonthephonewillinthebathroom(yeah, weirdos),andforawhilethissystemworks.Unfortunately,onedayonestudentgoestohavea phone/shower,grabsthephonelock,andstartswalkingtowardsthebathroom.Anotherstudent hasasimilaridea,butgrabsthebathroomlock,andthenstartswalkingtopickupthephone lock.Theymeetinthehallway,andcometoastandoff,eachrefusingtogiveuphis/her respectivelock. Thisexampleseemsabitcontrived,butisaverycommonmistakewhendealingwithmultiple locks.Thequicktakeawayistoalwaysacquireandreleasemultiplelocksinthesameorder. Otherwisethethreadsmaybecomedeadlocked.
30
31