安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

linux内核的链循环双链表简单使用

3月15日 终离去投稿
  linux内核的循环双链表是非常经典的代码实现方式,个人总结如下:API多,像nginx(二者原理一致)、redis的链表在api数目上还差一点扩展性强,比如可以实现一个LRU、和线程池结合使用都可以,而redis的链表还差了点
  demo代码如下:includestdio。hincludestdlib。hincludeincludelist。hdefineMAXELENUMS(5)structStu{unsignedintulId;structlistheadstN};structStuList{structlistheadstLi;};打印单个Node信息staticDLPrintNode(charpcPrefix,structStupstStu){assert((NULL!pcPrefix)(NULL!pstStu));printf(s,id:u,addr:p,node:p,pcPrefix,pstStuulId,pstStu,(pstStustNode));}释放链表的所有数据voidDLClearStuLi(structlistheadpstHead){assert(NULL!pstHead);structStupstStuNULL;structStupstNextStuNULL;listforeachentrysafe(pstStu,pstNextStu,pstHead,stNode){listdel((pstStustNode));DLPrintNode(free,pstStu);free((void)pstStu);}}打印链表数据voidDLPrintStuLi(structlistheadpstHead,intlReverse){assert(NULL!pstHead);structStupstStuNULL;structStupstNextStuNULL;if(lReverse){listforeachentrysafereverse(pstStu,pstNextStu,pstHead,stNode){DLPrintNode(showbackward,pstStu);}}else{listforeachentrysafe(pstStu,pstNextStu,pstHead,stNode){DLPrintNode(showforward,pstStu);}}}批量添加至链表中voidDLBatchAddStuLiNodes(structlistheadpstHead,structStuppstStus,unsignedintulNodeNum,intlAddTail){assert((NULL!pstHead)(NULL!ppstStus));structStupstStuNULL;if(lAddTail){for(unsignedinti0;iulNodeNi){pstStuppstStus〔i〕;listaddtail((pstStustNode),pstHead);}}else{for(unsignedinti0;iulNodeNi){pstStuppstStus〔i〕;listadd((pstStustNode),pstHead);}}}voidDLBatchCreateNodes(structStuppstStus,unsignedintulNodeNum,unsignedintulStartId){assert(NULL!ppstStus);for(unsignedinti0;iulNodeNi){ppstStus〔i〕(structStu)malloc(sizeof(structStu));assert(NULL!ppstStus〔i〕);ppstStus〔i〕ulIdulStartId;DLPrintNode(create,ppstStus〔i〕);ulStartId;}}从给定的元素开始遍历,包括给定的元素voidDLIterateIncludeGivenEntry(structlistheadpstHead,structStupstStu,intlReverse){assert((NULL!pstHead)(NULL!pstStu));structStupstNextStuNULL;if(lReverse){listforeachentryfromreverse(pstStu,pstHead,stNode){DLPrintNode(showbackward,pstStu);}}else{listforeachentrysafefrom(pstStu,pstNextStu,pstHead,stNode){DLPrintNode(showforward,pstStu);}}}从给定的元素开始遍历,voidDLIterateExcludeGivenEntry(structlistheadpstHead,structStupstStu,intlReverse){assert((NULL!pstHead)(NULL!pstStu));structStupstNextStuNULL;if(lReverse){listforeachentrycontinuereverse(pstStu,pstHead,stNode){DLPrintNode(showbackward,pstStu);}}else{listforeachentrysafecontinue(pstStu,pstNextStu,pstHead,stNode){DLPrintNode(showforward,pstStu);}}}voidDLCreateNoEmptyList(structlistheadpstHead,unsignedintulNodeNum){assert((NULL!pstHead)(0!ulNodeNum));structStuppstStusNULL;ppstStus(structStu)malloc(sizeof(structStu)ulNodeNum);assert(NULL!ppstStus);INITLISTHEAD(pstHead);DLBatchCreateNodes(ppstStus,ulNodeNum,0);DLBatchAddStuLiNodes(pstHead,ppstStus,ulNodeNum,1);free((void)ppstStus);}voidDLIterateGivenPoint(){分配空间structStuapstStus〔MAXELENUMS〕{0};DLBatchCreateNodes(apstStus,MAXELENUMS,0);初始化链表structStuListstList{0};INITLISTHEAD((stList。stLi));链表尾部添加DLBatchAddStuLiNodes((stList。stLi),apstStus,MAXELENUMS,1);DLIterateIncludeGivenEntry((stList。stLi),apstStus〔2〕,1);DLIterateExcludeGivenEntry((stList。stLi),apstStus〔2〕,1);释放链表所有数据DLClearStuLi((stList。stLi));}简单使用voidDLBasic(){分配空间structStuapstStus〔MAXELENUMS〕{0};DLBatchCreateNodes(apstStus,MAXELENUMS,0);初始化链表structStuListstList{0};INITLISTHEAD((stList。stLi));无数据,为空printf(init,listemtpy:s,listempty((stList。stLi))?yes:no);链表尾部添加DLBatchAddStuLiNodes((stList。stLi),apstStus,MAXELENUMS,1);有数据不为空printf(AfterAdd,listemtpy:s,listempty((stList。stLi))?yes:no);structStupstStuNULL;structlistheadpstNodeNULL;structlistheadpstNextNodeNULL;打印所有的链表数据DLPrintStuLi((stList。stLi),0);释放链表所有数据DLClearStuLi((stList。stLi));}voidshowBasicListInfo(){structStuapstStus〔MAXELENUMS〕{0};DLBatchCreateNodes(apstStus,MAXELENUMS,0);initliststructStuListstList{0};INITLISTHEAD((stList。stLi));nodata,isemptyprintf(init,listemtpy:s,listempty((stList。stLi))?yes:no);addnodetolisttailfor(unsignedinti0;iMAXELENUMS;i){listaddtail((apstStus〔i〕stNode),(stList。stLi));printf(listempty:s,listsingular:s,listfirst:s,listlast:s,entryishead:s,listempty((stList。stLi))?yes:no,listissingular((stList。stLi))?yes:no,listisfirst((apstStus〔i〕stNode),(stList。stLi))?yes:no,listislast((apstStus〔i〕stNode),(stList。stLi))?yes:no,listentryishead(apstStus〔i〕,(stList。stLi),stNode)?yes:no);}printf(listfirst:ulistlast:u,listfirstentryornull((stList。stLi),structStu,stNode)ulId,listlastentry((stList。stLi),structStu,stNode)ulId);DLPrintStuLi((stList。stLi),0);DLClearStuLi((stList。stLi));}structInvalidStruct{intulIunsignedlonglongdulDoubleIcharszName〔20〕;floatfDataF};intmain(){showBasicListInfo();return0;}
  为此,提取的代码如下,可直接复制粘贴供以后使用,由于代码中使用了new作为变量名,在C中会报错,可以自行将new替换掉其他变量名即可。SPDXLicenseIdentifier:GPL2。0ifndefR2MLISTHdefineR2MLISTHincludestdbool。hifndefoffsetofdefineoffsetof(TYPE,MEMBER)((sizet)((TYPE)0)MEMBER)endifcontainerofcastamemberofastructureouttothecontainingstructureptr:thepointertothemember。type:thetypeofthecontainerstructthisisembeddedin。member:thenameofthememberwithinthestruct。ifndefcontainerofdefinecontainerof(ptr,type,member)({voidmptr(void)(ptr);((type)(mptroffsetof(type,member)));})endifdefinePOISONPOINTERDELTA0ThesearenonNULLpointersthatwillresultinpagefaultsundernormalcircumstances,usedtoverifythatnobodyusesnoninitializedlistentries。defineLISTPOISON1((void)0x100POISONPOINTERDELTA)defineLISTPOISON2((void)0x122POISONPOINTERDELTA)Circulardoublylinkedlistimplementation。Someoftheinternalfunctions(xxx)areusefulwhenmanipulatingwholelistsratherthansingleentries,assometimeswealreadyknowthenextpreventriesandwecangeneratebettercodebyusingthemdirectlyratherthanusingthegenericsingleentryroutines。structlisthead{structlistheadnext,};defineLISTHEADINIT(name){(name),(name)}defineLISTHEAD(name)structlistheadnameLISTHEADINIT(name)INITLISTHEADInitializealistheadstructurelist:listheadstructuretobeinitialized。Initializesthelistheadtopointtoitself。Ifitisalistheader,theresultisanemptylist。staticinlinevoidINITLISTHEAD(structlistheadlist){}ifdefCONFIGDEBUGLISTexternboollistaddvalid(structlistheadnew,structlistheadprev,structlistheadnext);externboollistdelentryvalid(structlistheadentry);elsestaticinlineboollistaddvalid(structlistheadnew,structlistheadprev,structlistheadnext){}staticinlineboollistdelentryvalid(structlistheadentry){}endifInsertanewentrybetweentwoknownconsecutiveentries。Thisisonlyforinternallistmanipulationwhereweknowtheprevnextentriesalready!staticinlinevoidlistadd(structlistheadnew,structlistheadprev,structlistheadnext){if(!listaddvalid(new,prev,next))}listaddaddanewentrynew:newentrytobeaddedhead:listheadtoadditafterInsertanewentryafterthespecifiedhead。Thisisgoodforimplementingstacks。staticinlinevoidlistadd(structlistheadnew,structlistheadhead){listadd(new,head,headnext);}listaddtailaddanewentrynew:newentrytobeaddedhead:listheadtoadditbeforeInsertanewentrybeforethespecifiedhead。Thisisusefulforimplementingqueues。staticinlinevoidlistaddtail(structlistheadnew,structlistheadhead){listadd(new,headprev,head);}Deletealistentrybymakingtheprevnextentriespointtoeachother。Thisisonlyforinternallistmanipulationwhereweknowtheprevnextentriesalready!staticinlinevoidlistdel(structlistheadprev,structlistheadnext){}Deletealistentryandcleartheprevpointer。Thisisaspecialpurposelistclearingmethodusedinthenetworkingcodeforlistsallocatedaspercpu,wherewedontwanttoincurtheextraWRITEONCE()overheadofaregularlistdelinit()。Thecodethatusesthisneedstocheckthenodeprevpointerinsteadofcallinglistempty()。staticinlinevoidlistdelclearprev(structlistheadentry){listdel(entryprev,entrynext);entryprevNULL;}staticinlinevoidlistdelentry(structlistheadentry){if(!listdelentryvalid(entry))listdel(entryprev,entrynext);}listdeldeletesentryfromlist。entry:theelementtodeletefromthelist。Note:listempty()onentrydoesnotreturntrueafterthis,theentryisinanundefinedstate。staticinlinevoidlistdel(structlistheadentry){listdelentry(entry);entrynextLISTPOISON1;entryprevLISTPOISON2;}listreplacereplaceoldentrybynewoneold:theelementtobereplacednew:thenewelementtoinsertIfoldwasempty,itwillbeoverwritten。staticinlinevoidlistreplace(structlistheadold,structlistheadnew){}listreplaceinitreplaceoldentrybynewoneandinitializetheoldoneold:theelementtobereplacednew:thenewelementtoinsertIfoldwasempty,itwillbeoverwritten。staticinlinevoidlistreplaceinit(structlistheadold,structlistheadnew){listreplace(old,new);INITLISTHEAD(old);}listswapreplaceentry1withentry2andreaddentry1atentry2spositionentry1:thelocationtoplaceentry2entry2:thelocationtoplaceentry1staticinlinevoidlistswap(structlistheadentry1,structlistheadentry2){structlistheadposentry2listdel(entry2);listreplace(entry1,entry2);if(posentry1)posentry2;listadd(entry1,pos);}listdelinitdeletesentryfromlistandreinitializeit。entry:theelementtodeletefromthelist。staticinlinevoidlistdelinit(structlistheadentry){listdelentry(entry);INITLISTHEAD(entry);}listmovedeletefromonelistandaddasanothersheadlist:theentrytomovehead:theheadthatwillprecedeourentrystaticinlinevoidlistmove(structlistheadlist,structlistheadhead){listdelentry(list);listadd(list,head);}listmovetaildeletefromonelistandaddasanotherstaillist:theentrytomovehead:theheadthatwillfollowourentrystaticinlinevoidlistmovetail(structlistheadlist,structlistheadhead){listdelentry(list);listaddtail(list,head);}listbulkmovetailmoveasubsectionofalisttoitstailhead:theheadthatwillfollowourentryfirst:firstentrytomovelast:lastentrytomove,canbethesameasfirstMoveallentriesbetweenfirstandincludinglastbeforehead。Allthreeentriesmustbelongtothesamelinkedlist。staticinlinevoidlistbulkmovetail(structlistheadhead,structlistheadfirst,structlistheadlast){}listisfirsttestswhetherlististhefirstentryinlistheadlist:theentrytotesthead:theheadoftheliststaticinlineintlistisfirst(conststructlistheadlist,conststructlistheadhead){}listislasttestswhetherlististhelastentryinlistheadlist:theentrytotesthead:theheadoftheliststaticinlineintlistislast(conststructlistheadlist,conststructlistheadhead){}listemptytestswhetheralistisemptyhead:thelisttotest。staticinlineintlistempty(conststructlistheadhead){}listdelinitcarefuldeletesentryfromlistandreinitializeit。entry:theelementtodeletefromthelist。Thisisthesameaslistdelinit(),exceptdesignedtobeusedtogetherwithlistemptycareful()inawaytoguaranteeorderingofothermemoryoperations。Anymemoryoperationsdonebeforealistdelinitcareful()areguaranteedtobevisibleafteralistemptycareful()test。staticinlinevoidlistdelinitcareful(structlistheadentry){unsupportedif0listdelentry(entry);smpstorerelease(entrynext,entry);endif}listemptycarefultestswhetheralistisemptyandnotbeingmodifiedhead:thelisttotestDescription:testswhetheralistisemptyandchecksthatnootherCPUmightbeintheprocessofmodifyingeithermember(nextorprev)NOTE:usinglistemptycareful()withoutsynchronizationcanonlybesafeiftheonlyactivitythatcanhappentothelistentryislistdelinit()。Eg。itcannotbeusedifanotherCPUcouldrelistadd()it。staticinlineintlistemptycareful(conststructlistheadhead){unsupportedif0structlistheadnextsmploadacquire(headnext);return(nexthead)(nextheadprev);endifreturn0;}listrotateleftrotatethelisttothelefthead:theheadoftheliststaticinlinevoidlistrotateleft(structlistheadhead){if(!listempty(head)){listmovetail(first,head);}}listrotatetofront()Rotatelisttospecificitem。list:Thedesirednewfrontofthelist。head:Theheadofthelist。Rotateslistsothatlistbecomesthenewfrontofthelist。staticinlinevoidlistrotatetofront(structlistheadlist,structlistheadhead){Deletesthelistheadfromthelistdenotedbyheadandplacesitasthetailoflist,thiseffectivelyrotatesthelistsothatlistisatthefront。listmovetail(head,list);}listissingulartestswhetheralisthasjustoneentry。head:thelisttotest。staticinlineintlistissingular(conststructlistheadhead){return!listempty(head)(headnextheadprev);}staticinlinevoidlistcutposition(structlistheadlist,structlistheadhead,structlistheadentry){}listcutpositioncutalistintotwolist:anewlisttoaddallremovedentrieshead:alistwithentriesentry:anentrywithinhead,couldbetheheaditselfandifsowewontcutthelistThishelpermovestheinitialpartofhead,uptoandincludingentry,fromheadtolist。Youshouldpassonentryanelementyouknowisonhead。listshouldbeanemptylistoralistyoudonotcareaboutlosingitsdata。staticinlinevoidlistcutposition(structlistheadlist,structlistheadhead,structlistheadentry){if(listempty(head))if(listissingular(head)(headnext!entryhead!entry))if(entryhead)INITLISTHEAD(list);elselistcutposition(list,head,entry);}listcutbeforecutalistintotwo,beforegivenentrylist:anewlisttoaddallremovedentrieshead:alistwithentriesentry:anentrywithinhead,couldbetheheaditselfThishelpermovestheinitialpartofhead,uptobutexcludingentry,fromheadtolist。Youshouldpassinentryanelementyouknowisonhead。listshouldbeanemptylistoralistyoudonotcareaboutlosingitsdata。Ifentryhead,allentriesonheadaremovedtolist。staticinlinevoidlistcutbefore(structlistheadlist,structlistheadhead,structlistheadentry){if(headnextentry){INITLISTHEAD(list);}}staticinlinevoidlistsplice(conststructlistheadlist,structlistheadprev,structlistheadnext){}listsplicejointwolists,thisisdesignedforstackslist:thenewlisttoadd。head:theplacetoadditinthefirstlist。staticinlinevoidlistsplice(conststructlistheadlist,structlistheadhead){if(!listempty(list))listsplice(list,head,headnext);}listsplicetailjointwolists,eachlistbeingaqueuelist:thenewlisttoadd。head:theplacetoadditinthefirstlist。staticinlinevoidlistsplicetail(structlistheadlist,structlistheadhead){if(!listempty(list))listsplice(list,headprev,head);}listspliceinitjointwolistsandreinitialisetheemptiedlist。list:thenewlisttoadd。head:theplacetoadditinthefirstlist。Thelistatlistisreinitialisedstaticinlinevoidlistspliceinit(structlistheadlist,structlistheadhead){if(!listempty(list)){listsplice(list,head,headnext);INITLISTHEAD(list);}}listsplicetailinitjointwolistsandreinitialisetheemptiedlistlist:thenewlisttoadd。head:theplacetoadditinthefirstlist。Eachofthelistsisaqueue。Thelistatlistisreinitialisedstaticinlinevoidlistsplicetailinit(structlistheadlist,structlistheadhead){if(!listempty(list)){listsplice(list,headprev,head);INITLISTHEAD(list);}}listentrygetthestructforthisentryptr:thestructlistheadpointer。type:thetypeofthestructthisisembeddedin。member:thenameofthelistheadwithinthestruct。definelistentry(ptr,type,member)containerof(ptr,type,member)listfirstentrygetthefirstelementfromalistptr:thelistheadtotaketheelementfrom。type:thetypeofthestructthisisembeddedin。member:thenameofthelistheadwithinthestruct。Note,thatlistisexpectedtobenotempty。definelistfirstentry(ptr,type,member)listentry((ptr)next,type,member)listlastentrygetthelastelementfromalistptr:thelistheadtotaketheelementfrom。type:thetypeofthestructthisisembeddedin。member:thenameofthelistheadwithinthestruct。Note,thatlistisexpectedtobenotempty。definelistlastentry(ptr,type,member)listentry((ptr)prev,type,member)listfirstentryornullgetthefirstelementfromalistptr:thelistheadtotaketheelementfrom。type:thetypeofthestructthisisembeddedin。member:thenameofthelistheadwithinthestruct。Notethatifthelistisempty,itreturnsNULL。definelistfirstentryornull(ptr,type,member)({structlistheadhead(ptr);pos!head?listentry(pos,type,member):NULL;})listnextentrygetthenextelementinlistpos:thetypetocursormember:thenameofthelistheadwithinthestruct。definelistnextentry(pos,member)listentry((pos)member。next,typeof((pos)),member)listpreventrygettheprevelementinlistpos:thetypetocursormember:thenameofthelistheadwithinthestruct。definelistpreventry(pos,member)listentry((pos)member。prev,typeof((pos)),member)listforeachiterateoveralistpos:thestructlistheadtouseasaloopcursor。head:theheadforyourlist。definelistforeach(pos,head)for(pos(head)pos!(head);posposnext)listforeachcontinuecontinueiterationoveralistpos:thestructlistheadtouseasaloopcursor。head:theheadforyourlist。Continuetoiterateoveralist,continuingafterthecurrentposition。definelistforeachcontinue(pos,head)for(pos!(head);posposnext)listforeachpreviterateoveralistbackwardspos:thestructlistheadtouseasaloopcursor。head:theheadforyourlist。definelistforeachprev(pos,head)for(pos(head)pos!(head);posposprev)listforeachsafeiterateoveralistsafeagainstremovaloflistentrypos:thestructlistheadtouseasaloopcursor。n:anotherstructlistheadtouseastemporarystoragehead:theheadforyourlist。definelistforeachsafe(pos,n,head)for(pos(head)next,pos!(head);posn,nposnext)listforeachprevsafeiterateoveralistbackwardssafeagainstremovaloflistentrypos:thestructlistheadtouseasaloopcursor。n:anotherstructlistheadtouseastemporarystoragehead:theheadforyourlist。definelistforeachprevsafe(pos,n,head)for(pos(head)prev,pos!(head);posn,nposprev)listentryisheadtestiftheentrypointstotheheadofthelistpos:thetypetocursorhead:theheadforyourlist。member:thenameofthelistheadwithinthestruct。definelistentryishead(pos,head,member)(posmember(head))listforeachentryiterateoverlistofgiventypepos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。definelistforeachentry(pos,head,member)for(poslistfirstentry(head,typeof(pos),member);!listentryishead(pos,head,member);poslistnextentry(pos,member))listforeachentryreverseiteratebackwardsoverlistofgiventype。pos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。definelistforeachentryreverse(pos,head,member)for(poslistlastentry(head,typeof(pos),member);!listentryishead(pos,head,member);poslistpreventry(pos,member))listprepareentryprepareaposentryforuseinlistforeachentrycontinue()pos:thetypetouseasastartpointhead:theheadofthelistmember:thenameofthelistheadwithinthestruct。Preparesaposentryforuseasastartpointinlistforeachentrycontinue()。definelistprepareentry(pos,head,member)((pos)?:listentry(head,typeof(pos),member))listforeachentrycontinuecontinueiterationoverlistofgiventypepos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Continuetoiterateoverlistofgiventype,continuingafterthecurrentposition。definelistforeachentrycontinue(pos,head,member)for(poslistnextentry(pos,member);!listentryishead(pos,head,member);poslistnextentry(pos,member))listforeachentrycontinuereverseiteratebackwardsfromthegivenpointpos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Starttoiterateoverlistofgiventypebackwards,continuingafterthecurrentposition。definelistforeachentrycontinuereverse(pos,head,member)for(poslistpreventry(pos,member);!listentryishead(pos,head,member);poslistpreventry(pos,member))listforeachentryfromiterateoverlistofgiventypefromthecurrentpointpos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Iterateoverlistofgiventype,continuingfromcurrentposition。definelistforeachentryfrom(pos,head,member)for(;!listentryishead(pos,head,member);poslistnextentry(pos,member))listforeachentryfromreverseiteratebackwardsoverlistofgiventypefromthecurrentpointpos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Iteratebackwardsoverlistofgiventype,continuingfromcurrentposition。definelistforeachentryfromreverse(pos,head,member)for(;!listentryishead(pos,head,member);poslistpreventry(pos,member))listforeachentrysafeiterateoverlistofgiventypesafeagainstremovaloflistentrypos:thetypetouseasaloopcursor。n:anothertypetouseastemporarystoragehead:theheadforyourlist。member:thenameofthelistheadwithinthestruct。definelistforeachentrysafe(pos,n,head,member)for(poslistfirstentry(head,typeof(pos),member),nlistnextentry(pos,member);!listentryishead(pos,head,member);posn,nlistnextentry(n,member))listforeachentrysafecontinuecontinuelistiterationsafeagainstremovalpos:thetypetouseasaloopcursor。n:anothertypetouseastemporarystoragehead:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Iterateoverlistofgiventype,continuingaftercurrentpoint,safeagainstremovaloflistentry。definelistforeachentrysafecontinue(pos,n,head,member)for(poslistnextentry(pos,member),nlistnextentry(pos,member);!listentryishead(pos,head,member);posn,nlistnextentry(n,member))listforeachentrysafefromiterateoverlistfromcurrentpointsafeagainstremovalpos:thetypetouseasaloopcursor。n:anothertypetouseastemporarystoragehead:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Iterateoverlistofgiventypefromcurrentpoint,safeagainstremovaloflistentry。definelistforeachentrysafefrom(pos,n,head,member)for(nlistnextentry(pos,member);!listentryishead(pos,head,member);posn,nlistnextentry(n,member))listforeachentrysafereverseiteratebackwardsoverlistsafeagainstremovalpos:thetypetouseasaloopcursor。n:anothertypetouseastemporarystoragehead:theheadforyourlist。member:thenameofthelistheadwithinthestruct。Iteratebackwardsoverlistofgiventype,safeagainstremovaloflistentry。definelistforeachentrysafereverse(pos,n,head,member)for(poslistlastentry(head,typeof(pos),member),nlistpreventry(pos,member);!listentryishead(pos,head,member);posn,nlistpreventry(n,member))listsaferesetnextresetastalelistforeachentrysafelooppos:theloopcursorusedinthelistforeachentrysafeloopn:temporarystorageusedinlistforeachentrysafemember:thenameofthelistheadwithinthestruct。listsaferesetnextisnotsafetouseingeneralifthelistmaybemodifiedconcurrently(eg。thelockisdroppedintheloopbody)。Anexceptiontothisisifthecursorelement(pos)ispinnedinthelist,andlistsaferesetnextiscalledafterretakingthelockandbeforecompletingthecurrentiterationoftheloopbody。definelistsaferesetnext(pos,n,member)nlistnextentry(pos,member)Doublelinkedlistswithasinglepointerlisthead。Mostlyusefulforhashtableswherethetwopointerlistheadistoowasteful。YoulosetheabilitytoaccessthetailinO(1)。structhlisthead{};structhlistnode{structhlistnodenext,};defineHLISTHEADINIT{。firstNULL}defineHLISTHEAD(name)structhlistheadname{。firstNULL}defineINITHLISTHEAD(ptr)((ptr)firstNULL)staticinlinevoidINITHLISTNODE(structhlistnodeh){hnextNULL;hpprevNULL;}hlistunhashedHasnodebeenremovedfromlistandreinitialized?h:NodetobecheckedNotthatnotallremovalfunctionswillleaveanodeinunhashedstate。Forexample,hlistnullsdelinitrcu()doesleavethenodeinunhashedstate,buthlistnullsdel()doesnot。staticinlineinthlistunhashed(conststructhlistnodeh){return!}hlistunhashedlocklessVersionofhlistunhashedforlocklessuseh:NodetobecheckedThisvariantofhlistunhashed()mustbeusedinlocklesscontextstoavoidpotentialloadtearing。TheREADONCE()ispairedwiththevariousWRITEONCE()inhlisthelpersthataredefinedbelow。staticinlineinthlistunhashedlockless(conststructhlistnodeh){return!}hlistemptyIsthespecifiedhlistheadstructureanemptyhlist?h:Structuretocheck。staticinlineinthlistempty(conststructhlistheadh){return!}staticinlinevoidhlistdel(structhlistnoden){if(next)}hlistdelDeletethespecifiedhlistnodefromitslistn:Nodetodelete。Notethatthisfunctionleavesthenodeinhashedstate。Usehlistdelinit()orsimilarinsteadtounhashn。staticinlinevoidhlistdel(structhlistnoden){hlistdel(n);nnextLISTPOISON1;npprevLISTPOISON2;}hlistdelinitDeletethespecifiedhlistnodefromitslistandinitializen:Nodetodelete。Notethatthisfunctionleavesthenodeinunhashedstate。staticinlinevoidhlistdelinit(structhlistnoden){if(!hlistunhashed(n)){hlistdel(n);INITHLISTNODE(n);}}hlistaddheadaddanewentryatthebeginningofthehlistn:newentrytobeaddedh:hlistheadtoadditafterInsertanewentryafterthespecifiedhead。Thisisgoodforimplementingstacks。staticinlinevoidhlistaddhead(structhlistnoden,structhlistheadh){if(first)}hlistaddbeforeaddanewentrybeforetheonespecifiedn:newentrytobeaddednext:hlistnodetoadditbefore,whichmustbenonNULLstaticinlinevoidhlistaddbefore(structhlistnoden,structhlistnodenext){(npprev)n;}hlistaddbehindaddanewentryaftertheonespecifiedn:newentrytobeaddedprev:hlistnodetoadditafter,whichmustbenonNULLstaticinlinevoidhlistaddbehind(structhlistnoden,structhlistnodeprev){if(nnext)}hlistaddfakecreateafakehlistconsistingofasingleheadlessnoden:NodetomakeafakelistoutofThismakesnappeartobeitsownpredecessoronaheadlesshlist。Thepointofthisistoallowthingslikehlistdel()toworkcorrectlyincaseswherethereisnolist。staticinlinevoidhlistaddfake(structhlistnoden){}hlistfake:Isthisnodeafakehlist?h:Nodetocheckforbeingaselfreferentialfakehlist。staticinlineboolhlistfake(structhlistnodeh){}hlistissingularnodeisnodetheonlyelementofthespecifiedhlist?n:Nodetocheckforsingularity。h:Headerforpotentiallysingularlist。Checkwhetherthenodeistheonlynodeoftheheadwithoutaccessinghead,thusavoidingunnecessarycachemisses。staticinlineboolhlistissingularnode(structhlistnoden,structhlistheadh){return!}hlistmovelistMoveanhlistold:hlistheadforoldlist。new:hlistheadfornewlist。Movealistfromonelistheadtoanother。Fixupthepprevreferenceofthefirstentryifitexists。staticinlinevoidhlistmovelist(structhlistheadold,structhlistheadnew){if(newfirst)oldfirstNULL;}definehlistentry(ptr,type,member)containerof(ptr,type,member)definehlistforeach(pos,head)for(pos(head)posposnext)definehlistforeachsafe(pos,n,head)for(pos(head)pos({1;});posn)definehlistentrysafe(ptr,type,member)({typeof(ptr)ptr(ptr);ptr?hlistentry(ptr,type,member):NULL;})hlistforeachentryiterateoverlistofgiventypepos:thetypetouseasaloopcursor。head:theheadforyourlist。member:thenameofthehlistnodewithinthestruct。definehlistforeachentry(pos,head,member)for(poshlistentrysafe((head)first,typeof((pos)),member);poshlistentrysafe((pos)member。next,typeof((pos)),member))hlistforeachentrycontinueiterateoverahlistcontinuingaftercurrentpointpos:thetypetouseasaloopcursor。member:thenameofthehlistnodewithinthestruct。definehlistforeachentrycontinue(pos,member)for(poshlistentrysafe((pos)member。next,typeof((pos)),member);poshlistentrysafe((pos)member。next,typeof((pos)),member))hlistforeachentryfromiterateoverahlistcontinuingfromcurrentpointpos:thetypetouseasaloopcursor。member:thenameofthehlistnodewithinthestruct。definehlistforeachentryfrom(pos,member)for(;poshlistentrysafe((pos)member。next,typeof((pos)),member))hlistforeachentrysafeiterateoverlistofgiventypesafeagainstremovaloflistentrypos:thetypetouseasaloopcursor。n:astructhlistnodetouseastemporarystoragehead:theheadforyourlist。member:thenameofthehlistnodewithinthestruct。definehlistforeachentrysafe(pos,n,head,member)for(poshlistentrysafe((head)first,typeof(pos),member);pos({nposmember。1;});poshlistentrysafe(n,typeof(pos),member))endif
