先搁这吧,晚上回去分析。
- #include<string.h>
- #include<stdlib.h>
- #undefstrlen
- /*
- Returnthelengthofthenull-terminatedstringSTR.Scanfor
- thenullterminatorquicklybytestingfourbytesatatime.
- */
- size_tstrlen(str)
- constchar*str;
- {
- constchar*char_ptr;
- constunsignedlongint*longword_ptr;
- unsignedlongintlongword,magic_bits,himagic,lomagic;
- /*
- Handlethefirstfewcharactersbyreadingonecharacteratatime.
- DothisuntilCHAR_PTRisalignedonalongwordboundary.
- */
- for(char_ptr=str;((unsignedlongint)char_ptr
- &(sizeof(longword)-1))!=0;++char_ptr)
- if(*char_ptr=='/0')
- returnchar_ptr-str;
- /*
- Alltheseelucidatorycommentsreferto4-bytelongwords,
- butthetheoryappliesequallywellto8-bytelongwords.
- */
- longword_ptr=(unsignedlongint*)char_ptr;
- /*
- Bits31,24,16,and8ofthisnumberarezero.Callthesebits
- the"holes."Notethatthereisaholejusttotheleftof
- eachbyte,withanextraattheend:
- bits:01111110111111101111111011111111
- bytes:AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
- The1-bitsmakesurethatcarriespropagatetothenext0-bit.
- The0-bitsprovideholesforcarriestofallinto.
- */
- magic_bits=0x7efefeffL;
- himagic=0x80808080L;
- lomagic=0x01010101L;
- if(sizeof(longword)>4)
- {
- /*64-bitversionofthemagic.*/
- /*Dotheshiftintwostepstoavoidawarningiflonghas32bits.*/
- magic_bits=((0x7efefefeL<<16)<<16)|0xfefefeffL;
- himagic=((himagic<<16)<<16)|himagic;
- lomagic=((lomagic<<16)<<16)|lomagic;
- }
- if(sizeof(longword)>8)
- abort();
- /*
- Insteadofthetraditionalloopwhichtestseachcharacter,
- wewilltestalongwordatatime.Thetrickypartistesting
- if*anyofthefour*bytesinthelongwordinquestionarezero.
- */
- for(;;)
- {
- /*WetentativelyexittheloopifaddingMAGIC_BITSto
- LONGWORDfailstochangeanyoftheholebitsofLONGWORD.
- 1)Isthissafe?Willitcatchallthezerobytes?
- Supposethereisabytewithallzeros.Anycarrybits
- propagatingfromitsleftwillfallintotheholeatits
- leastsignificantbitandstop.Sincetherewillbeno
- carryfromitsmostsignificantbit,theLSBofthe
- bytetotheleftwillbeunchanged,andthezerowillbe
- detected.
- 2)Isthisworthwhile?Willitignoreeverythingexcept
- zerobytes?SupposeeverybyteofLONGWORDhasabitset
- somewhere.Therewillbeacarryintobit8.Ifbit8
- isset,thiswillcarryintobit16.Ifbit8isclear,
- oneofbits9-15mustbeset,sotherewillbeacarry
- intobit16.Similarly,therewillbeacarryintobit
- 24.Ifoneofbits24-30isset,therewillbeacarry
- intobit31,soalloftheholebitswillbechanged.
- Theonemisfireoccurswhenbits24-30areclearandbit
- 31isset;inthiscase,theholeatbit31isnot
- changed.Ifwehadaccesstotheprocessorcarryflag,
- wecouldclosethisloopholebyputtingthefourthhole
- atbit32!
- Soitignoreseverythingexcept128's,whenthey'realigned
- properly.*/
- longword=*longword_ptr++;
- if(
- #if0
- /*AddMAGIC_BITStoLONGWORD.*/
- (((longword+magic_bits)
- /*Setthosebitsthatwereunchangedbytheaddition.*/
- ^~longword)
- /*Lookatonlytheholebits.Ifanyoftheholebits
- areunchanged,mostlikelyoneofthebyteswasa
- zero.*/
- &~magic_bits)
- #else
- ((longword-lomagic)&himagic)
- #endif
- !=0)
- {
- /*
- Whichofthebyteswasthezero?Ifnoneofthemwere,itwas
- amisfire;continuethesearch.
- */
- constchar*cp=(constchar*)(longword_ptr-1);
- if(cp[0]==0)
- returncp-str;
- if(cp[1]==0)
- returncp-str+1;
- if(cp[2]==0)
- returncp-str+2;
- if(cp[3]==0)
- returncp-str+3;
- if(sizeof(longword)>4)
- {
- if(cp[4]==0)
- returncp-str+4;
- if(cp[5]==0)
- returncp-str+5;
- if(cp[6]==0)
- returncp-str+6;
- if(cp[7]==0)
- returncp-str+7;
- }
- }
- }
- }
- libc_hidden_builtin_def(strlen)