Linux设备驱动第五章并发和竞争读书笔记Linux device drivers fifth chapters concurrency and compe.docx
《Linux设备驱动第五章并发和竞争读书笔记Linux device drivers fifth chapters concurrency and compe.docx》由会员分享,可在线阅读,更多相关《Linux设备驱动第五章并发和竞争读书笔记Linux device drivers fifth chapters concurrency and compe.docx(9页珍藏版)》请在冰豆网上搜索。
Linux设备驱动第五章并发和竞争读书笔记Linuxdevicedriversfifthchaptersconcurrencyandcompe
Linux设备驱动第五章(并发和竞争)读书笔记(Linuxdevicedrivers,fifthchapters(concurrencyandcompetition),readingnotes)
Thefifthchapterisconcurrencyandcompetition
Referencearticle:
Id=408682?
5.3flagsandmutex
1)flagisthecoreofasingleintegervalue.Combinedwithapairoffunctions,alsoknownasPVoperations".
OnewantstoenterthecriticalsectionofthePprocesswiththeflagraised,iftheflagvalueisgreaterthan0,thisvaluedecreased1,andtheprocesscontinues.Iftheflagissmallthanorequalto0,indicatingthattheflaghasbeenoccupiedbyotherprocesses,theprocessmustwaituntiltheflagisreleased.
Unlocktheflag,flagisreleased,tocompletetheoperationbycallingtheVVoperation,increasingthevalueoftheflag,andtheflagcanwakeupwaitingprocess.
2)mutexfunctionis:
mutualexclusion,topreventmultipleprocessessimultaneouslyinthesamecriticalarea.Themutexisinitializedto1flags.Becausethatisinitializedto1,whenthefirstprocessofP,1>0,sotheprocesscanrunatthesametime,theflagvalueis0,1decline,thesecondprocesstoobtaintheflagisusedtoaccessthecriticalsection,butfoundthattheflagvalueis0,sotheprocesscannotrununtilthe2releaseoftheflagprocess1.
5.3.1implementationoftheLINUXflag
1)tousetheflag,musttypecontains.isrelatedtothestructsemaphore;
2)theflag:
createaflag,thenusesema_inittosetit
Suchas:
Structsemaphore*sem;//defineflag
Sema_init(SEM,Val);//initializeValtoinitializethevalueofflagflag.
3)usually,flagisusedtomodelthemutex.Asaresult,thekernelprovidesaseriesofmacrostoinitialize.
DECLARE_MUTEX(name);//initializeamutex,avalueof1
DECLARE_MUTEX_LOCKED(name);//initializeamutex,avalueof0is:
flagafterinitializationisnotavailable.
Tousethisflaganyprocessmustfirstunlockitagain.
Whenweneedtoinitializeatruntime(thatis,dynamiccreation),weusethe:
Voidinit_MUTEX(structsemaphore*sem);//initializeamutex,avalueof1
Voidinit_MUTEX_LOCKED(structsemaphore*sem);initializesamutexwiththevalueof0
Forexample,wewanttocreateamutexthatisinitializedto0:
Structsemaphore*sem;//defineflag
ECLARE_MUTEX_LOCKED(SEM);//initializeflagvalueis0.
Theaboveistheinitializationflag,afterinitializationofcoursewemustusetheflag,orcreateitwhatisthesignificance?
4)flagacquisitionandrelease(canalsobeamutex,becausebasicallyallflagsareusedtoLINUXmutex)
GettheflagalsoknownasP,alsocalleddown.Downliterallymeans"drop".Theflagisminus1.
ThePfunctionisasfollows:
Voiddown(structsemaphore*sem);/*isnotrecommended,willestablishnotkillprocess*/
Intdown_interruptible(structsemaphore*sem);/*recommendedtheuseofdown_interruptibleneedtobecareful,iftheoperationisinterrupted,thefunctionreturnsanonzerovalue,anditwillnothavethecallsignal.Theproperuseofdown_interruptiblerequiresalwayscheckingthereturnvalueandrespondingaccordingly.*/
Intdown_trylock(structsemaphore*sem);/*with"_trylock"neversleeps,ifthesignalisnotavailableinthecall,willreturnanonzerovalue.*/
Weusuallyusethedown_interruptiblefunction.Recommendeddropsinthebook.
Oncetheflag,theflagoftheobtainingprocesscanaccessthecriticalareatoprotecttheflag.Whatdoyoudowhenyouuseit?
Ofcourseistocontrolthediscardedinthecriticalregion,isalsothereleaseflag.
ThereleaseflagalsoknownasV,alsocalledUPup,literallyrise.
Theflagis1.(downandupdescriptionoftheimageoftheflagoperation).
TheVfunctionisasfollows:
Voidup(struct,semaphore,*sem);
OncecalledUP,willnothavetheflagintheprocess.
5)useflagsareeasytomakemistakes
GettheprocesstoreleasetheflagflagusingthecalltoUP,butnotmanycallUP,thatis:
adownforaUP.
Intheholdflagwhenanerrorisencountered,wemustbeinthereturn(errorstate)istocallUPreleaseflag,otherwisethecriticalregionhasbeentheprocessofpossession,butperhapstheprocesshasbeenkill,andtheothertotheuseofcriticalareaswillbedueprocesshasnotbeensuspendedcriticalregion.
5.3.2.inscullusingtheflag
Thekeytothecorrectuseofthelockprimitiveistospecifyexactlywhatresourcestoprotectandconfirmthateachaccesstotheseresourcesusesthecorrectlockingmethod
Firstofall,lookatascullstructure:
Structscull_dev{
Structscull_qset*dataPointertofirstquantumset;/**/
Intquantumthecurrentquantumsize;/**/
Intqsetthecurrentarraysize;/**/
Unsignedlongsizeamountofdatastoredhere;/**/
Unsignedintaccess_keyusedbysculluidandscullpriv;/**/
StructsemaphoreSEMmutualexclusionsemaphore;/**/
StructCDEVCDEVChardevicestructure;/**/
};
StructsemaphoreSEMisourflag,andthisstructureistheobjectwewanttoprotectthe.
Flagmustbeinitializedbeforeuse.Scullthisinitializationatloadtime,inthiscycle:
For(I=0;IScull_devices[i].quantum=scull_quantum;
Scull_devices[i].qset=scull_qset;
Init_MUTEX(&scull_devices[i].sem);
Scull_setup_cdev(&scull_devices[i],I);
}
Wedefineascull_nr_devscharacterdriven,sowesetupascull_nr_devsflag,peopleask:
whynotsetaglobalflagonit?
Theansweristhateachcharacterdriverdoesnotshareresources.Forefficiency,thereisnoreasonforustouseoneoftheSCULLdevicesandotherprocessescannotuseothersculldevices.
Thislooptypicallyappearsinthe__initloadingfunctionthatdrivestheinitializationofvariablesandtheloadingofcharacterdevices.
Init_MUTEXiscalledinscull_setup_cdev.Intheoppositeorderofthisoperationmayproduceacompetitivesituation,theflagmaybeaccessedbeforeitisready.(note).
Whentheinitializationfinished,wewanttousethedriver,wemustconfirmthatthereisnoaccesstothedatastructureofscull_devintheabsenceofholdingflag.Inotherwords:
onlyintheholdwhentheflagcanaccessthedata.
Inthescull_writecode,wecansee:
If(down_interruptible(&dev->sem))
Return-ERESTARTSYS;
Notethatthereturnvalueoftheexaminationofthedown_interruptible;ifitreturnsnon-zero,theoperationwasinterrupted.Usuallydointhiscaseistoreturnto-ERESTARTSYS.toseethereturnvalue,thekernelorrestartthecallfromthetoporreturntheerrortotheuser.Ifyoureturn-ERESTARTSYS,youmustfirstrestoreanyuservisiblehasbeendonetochange,toensurethatwhentherightthingshappenagainwhenthesystemcall.Ifyoucannotrecoverinthisway,youshouldbebackfor-EINTR.
Whenwefinishedusingthecriticalarea,thewirtefunctionmustreleasetheflag,
Whetheritsucceedsorfailswhenweusethewritefunction,forexample,kmallocfailstoallocatememory,andcopy_form_uesrfailsfromuserspacecopydata.Remember:
besuretoreleasetheflag.
Code:
Out:
Up(&dev->sem);
Returnretval;
Whenyouencounteradifferenterror,usethegotostatementtojumptoout.
Also,youmustmakesurethatyoudonotaccessthescull_devstructurewhenyoudon'thavesemaphores.
5.3.3reader/writerflag
Flagforallcallerexclusive,butsometimeswecanthink:
whatistheflag?
Ingeneral,weusedintheaccesstothecriticalsection,becauseifthereisnoflag,canprocess1hasjustcompletedtherevisionofaprocessvariable,2andmodifiedthesamevariable,leadingtothelaterdataonthefrontofthedatatocover.Justliketheexamplesin5.1.scull.Butwhenwereadonly,weonlyallowoneprocesstoread,whichmakesitinefficient.Therefore,thereader/writerflag.
Thereader/writeflag:
wecanrealizetheconcurrentreadexclusivewrite,butonly.Improvedefficiency.Theread-onlytaskscanworkinparallelwithoutwaitingforotherreaderstoexitthecriticalarea
1)userwsemtoinclude.
2)initializearwsem.
Voidinit_rwsem(struct,rw_semaphore,*sem);
3)functionasfollows:
Theinterfacethatrequiresread-onlyaccesstothecodeis:
Voiddown_read(struct,rw_semaphore,*sem);
Intdown_read_trylock(struct,rw_semaphore,*sem);
Voidup_read(struct,rw_semaphore,*sem);
Providesread-onlyaccesstoprotectedresourcesofthedown_readcallcanaccessconcurrentlywithotherreaders.Notethatthedown_readmaybesettothecallingprocesscannotbeinterruptedsleep.Ifthedown_read_trylockisnotwaitingforthereadaccessisnotavailable;ifallowedtoaccessitreturnsnon-zero,otherwiseitis0.down_read_trylockconventiondifferentfrommostofthekernelfunction,areturnvalueof0indicatessuccess.Theuseofadown_readtoobtaintherwsemmusteventuallyuseup_readrelease.
Thereader'sinterfaceissimilar:
Voiddown_write(struct,rw_semaphore,*sem);
Intdown_write_trylock(struct,rw_semaphore,*sem);
Voidup_write(struct,rw_semaphore,*sem);
Voiddowngrade_write(struct,rw_semaphore,*sem);
Down_write,down_write_trylock,andup_writeallliketheirreaderscorrespondingpart,besides,ofcourse,theyprovidewriteaccess.Ifyouareinsuchasituation,theneedforawritelocktodoaquickchange,thenread-onlyaccessforalongtime,youcanusedowngrade_writeonceyouhavecompletedthechangeinallowotherreaderstoenter.
4)rwsemusesrelativelylittleindriving,butsometimestheyareuseful.Rwsemallowsmultiplereaderstoholdtheflag,andwriteapriority,whenawritertryingtogettheflag,itdoesnotallowreaderstoenteruntilthewritecompletesthework.Butitcanlead