投诉 评论 转载

线下培训机构请安心中国的互联网企业的996、997及资本化带坏了全国的行业,让所有的创业者成为追逐资本逐利的投机者,实业兴国成了一句空话。特别是进入教育行业的互联网教育企业,疯狂的烧钱敛财……重要财经消息,上市公司重要公告集锦!(12月7号)【财经要闻】1。【工信部、卫健委面向医疗领域征集机器人典型应用场景】工业和信息化部、国家卫生健康委员会近日联合发函,面向医疗领域征集一批具有较高技术水平、成熟应用模式和显……鸿蒙harmonyos什么时候才敢开源?OpenHarmony没开源?需要附上开放原子基金会的网址吗〔吃瓜群众〕鸿蒙os难道被你锁起来了??为什么要开,你给线了吗?鸿蒙HarmonyOS是华为基于O……从游戏到社交,为何互联网巨头们都将元宇宙概念落在了消费者端?自从元宇宙这个概念火爆起来后,社交和游戏两大产业就找到了新的风口。不妨回想一下那些积极投身元宇宙的名字:Epic,Facebook,腾讯,字节跳动他们或是游戏巨头,或是社交大佬……加速纯电动转型路特斯未来五年推四款纯电动车型〔爱卡汽车行业资讯原创〕8月31日,吉利集团旗下超跑品牌路特斯(LOTUS)在中国正式成立全新公司路特斯科技。按照规划五年之内,路特斯科技将推出四款纯电动产品。在2022……苹果秋季发布来了,多场活动苹果秋季发布来了,多场活动关注公众号果粉机帮助果粉们快速成长果粉们Apple在今年秋天将举办多项设备发布,果粉们最期待的产品,包括新iPhone、AppleWatc……想买苹果手机,哪款值得入手,性价比高一点,不玩游戏?您好!这里是松果拆机,我是松果三号,为您解答。根据您的问题我这里有一个方案可以供您参考。小屏旗舰,美版真香众所周知,iPhone并不是仅有国行一种选择,在中国大陆有……新一代技术落地,隔空充电真的能够彻底解决电量焦虑吗?想象一个场景,当你正在厨房一边看着视频一边准备着明天午饭的时候,突然声音没了视频暂停,屏幕上赫然出现了一个熟悉的提醒:当前手机电量已不足百分之20那时候的你是一种什……现代汽车宣布在美国新投资计划,到2025年投入将超100亿美路透社5月22日消息,现代汽车集团22日宣布将在2025年前在美国追加投资50亿美元,以加强与美国公司在先进技术方面的合作,包括机器人技术、城市空中交通、自动驾驶和人工智能。……真正懂手机的只会买这几款,性价比都非常高一,红米k40(游戏增强版)这款手机搭配天玑1200处理器,6。67英寸和120Hz的刷频率,使用起来非常流畅。摄像方面搭配前置1600万像素和后置6400万主摄和800……linux内核的链循环双链表简单使用linux内核的循环双链表是非常经典的代码实现方式,个人总结如下:API多,像nginx(二者原理一致)、redis的链表在api数目上还差一点扩展性强,比如可以实现一个LRU……小米用户为何卸载了QQ音乐?5款安卓必装APP,免费又实用自从小米官网把自家音乐软件升级后,打开了合作壁垒,跟腾讯巨头旗下的QQ音乐开展了合作关系。小米用户打开自带的音乐软件后,可以登录绑定QQ音乐账号,享受QQ音乐的会员权益版……
享趣鲜奶配送系统您的最优方案IPFS存储软件测试结果初现,新元科技区块链业务迈出第一步一年之内达成目标,华为没有退路了脸书与雷朋合作,涉足智能太阳镜业务CentOS通用脚本处理jar包程序应用市场对任务悬赏类平台的态度懂车周报从3799跌至2599元,哈曼卡顿12256GB,顶配骁龙8我们国家什么时候才能成为真正的科技强国,我们现在真正处于什么监管接连出手围剿苹果税苹果(AAPL。US)尚能饭否?大病筹款平台收取支持费,你怎么看?扩大智慧办公新版图,华为面向全球发布七款终端新品MWC202中国又一奥运冠军公开怀孕喜讯,人称小章子怡素颜仍明艳动人冬季如何保养家用电器暑假中的一件后悔的事优秀作文宝贝,小心你的小屁股!UniFi全家桶YYDS!家庭网络折腾记之硬件篇在尝试中成长初中记叙文500字身为老板你最需要做的就是培养优势思维柏林前市长孤立中国不符合德国利益教女儿法庭上醉驾如何为自己辩护?桨战金溪!倒计时3天!神秘嘉宾精彩活动等你来!高考时突遇心理障碍怎么办

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利