kmp_settings.cpp 217 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405
  1. /*
  2. * kmp_settings.cpp -- Initialize environment variables
  3. */
  4. //===----------------------------------------------------------------------===//
  5. //
  6. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  7. // See https://llvm.org/LICENSE.txt for license information.
  8. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #include "kmp.h"
  12. #include "kmp_affinity.h"
  13. #include "kmp_atomic.h"
  14. #if KMP_USE_HIER_SCHED
  15. #error #include "kmp_dispatch_hier.h"
  16. #endif
  17. #include "kmp_environment.h"
  18. #include "kmp_i18n.h"
  19. #include "kmp_io.h"
  20. #include "kmp_itt.h"
  21. #include "kmp_lock.h"
  22. #include "kmp_settings.h"
  23. #include "kmp_str.h"
  24. #include "kmp_wrapper_getpid.h"
  25. #include <ctype.h> // toupper()
  26. #if OMPD_SUPPORT
  27. #error #include "ompd-specific.h"
  28. #endif
  29. static int __kmp_env_toPrint(char const *name, int flag);
  30. bool __kmp_env_format = 0; // 0 - old format; 1 - new format
  31. // -----------------------------------------------------------------------------
  32. // Helper string functions. Subject to move to kmp_str.
  33. #ifdef USE_LOAD_BALANCE
  34. static double __kmp_convert_to_double(char const *s) {
  35. double result;
  36. if (KMP_SSCANF(s, "%lf", &result) < 1) {
  37. result = 0.0;
  38. }
  39. return result;
  40. }
  41. #endif
  42. #ifdef KMP_DEBUG
  43. static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src,
  44. size_t len, char sentinel) {
  45. unsigned int i;
  46. for (i = 0; i < len; i++) {
  47. if ((*src == '\0') || (*src == sentinel)) {
  48. break;
  49. }
  50. *(dest++) = *(src++);
  51. }
  52. *dest = '\0';
  53. return i;
  54. }
  55. #endif
  56. static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len,
  57. char sentinel) {
  58. size_t l = 0;
  59. if (a == NULL)
  60. a = "";
  61. if (b == NULL)
  62. b = "";
  63. while (*a && *b && *b != sentinel) {
  64. char ca = *a, cb = *b;
  65. if (ca >= 'a' && ca <= 'z')
  66. ca -= 'a' - 'A';
  67. if (cb >= 'a' && cb <= 'z')
  68. cb -= 'a' - 'A';
  69. if (ca != cb)
  70. return FALSE;
  71. ++l;
  72. ++a;
  73. ++b;
  74. }
  75. return l >= len;
  76. }
  77. // Expected usage:
  78. // token is the token to check for.
  79. // buf is the string being parsed.
  80. // *end returns the char after the end of the token.
  81. // it is not modified unless a match occurs.
  82. //
  83. // Example 1:
  84. //
  85. // if (__kmp_match_str("token", buf, *end) {
  86. // <do something>
  87. // buf = end;
  88. // }
  89. //
  90. // Example 2:
  91. //
  92. // if (__kmp_match_str("token", buf, *end) {
  93. // char *save = **end;
  94. // **end = sentinel;
  95. // <use any of the __kmp*_with_sentinel() functions>
  96. // **end = save;
  97. // buf = end;
  98. // }
  99. static int __kmp_match_str(char const *token, char const *buf,
  100. const char **end) {
  101. KMP_ASSERT(token != NULL);
  102. KMP_ASSERT(buf != NULL);
  103. KMP_ASSERT(end != NULL);
  104. while (*token && *buf) {
  105. char ct = *token, cb = *buf;
  106. if (ct >= 'a' && ct <= 'z')
  107. ct -= 'a' - 'A';
  108. if (cb >= 'a' && cb <= 'z')
  109. cb -= 'a' - 'A';
  110. if (ct != cb)
  111. return FALSE;
  112. ++token;
  113. ++buf;
  114. }
  115. if (*token) {
  116. return FALSE;
  117. }
  118. *end = buf;
  119. return TRUE;
  120. }
  121. #if KMP_OS_DARWIN
  122. static size_t __kmp_round4k(size_t size) {
  123. size_t _4k = 4 * 1024;
  124. if (size & (_4k - 1)) {
  125. size &= ~(_4k - 1);
  126. if (size <= KMP_SIZE_T_MAX - _4k) {
  127. size += _4k; // Round up if there is no overflow.
  128. }
  129. }
  130. return size;
  131. } // __kmp_round4k
  132. #endif
  133. /* Here, multipliers are like __kmp_convert_to_seconds, but floating-point
  134. values are allowed, and the return value is in milliseconds. The default
  135. multiplier is milliseconds. Returns INT_MAX only if the value specified
  136. matches "infinit*". Returns -1 if specified string is invalid. */
  137. int __kmp_convert_to_milliseconds(char const *data) {
  138. int ret, nvalues, factor;
  139. char mult, extra;
  140. double value;
  141. if (data == NULL)
  142. return (-1);
  143. if (__kmp_str_match("infinit", -1, data))
  144. return (INT_MAX);
  145. value = (double)0.0;
  146. mult = '\0';
  147. #if KMP_OS_WINDOWS && KMP_MSVC_COMPAT
  148. // On Windows, each %c parameter needs additional size parameter for sscanf_s
  149. nvalues = KMP_SSCANF(data, "%lf%c%c", &value, &mult, 1, &extra, 1);
  150. #else
  151. nvalues = KMP_SSCANF(data, "%lf%c%c", &value, &mult, &extra);
  152. #endif
  153. if (nvalues < 1)
  154. return (-1);
  155. if (nvalues == 1)
  156. mult = '\0';
  157. if (nvalues == 3)
  158. return (-1);
  159. if (value < 0)
  160. return (-1);
  161. switch (mult) {
  162. case '\0':
  163. /* default is milliseconds */
  164. factor = 1;
  165. break;
  166. case 's':
  167. case 'S':
  168. factor = 1000;
  169. break;
  170. case 'm':
  171. case 'M':
  172. factor = 1000 * 60;
  173. break;
  174. case 'h':
  175. case 'H':
  176. factor = 1000 * 60 * 60;
  177. break;
  178. case 'd':
  179. case 'D':
  180. factor = 1000 * 24 * 60 * 60;
  181. break;
  182. default:
  183. return (-1);
  184. }
  185. if (value >= ((INT_MAX - 1) / factor))
  186. ret = INT_MAX - 1; /* Don't allow infinite value here */
  187. else
  188. ret = (int)(value * (double)factor); /* truncate to int */
  189. return ret;
  190. }
  191. static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b,
  192. char sentinel) {
  193. if (a == NULL)
  194. a = "";
  195. if (b == NULL)
  196. b = "";
  197. while (*a && *b && *b != sentinel) {
  198. char ca = *a, cb = *b;
  199. if (ca >= 'a' && ca <= 'z')
  200. ca -= 'a' - 'A';
  201. if (cb >= 'a' && cb <= 'z')
  202. cb -= 'a' - 'A';
  203. if (ca != cb)
  204. return (int)(unsigned char)*a - (int)(unsigned char)*b;
  205. ++a;
  206. ++b;
  207. }
  208. return *a ? (*b && *b != sentinel)
  209. ? (int)(unsigned char)*a - (int)(unsigned char)*b
  210. : 1
  211. : (*b && *b != sentinel) ? -1
  212. : 0;
  213. }
  214. // =============================================================================
  215. // Table structures and helper functions.
  216. typedef struct __kmp_setting kmp_setting_t;
  217. typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t;
  218. typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t;
  219. typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t;
  220. typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value,
  221. void *data);
  222. typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name,
  223. void *data);
  224. struct __kmp_setting {
  225. char const *name; // Name of setting (environment variable).
  226. kmp_stg_parse_func_t parse; // Parser function.
  227. kmp_stg_print_func_t print; // Print function.
  228. void *data; // Data passed to parser and printer.
  229. int set; // Variable set during this "session"
  230. // (__kmp_env_initialize() or kmp_set_defaults() call).
  231. int defined; // Variable set in any "session".
  232. }; // struct __kmp_setting
  233. struct __kmp_stg_ss_data {
  234. size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
  235. kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
  236. }; // struct __kmp_stg_ss_data
  237. struct __kmp_stg_wp_data {
  238. int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
  239. kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
  240. }; // struct __kmp_stg_wp_data
  241. struct __kmp_stg_fr_data {
  242. int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
  243. kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
  244. }; // struct __kmp_stg_fr_data
  245. static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
  246. char const *name, // Name of variable.
  247. char const *value, // Value of the variable.
  248. kmp_setting_t **rivals // List of rival settings (must include current one).
  249. );
  250. // -----------------------------------------------------------------------------
  251. // Helper parse functions.
  252. static void __kmp_stg_parse_bool(char const *name, char const *value,
  253. int *out) {
  254. if (__kmp_str_match_true(value)) {
  255. *out = TRUE;
  256. } else if (__kmp_str_match_false(value)) {
  257. *out = FALSE;
  258. } else {
  259. __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value),
  260. KMP_HNT(ValidBoolValues), __kmp_msg_null);
  261. }
  262. } // __kmp_stg_parse_bool
  263. // placed here in order to use __kmp_round4k static function
  264. void __kmp_check_stksize(size_t *val) {
  265. // if system stack size is too big then limit the size for worker threads
  266. if (*val > KMP_DEFAULT_STKSIZE * 16) // just a heuristics...
  267. *val = KMP_DEFAULT_STKSIZE * 16;
  268. if (*val < __kmp_sys_min_stksize)
  269. *val = __kmp_sys_min_stksize;
  270. if (*val > KMP_MAX_STKSIZE)
  271. *val = KMP_MAX_STKSIZE; // dead code currently, but may work in future
  272. #if KMP_OS_DARWIN
  273. *val = __kmp_round4k(*val);
  274. #endif // KMP_OS_DARWIN
  275. }
  276. static void __kmp_stg_parse_size(char const *name, char const *value,
  277. size_t size_min, size_t size_max,
  278. int *is_specified, size_t *out,
  279. size_t factor) {
  280. char const *msg = NULL;
  281. #if KMP_OS_DARWIN
  282. size_min = __kmp_round4k(size_min);
  283. size_max = __kmp_round4k(size_max);
  284. #endif // KMP_OS_DARWIN
  285. if (value) {
  286. if (is_specified != NULL) {
  287. *is_specified = 1;
  288. }
  289. __kmp_str_to_size(value, out, factor, &msg);
  290. if (msg == NULL) {
  291. if (*out > size_max) {
  292. *out = size_max;
  293. msg = KMP_I18N_STR(ValueTooLarge);
  294. } else if (*out < size_min) {
  295. *out = size_min;
  296. msg = KMP_I18N_STR(ValueTooSmall);
  297. } else {
  298. #if KMP_OS_DARWIN
  299. size_t round4k = __kmp_round4k(*out);
  300. if (*out != round4k) {
  301. *out = round4k;
  302. msg = KMP_I18N_STR(NotMultiple4K);
  303. }
  304. #endif
  305. }
  306. } else {
  307. // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to
  308. // size_max silently.
  309. if (*out < size_min) {
  310. *out = size_max;
  311. } else if (*out > size_max) {
  312. *out = size_max;
  313. }
  314. }
  315. if (msg != NULL) {
  316. // Message is not empty. Print warning.
  317. kmp_str_buf_t buf;
  318. __kmp_str_buf_init(&buf);
  319. __kmp_str_buf_print_size(&buf, *out);
  320. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  321. KMP_INFORM(Using_str_Value, name, buf.str);
  322. __kmp_str_buf_free(&buf);
  323. }
  324. }
  325. } // __kmp_stg_parse_size
  326. static void __kmp_stg_parse_str(char const *name, char const *value,
  327. char **out) {
  328. __kmp_str_free(out);
  329. *out = __kmp_str_format("%s", value);
  330. } // __kmp_stg_parse_str
  331. static void __kmp_stg_parse_int(
  332. char const
  333. *name, // I: Name of environment variable (used in warning messages).
  334. char const *value, // I: Value of environment variable to parse.
  335. int min, // I: Minimum allowed value.
  336. int max, // I: Maximum allowed value.
  337. int *out // O: Output (parsed) value.
  338. ) {
  339. char const *msg = NULL;
  340. kmp_uint64 uint = *out;
  341. __kmp_str_to_uint(value, &uint, &msg);
  342. if (msg == NULL) {
  343. if (uint < (unsigned int)min) {
  344. msg = KMP_I18N_STR(ValueTooSmall);
  345. uint = min;
  346. } else if (uint > (unsigned int)max) {
  347. msg = KMP_I18N_STR(ValueTooLarge);
  348. uint = max;
  349. }
  350. } else {
  351. // If overflow occurred msg contains error message and uint is very big. Cut
  352. // tmp it to INT_MAX.
  353. if (uint < (unsigned int)min) {
  354. uint = min;
  355. } else if (uint > (unsigned int)max) {
  356. uint = max;
  357. }
  358. }
  359. if (msg != NULL) {
  360. // Message is not empty. Print warning.
  361. kmp_str_buf_t buf;
  362. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  363. __kmp_str_buf_init(&buf);
  364. __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint);
  365. KMP_INFORM(Using_uint64_Value, name, buf.str);
  366. __kmp_str_buf_free(&buf);
  367. }
  368. __kmp_type_convert(uint, out);
  369. } // __kmp_stg_parse_int
  370. #if KMP_DEBUG_ADAPTIVE_LOCKS
  371. static void __kmp_stg_parse_file(char const *name, char const *value,
  372. const char *suffix, char **out) {
  373. char buffer[256];
  374. char *t;
  375. int hasSuffix;
  376. __kmp_str_free(out);
  377. t = (char *)strrchr(value, '.');
  378. hasSuffix = t && __kmp_str_eqf(t, suffix);
  379. t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix);
  380. __kmp_expand_file_name(buffer, sizeof(buffer), t);
  381. __kmp_str_free(&t);
  382. *out = __kmp_str_format("%s", buffer);
  383. } // __kmp_stg_parse_file
  384. #endif
  385. #ifdef KMP_DEBUG
  386. static char *par_range_to_print = NULL;
  387. static void __kmp_stg_parse_par_range(char const *name, char const *value,
  388. int *out_range, char *out_routine,
  389. char *out_file, int *out_lb,
  390. int *out_ub) {
  391. const char *par_range_value;
  392. size_t len = KMP_STRLEN(value) + 1;
  393. par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1);
  394. KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1);
  395. __kmp_par_range = +1;
  396. __kmp_par_range_lb = 0;
  397. __kmp_par_range_ub = INT_MAX;
  398. for (;;) {
  399. unsigned int len;
  400. if (!value || *value == '\0') {
  401. break;
  402. }
  403. if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) {
  404. par_range_value = strchr(value, '=') + 1;
  405. if (!par_range_value)
  406. goto par_range_error;
  407. value = par_range_value;
  408. len = __kmp_readstr_with_sentinel(out_routine, value,
  409. KMP_PAR_RANGE_ROUTINE_LEN - 1, ',');
  410. if (len == 0) {
  411. goto par_range_error;
  412. }
  413. value = strchr(value, ',');
  414. if (value != NULL) {
  415. value++;
  416. }
  417. continue;
  418. }
  419. if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) {
  420. par_range_value = strchr(value, '=') + 1;
  421. if (!par_range_value)
  422. goto par_range_error;
  423. value = par_range_value;
  424. len = __kmp_readstr_with_sentinel(out_file, value,
  425. KMP_PAR_RANGE_FILENAME_LEN - 1, ',');
  426. if (len == 0) {
  427. goto par_range_error;
  428. }
  429. value = strchr(value, ',');
  430. if (value != NULL) {
  431. value++;
  432. }
  433. continue;
  434. }
  435. if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) ||
  436. (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) {
  437. par_range_value = strchr(value, '=') + 1;
  438. if (!par_range_value)
  439. goto par_range_error;
  440. value = par_range_value;
  441. if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
  442. goto par_range_error;
  443. }
  444. *out_range = +1;
  445. value = strchr(value, ',');
  446. if (value != NULL) {
  447. value++;
  448. }
  449. continue;
  450. }
  451. if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) {
  452. par_range_value = strchr(value, '=') + 1;
  453. if (!par_range_value)
  454. goto par_range_error;
  455. value = par_range_value;
  456. if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
  457. goto par_range_error;
  458. }
  459. *out_range = -1;
  460. value = strchr(value, ',');
  461. if (value != NULL) {
  462. value++;
  463. }
  464. continue;
  465. }
  466. par_range_error:
  467. KMP_WARNING(ParRangeSyntax, name);
  468. __kmp_par_range = 0;
  469. break;
  470. }
  471. } // __kmp_stg_parse_par_range
  472. #endif
  473. int __kmp_initial_threads_capacity(int req_nproc) {
  474. int nth = 32;
  475. /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
  476. * __kmp_max_nth) */
  477. if (nth < (4 * req_nproc))
  478. nth = (4 * req_nproc);
  479. if (nth < (4 * __kmp_xproc))
  480. nth = (4 * __kmp_xproc);
  481. // If hidden helper task is enabled, we initialize the thread capacity with
  482. // extra __kmp_hidden_helper_threads_num.
  483. if (__kmp_enable_hidden_helper) {
  484. nth += __kmp_hidden_helper_threads_num;
  485. }
  486. if (nth > __kmp_max_nth)
  487. nth = __kmp_max_nth;
  488. return nth;
  489. }
  490. int __kmp_default_tp_capacity(int req_nproc, int max_nth,
  491. int all_threads_specified) {
  492. int nth = 128;
  493. if (all_threads_specified)
  494. return max_nth;
  495. /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
  496. * __kmp_max_nth ) */
  497. if (nth < (4 * req_nproc))
  498. nth = (4 * req_nproc);
  499. if (nth < (4 * __kmp_xproc))
  500. nth = (4 * __kmp_xproc);
  501. if (nth > __kmp_max_nth)
  502. nth = __kmp_max_nth;
  503. return nth;
  504. }
  505. // -----------------------------------------------------------------------------
  506. // Helper print functions.
  507. static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name,
  508. int value) {
  509. if (__kmp_env_format) {
  510. KMP_STR_BUF_PRINT_BOOL;
  511. } else {
  512. __kmp_str_buf_print(buffer, " %s=%s\n", name, value ? "true" : "false");
  513. }
  514. } // __kmp_stg_print_bool
  515. static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name,
  516. int value) {
  517. if (__kmp_env_format) {
  518. KMP_STR_BUF_PRINT_INT;
  519. } else {
  520. __kmp_str_buf_print(buffer, " %s=%d\n", name, value);
  521. }
  522. } // __kmp_stg_print_int
  523. static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name,
  524. kmp_uint64 value) {
  525. if (__kmp_env_format) {
  526. KMP_STR_BUF_PRINT_UINT64;
  527. } else {
  528. __kmp_str_buf_print(buffer, " %s=%" KMP_UINT64_SPEC "\n", name, value);
  529. }
  530. } // __kmp_stg_print_uint64
  531. static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name,
  532. char const *value) {
  533. if (__kmp_env_format) {
  534. KMP_STR_BUF_PRINT_STR;
  535. } else {
  536. __kmp_str_buf_print(buffer, " %s=%s\n", name, value);
  537. }
  538. } // __kmp_stg_print_str
  539. static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name,
  540. size_t value) {
  541. if (__kmp_env_format) {
  542. KMP_STR_BUF_PRINT_NAME_EX(name);
  543. __kmp_str_buf_print_size(buffer, value);
  544. __kmp_str_buf_print(buffer, "'\n");
  545. } else {
  546. __kmp_str_buf_print(buffer, " %s=", name);
  547. __kmp_str_buf_print_size(buffer, value);
  548. __kmp_str_buf_print(buffer, "\n");
  549. return;
  550. }
  551. } // __kmp_stg_print_size
  552. // =============================================================================
  553. // Parse and print functions.
  554. // -----------------------------------------------------------------------------
  555. // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS
  556. static void __kmp_stg_parse_device_thread_limit(char const *name,
  557. char const *value, void *data) {
  558. kmp_setting_t **rivals = (kmp_setting_t **)data;
  559. int rc;
  560. if (strcmp(name, "KMP_ALL_THREADS") == 0) {
  561. KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT");
  562. }
  563. rc = __kmp_stg_check_rivals(name, value, rivals);
  564. if (rc) {
  565. return;
  566. }
  567. if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
  568. __kmp_max_nth = __kmp_xproc;
  569. __kmp_allThreadsSpecified = 1;
  570. } else {
  571. __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_max_nth);
  572. __kmp_allThreadsSpecified = 0;
  573. }
  574. K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth));
  575. } // __kmp_stg_parse_device_thread_limit
  576. static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer,
  577. char const *name, void *data) {
  578. __kmp_stg_print_int(buffer, name, __kmp_max_nth);
  579. } // __kmp_stg_print_device_thread_limit
  580. // -----------------------------------------------------------------------------
  581. // OMP_THREAD_LIMIT
  582. static void __kmp_stg_parse_thread_limit(char const *name, char const *value,
  583. void *data) {
  584. __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_cg_max_nth);
  585. K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth));
  586. } // __kmp_stg_parse_thread_limit
  587. static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer,
  588. char const *name, void *data) {
  589. __kmp_stg_print_int(buffer, name, __kmp_cg_max_nth);
  590. } // __kmp_stg_print_thread_limit
  591. // -----------------------------------------------------------------------------
  592. // OMP_NUM_TEAMS
  593. static void __kmp_stg_parse_nteams(char const *name, char const *value,
  594. void *data) {
  595. __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_nteams);
  596. K_DIAG(1, ("__kmp_nteams == %d\n", __kmp_nteams));
  597. } // __kmp_stg_parse_nteams
  598. static void __kmp_stg_print_nteams(kmp_str_buf_t *buffer, char const *name,
  599. void *data) {
  600. __kmp_stg_print_int(buffer, name, __kmp_nteams);
  601. } // __kmp_stg_print_nteams
  602. // -----------------------------------------------------------------------------
  603. // OMP_TEAMS_THREAD_LIMIT
  604. static void __kmp_stg_parse_teams_th_limit(char const *name, char const *value,
  605. void *data) {
  606. __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth,
  607. &__kmp_teams_thread_limit);
  608. K_DIAG(1, ("__kmp_teams_thread_limit == %d\n", __kmp_teams_thread_limit));
  609. } // __kmp_stg_parse_teams_th_limit
  610. static void __kmp_stg_print_teams_th_limit(kmp_str_buf_t *buffer,
  611. char const *name, void *data) {
  612. __kmp_stg_print_int(buffer, name, __kmp_teams_thread_limit);
  613. } // __kmp_stg_print_teams_th_limit
  614. // -----------------------------------------------------------------------------
  615. // KMP_TEAMS_THREAD_LIMIT
  616. static void __kmp_stg_parse_teams_thread_limit(char const *name,
  617. char const *value, void *data) {
  618. __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_teams_max_nth);
  619. } // __kmp_stg_teams_thread_limit
  620. static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer,
  621. char const *name, void *data) {
  622. __kmp_stg_print_int(buffer, name, __kmp_teams_max_nth);
  623. } // __kmp_stg_print_teams_thread_limit
  624. // -----------------------------------------------------------------------------
  625. // KMP_USE_YIELD
  626. static void __kmp_stg_parse_use_yield(char const *name, char const *value,
  627. void *data) {
  628. __kmp_stg_parse_int(name, value, 0, 2, &__kmp_use_yield);
  629. __kmp_use_yield_exp_set = 1;
  630. } // __kmp_stg_parse_use_yield
  631. static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name,
  632. void *data) {
  633. __kmp_stg_print_int(buffer, name, __kmp_use_yield);
  634. } // __kmp_stg_print_use_yield
  635. // -----------------------------------------------------------------------------
  636. // KMP_BLOCKTIME
  637. static void __kmp_stg_parse_blocktime(char const *name, char const *value,
  638. void *data) {
  639. __kmp_dflt_blocktime = __kmp_convert_to_milliseconds(value);
  640. if (__kmp_dflt_blocktime < 0) {
  641. __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME;
  642. __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value),
  643. __kmp_msg_null);
  644. KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime);
  645. __kmp_env_blocktime = FALSE; // Revert to default as if var not set.
  646. } else {
  647. if (__kmp_dflt_blocktime < KMP_MIN_BLOCKTIME) {
  648. __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME;
  649. __kmp_msg(kmp_ms_warning, KMP_MSG(SmallValue, name, value),
  650. __kmp_msg_null);
  651. KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime);
  652. } else if (__kmp_dflt_blocktime > KMP_MAX_BLOCKTIME) {
  653. __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;
  654. __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value),
  655. __kmp_msg_null);
  656. KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime);
  657. }
  658. __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.
  659. }
  660. #if KMP_USE_MONITOR
  661. // calculate number of monitor thread wakeup intervals corresponding to
  662. // blocktime.
  663. __kmp_monitor_wakeups =
  664. KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
  665. __kmp_bt_intervals =
  666. KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
  667. #endif
  668. K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime));
  669. if (__kmp_env_blocktime) {
  670. K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime));
  671. }
  672. } // __kmp_stg_parse_blocktime
  673. static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name,
  674. void *data) {
  675. __kmp_stg_print_int(buffer, name, __kmp_dflt_blocktime);
  676. } // __kmp_stg_print_blocktime
  677. // -----------------------------------------------------------------------------
  678. // KMP_DUPLICATE_LIB_OK
  679. static void __kmp_stg_parse_duplicate_lib_ok(char const *name,
  680. char const *value, void *data) {
  681. /* actually this variable is not supported, put here for compatibility with
  682. earlier builds and for static/dynamic combination */
  683. __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok);
  684. } // __kmp_stg_parse_duplicate_lib_ok
  685. static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer,
  686. char const *name, void *data) {
  687. __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok);
  688. } // __kmp_stg_print_duplicate_lib_ok
  689. // -----------------------------------------------------------------------------
  690. // KMP_INHERIT_FP_CONTROL
  691. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  692. static void __kmp_stg_parse_inherit_fp_control(char const *name,
  693. char const *value, void *data) {
  694. __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control);
  695. } // __kmp_stg_parse_inherit_fp_control
  696. static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer,
  697. char const *name, void *data) {
  698. #if KMP_DEBUG
  699. __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control);
  700. #endif /* KMP_DEBUG */
  701. } // __kmp_stg_print_inherit_fp_control
  702. #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
  703. // Used for OMP_WAIT_POLICY
  704. static char const *blocktime_str = NULL;
  705. // -----------------------------------------------------------------------------
  706. // KMP_LIBRARY, OMP_WAIT_POLICY
  707. static void __kmp_stg_parse_wait_policy(char const *name, char const *value,
  708. void *data) {
  709. kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;
  710. int rc;
  711. rc = __kmp_stg_check_rivals(name, value, wait->rivals);
  712. if (rc) {
  713. return;
  714. }
  715. if (wait->omp) {
  716. if (__kmp_str_match("ACTIVE", 1, value)) {
  717. __kmp_library = library_turnaround;
  718. if (blocktime_str == NULL) {
  719. // KMP_BLOCKTIME not specified, so set default to "infinite".
  720. __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;
  721. }
  722. } else if (__kmp_str_match("PASSIVE", 1, value)) {
  723. __kmp_library = library_throughput;
  724. __kmp_wpolicy_passive = true; /* allow sleep while active tasking */
  725. if (blocktime_str == NULL) {
  726. // KMP_BLOCKTIME not specified, so set default to 0.
  727. __kmp_dflt_blocktime = 0;
  728. }
  729. } else {
  730. KMP_WARNING(StgInvalidValue, name, value);
  731. }
  732. } else {
  733. if (__kmp_str_match("serial", 1, value)) { /* S */
  734. __kmp_library = library_serial;
  735. } else if (__kmp_str_match("throughput", 2, value)) { /* TH */
  736. __kmp_library = library_throughput;
  737. if (blocktime_str == NULL) {
  738. // KMP_BLOCKTIME not specified, so set default to 0.
  739. __kmp_dflt_blocktime = 0;
  740. }
  741. } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */
  742. __kmp_library = library_turnaround;
  743. } else if (__kmp_str_match("dedicated", 1, value)) { /* D */
  744. __kmp_library = library_turnaround;
  745. } else if (__kmp_str_match("multiuser", 1, value)) { /* M */
  746. __kmp_library = library_throughput;
  747. if (blocktime_str == NULL) {
  748. // KMP_BLOCKTIME not specified, so set default to 0.
  749. __kmp_dflt_blocktime = 0;
  750. }
  751. } else {
  752. KMP_WARNING(StgInvalidValue, name, value);
  753. }
  754. }
  755. } // __kmp_stg_parse_wait_policy
  756. static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name,
  757. void *data) {
  758. kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;
  759. char const *value = NULL;
  760. if (wait->omp) {
  761. switch (__kmp_library) {
  762. case library_turnaround: {
  763. value = "ACTIVE";
  764. } break;
  765. case library_throughput: {
  766. value = "PASSIVE";
  767. } break;
  768. }
  769. } else {
  770. switch (__kmp_library) {
  771. case library_serial: {
  772. value = "serial";
  773. } break;
  774. case library_turnaround: {
  775. value = "turnaround";
  776. } break;
  777. case library_throughput: {
  778. value = "throughput";
  779. } break;
  780. }
  781. }
  782. if (value != NULL) {
  783. __kmp_stg_print_str(buffer, name, value);
  784. }
  785. } // __kmp_stg_print_wait_policy
  786. #if KMP_USE_MONITOR
  787. // -----------------------------------------------------------------------------
  788. // KMP_MONITOR_STACKSIZE
  789. static void __kmp_stg_parse_monitor_stacksize(char const *name,
  790. char const *value, void *data) {
  791. __kmp_stg_parse_size(name, value, __kmp_sys_min_stksize, KMP_MAX_STKSIZE,
  792. NULL, &__kmp_monitor_stksize, 1);
  793. } // __kmp_stg_parse_monitor_stacksize
  794. static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer,
  795. char const *name, void *data) {
  796. if (__kmp_env_format) {
  797. if (__kmp_monitor_stksize > 0)
  798. KMP_STR_BUF_PRINT_NAME_EX(name);
  799. else
  800. KMP_STR_BUF_PRINT_NAME;
  801. } else {
  802. __kmp_str_buf_print(buffer, " %s", name);
  803. }
  804. if (__kmp_monitor_stksize > 0) {
  805. __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize);
  806. } else {
  807. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  808. }
  809. if (__kmp_env_format && __kmp_monitor_stksize) {
  810. __kmp_str_buf_print(buffer, "'\n");
  811. }
  812. } // __kmp_stg_print_monitor_stacksize
  813. #endif // KMP_USE_MONITOR
  814. // -----------------------------------------------------------------------------
  815. // KMP_SETTINGS
  816. static void __kmp_stg_parse_settings(char const *name, char const *value,
  817. void *data) {
  818. __kmp_stg_parse_bool(name, value, &__kmp_settings);
  819. } // __kmp_stg_parse_settings
  820. static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name,
  821. void *data) {
  822. __kmp_stg_print_bool(buffer, name, __kmp_settings);
  823. } // __kmp_stg_print_settings
  824. // -----------------------------------------------------------------------------
  825. // KMP_STACKPAD
  826. static void __kmp_stg_parse_stackpad(char const *name, char const *value,
  827. void *data) {
  828. __kmp_stg_parse_int(name, // Env var name
  829. value, // Env var value
  830. KMP_MIN_STKPADDING, // Min value
  831. KMP_MAX_STKPADDING, // Max value
  832. &__kmp_stkpadding // Var to initialize
  833. );
  834. } // __kmp_stg_parse_stackpad
  835. static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name,
  836. void *data) {
  837. __kmp_stg_print_int(buffer, name, __kmp_stkpadding);
  838. } // __kmp_stg_print_stackpad
  839. // -----------------------------------------------------------------------------
  840. // KMP_STACKOFFSET
  841. static void __kmp_stg_parse_stackoffset(char const *name, char const *value,
  842. void *data) {
  843. __kmp_stg_parse_size(name, // Env var name
  844. value, // Env var value
  845. KMP_MIN_STKOFFSET, // Min value
  846. KMP_MAX_STKOFFSET, // Max value
  847. NULL, //
  848. &__kmp_stkoffset, // Var to initialize
  849. 1);
  850. } // __kmp_stg_parse_stackoffset
  851. static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name,
  852. void *data) {
  853. __kmp_stg_print_size(buffer, name, __kmp_stkoffset);
  854. } // __kmp_stg_print_stackoffset
  855. // -----------------------------------------------------------------------------
  856. // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
  857. static void __kmp_stg_parse_stacksize(char const *name, char const *value,
  858. void *data) {
  859. kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;
  860. int rc;
  861. rc = __kmp_stg_check_rivals(name, value, stacksize->rivals);
  862. if (rc) {
  863. return;
  864. }
  865. __kmp_stg_parse_size(name, // Env var name
  866. value, // Env var value
  867. __kmp_sys_min_stksize, // Min value
  868. KMP_MAX_STKSIZE, // Max value
  869. &__kmp_env_stksize, //
  870. &__kmp_stksize, // Var to initialize
  871. stacksize->factor);
  872. } // __kmp_stg_parse_stacksize
  873. // This function is called for printing both KMP_STACKSIZE (factor is 1) and
  874. // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print
  875. // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a
  876. // customer request in future.
  877. static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name,
  878. void *data) {
  879. kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;
  880. if (__kmp_env_format) {
  881. KMP_STR_BUF_PRINT_NAME_EX(name);
  882. __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)
  883. ? __kmp_stksize / stacksize->factor
  884. : __kmp_stksize);
  885. __kmp_str_buf_print(buffer, "'\n");
  886. } else {
  887. __kmp_str_buf_print(buffer, " %s=", name);
  888. __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)
  889. ? __kmp_stksize / stacksize->factor
  890. : __kmp_stksize);
  891. __kmp_str_buf_print(buffer, "\n");
  892. }
  893. } // __kmp_stg_print_stacksize
  894. // -----------------------------------------------------------------------------
  895. // KMP_VERSION
  896. static void __kmp_stg_parse_version(char const *name, char const *value,
  897. void *data) {
  898. __kmp_stg_parse_bool(name, value, &__kmp_version);
  899. } // __kmp_stg_parse_version
  900. static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name,
  901. void *data) {
  902. __kmp_stg_print_bool(buffer, name, __kmp_version);
  903. } // __kmp_stg_print_version
  904. // -----------------------------------------------------------------------------
  905. // KMP_WARNINGS
  906. static void __kmp_stg_parse_warnings(char const *name, char const *value,
  907. void *data) {
  908. __kmp_stg_parse_bool(name, value, &__kmp_generate_warnings);
  909. if (__kmp_generate_warnings != kmp_warnings_off) {
  910. // AC: only 0/1 values documented, so reset to explicit to distinguish from
  911. // default setting
  912. __kmp_generate_warnings = kmp_warnings_explicit;
  913. }
  914. } // __kmp_stg_parse_warnings
  915. static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name,
  916. void *data) {
  917. // AC: TODO: change to print_int? (needs documentation change)
  918. __kmp_stg_print_bool(buffer, name, __kmp_generate_warnings);
  919. } // __kmp_stg_print_warnings
  920. // -----------------------------------------------------------------------------
  921. // KMP_NESTING_MODE
  922. static void __kmp_stg_parse_nesting_mode(char const *name, char const *value,
  923. void *data) {
  924. __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_nesting_mode);
  925. #if KMP_AFFINITY_SUPPORTED && KMP_USE_HWLOC
  926. if (__kmp_nesting_mode > 0)
  927. __kmp_affinity_top_method = affinity_top_method_hwloc;
  928. #endif
  929. } // __kmp_stg_parse_nesting_mode
  930. static void __kmp_stg_print_nesting_mode(kmp_str_buf_t *buffer,
  931. char const *name, void *data) {
  932. if (__kmp_env_format) {
  933. KMP_STR_BUF_PRINT_NAME;
  934. } else {
  935. __kmp_str_buf_print(buffer, " %s", name);
  936. }
  937. __kmp_str_buf_print(buffer, "=%d\n", __kmp_nesting_mode);
  938. } // __kmp_stg_print_nesting_mode
  939. // -----------------------------------------------------------------------------
  940. // OMP_NESTED, OMP_NUM_THREADS
  941. static void __kmp_stg_parse_nested(char const *name, char const *value,
  942. void *data) {
  943. int nested;
  944. KMP_INFORM(EnvVarDeprecated, name, "OMP_MAX_ACTIVE_LEVELS");
  945. __kmp_stg_parse_bool(name, value, &nested);
  946. if (nested) {
  947. if (!__kmp_dflt_max_active_levels_set)
  948. __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;
  949. } else { // nesting explicitly turned off
  950. __kmp_dflt_max_active_levels = 1;
  951. __kmp_dflt_max_active_levels_set = true;
  952. }
  953. } // __kmp_stg_parse_nested
  954. static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name,
  955. void *data) {
  956. if (__kmp_env_format) {
  957. KMP_STR_BUF_PRINT_NAME;
  958. } else {
  959. __kmp_str_buf_print(buffer, " %s", name);
  960. }
  961. __kmp_str_buf_print(buffer, ": deprecated; max-active-levels-var=%d\n",
  962. __kmp_dflt_max_active_levels);
  963. } // __kmp_stg_print_nested
  964. static void __kmp_parse_nested_num_threads(const char *var, const char *env,
  965. kmp_nested_nthreads_t *nth_array) {
  966. const char *next = env;
  967. const char *scan = next;
  968. int total = 0; // Count elements that were set. It'll be used as an array size
  969. int prev_comma = FALSE; // For correct processing sequential commas
  970. // Count the number of values in the env. var string
  971. for (;;) {
  972. SKIP_WS(next);
  973. if (*next == '\0') {
  974. break;
  975. }
  976. // Next character is not an integer or not a comma => end of list
  977. if (((*next < '0') || (*next > '9')) && (*next != ',')) {
  978. KMP_WARNING(NthSyntaxError, var, env);
  979. return;
  980. }
  981. // The next character is ','
  982. if (*next == ',') {
  983. // ',' is the first character
  984. if (total == 0 || prev_comma) {
  985. total++;
  986. }
  987. prev_comma = TRUE;
  988. next++; // skip ','
  989. SKIP_WS(next);
  990. }
  991. // Next character is a digit
  992. if (*next >= '0' && *next <= '9') {
  993. prev_comma = FALSE;
  994. SKIP_DIGITS(next);
  995. total++;
  996. const char *tmp = next;
  997. SKIP_WS(tmp);
  998. if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
  999. KMP_WARNING(NthSpacesNotAllowed, var, env);
  1000. return;
  1001. }
  1002. }
  1003. }
  1004. if (!__kmp_dflt_max_active_levels_set && total > 1)
  1005. __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;
  1006. KMP_DEBUG_ASSERT(total > 0);
  1007. if (total <= 0) {
  1008. KMP_WARNING(NthSyntaxError, var, env);
  1009. return;
  1010. }
  1011. // Check if the nested nthreads array exists
  1012. if (!nth_array->nth) {
  1013. // Allocate an array of double size
  1014. nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2);
  1015. if (nth_array->nth == NULL) {
  1016. KMP_FATAL(MemoryAllocFailed);
  1017. }
  1018. nth_array->size = total * 2;
  1019. } else {
  1020. if (nth_array->size < total) {
  1021. // Increase the array size
  1022. do {
  1023. nth_array->size *= 2;
  1024. } while (nth_array->size < total);
  1025. nth_array->nth = (int *)KMP_INTERNAL_REALLOC(
  1026. nth_array->nth, sizeof(int) * nth_array->size);
  1027. if (nth_array->nth == NULL) {
  1028. KMP_FATAL(MemoryAllocFailed);
  1029. }
  1030. }
  1031. }
  1032. nth_array->used = total;
  1033. int i = 0;
  1034. prev_comma = FALSE;
  1035. total = 0;
  1036. // Save values in the array
  1037. for (;;) {
  1038. SKIP_WS(scan);
  1039. if (*scan == '\0') {
  1040. break;
  1041. }
  1042. // The next character is ','
  1043. if (*scan == ',') {
  1044. // ',' in the beginning of the list
  1045. if (total == 0) {
  1046. // The value is supposed to be equal to __kmp_avail_proc but it is
  1047. // unknown at the moment.
  1048. // So let's put a placeholder (#threads = 0) to correct it later.
  1049. nth_array->nth[i++] = 0;
  1050. total++;
  1051. } else if (prev_comma) {
  1052. // Num threads is inherited from the previous level
  1053. nth_array->nth[i] = nth_array->nth[i - 1];
  1054. i++;
  1055. total++;
  1056. }
  1057. prev_comma = TRUE;
  1058. scan++; // skip ','
  1059. SKIP_WS(scan);
  1060. }
  1061. // Next character is a digit
  1062. if (*scan >= '0' && *scan <= '9') {
  1063. int num;
  1064. const char *buf = scan;
  1065. char const *msg = NULL;
  1066. prev_comma = FALSE;
  1067. SKIP_DIGITS(scan);
  1068. total++;
  1069. num = __kmp_str_to_int(buf, *scan);
  1070. if (num < KMP_MIN_NTH) {
  1071. msg = KMP_I18N_STR(ValueTooSmall);
  1072. num = KMP_MIN_NTH;
  1073. } else if (num > __kmp_sys_max_nth) {
  1074. msg = KMP_I18N_STR(ValueTooLarge);
  1075. num = __kmp_sys_max_nth;
  1076. }
  1077. if (msg != NULL) {
  1078. // Message is not empty. Print warning.
  1079. KMP_WARNING(ParseSizeIntWarn, var, env, msg);
  1080. KMP_INFORM(Using_int_Value, var, num);
  1081. }
  1082. nth_array->nth[i++] = num;
  1083. }
  1084. }
  1085. }
  1086. static void __kmp_stg_parse_num_threads(char const *name, char const *value,
  1087. void *data) {
  1088. // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
  1089. if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
  1090. // The array of 1 element
  1091. __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int));
  1092. __kmp_nested_nth.size = __kmp_nested_nth.used = 1;
  1093. __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub =
  1094. __kmp_xproc;
  1095. } else {
  1096. __kmp_parse_nested_num_threads(name, value, &__kmp_nested_nth);
  1097. if (__kmp_nested_nth.nth) {
  1098. __kmp_dflt_team_nth = __kmp_nested_nth.nth[0];
  1099. if (__kmp_dflt_team_nth_ub < __kmp_dflt_team_nth) {
  1100. __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth;
  1101. }
  1102. }
  1103. }
  1104. K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth));
  1105. } // __kmp_stg_parse_num_threads
  1106. static void __kmp_stg_parse_num_hidden_helper_threads(char const *name,
  1107. char const *value,
  1108. void *data) {
  1109. __kmp_stg_parse_int(name, value, 0, 16, &__kmp_hidden_helper_threads_num);
  1110. // If the number of hidden helper threads is zero, we disable hidden helper
  1111. // task
  1112. if (__kmp_hidden_helper_threads_num == 0) {
  1113. __kmp_enable_hidden_helper = FALSE;
  1114. } else {
  1115. // Since the main thread of hidden helper team dooes not participate
  1116. // in tasks execution let's increment the number of threads by one
  1117. // so that requested number of threads do actual job.
  1118. __kmp_hidden_helper_threads_num++;
  1119. }
  1120. } // __kmp_stg_parse_num_hidden_helper_threads
  1121. static void __kmp_stg_print_num_hidden_helper_threads(kmp_str_buf_t *buffer,
  1122. char const *name,
  1123. void *data) {
  1124. if (__kmp_hidden_helper_threads_num == 0) {
  1125. __kmp_stg_print_int(buffer, name, __kmp_hidden_helper_threads_num);
  1126. } else {
  1127. KMP_DEBUG_ASSERT(__kmp_hidden_helper_threads_num > 1);
  1128. // Let's exclude the main thread of hidden helper team and print
  1129. // number of worker threads those do actual job.
  1130. __kmp_stg_print_int(buffer, name, __kmp_hidden_helper_threads_num - 1);
  1131. }
  1132. } // __kmp_stg_print_num_hidden_helper_threads
  1133. static void __kmp_stg_parse_use_hidden_helper(char const *name,
  1134. char const *value, void *data) {
  1135. __kmp_stg_parse_bool(name, value, &__kmp_enable_hidden_helper);
  1136. #if !KMP_OS_LINUX
  1137. __kmp_enable_hidden_helper = FALSE;
  1138. K_DIAG(1,
  1139. ("__kmp_stg_parse_use_hidden_helper: Disable hidden helper task on "
  1140. "non-Linux platform although it is enabled by user explicitly.\n"));
  1141. #endif
  1142. } // __kmp_stg_parse_use_hidden_helper
  1143. static void __kmp_stg_print_use_hidden_helper(kmp_str_buf_t *buffer,
  1144. char const *name, void *data) {
  1145. __kmp_stg_print_bool(buffer, name, __kmp_enable_hidden_helper);
  1146. } // __kmp_stg_print_use_hidden_helper
  1147. static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name,
  1148. void *data) {
  1149. if (__kmp_env_format) {
  1150. KMP_STR_BUF_PRINT_NAME;
  1151. } else {
  1152. __kmp_str_buf_print(buffer, " %s", name);
  1153. }
  1154. if (__kmp_nested_nth.used) {
  1155. kmp_str_buf_t buf;
  1156. __kmp_str_buf_init(&buf);
  1157. for (int i = 0; i < __kmp_nested_nth.used; i++) {
  1158. __kmp_str_buf_print(&buf, "%d", __kmp_nested_nth.nth[i]);
  1159. if (i < __kmp_nested_nth.used - 1) {
  1160. __kmp_str_buf_print(&buf, ",");
  1161. }
  1162. }
  1163. __kmp_str_buf_print(buffer, "='%s'\n", buf.str);
  1164. __kmp_str_buf_free(&buf);
  1165. } else {
  1166. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  1167. }
  1168. } // __kmp_stg_print_num_threads
  1169. // -----------------------------------------------------------------------------
  1170. // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
  1171. static void __kmp_stg_parse_tasking(char const *name, char const *value,
  1172. void *data) {
  1173. __kmp_stg_parse_int(name, value, 0, (int)tskm_max,
  1174. (int *)&__kmp_tasking_mode);
  1175. } // __kmp_stg_parse_tasking
  1176. static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name,
  1177. void *data) {
  1178. __kmp_stg_print_int(buffer, name, __kmp_tasking_mode);
  1179. } // __kmp_stg_print_tasking
  1180. static void __kmp_stg_parse_task_stealing(char const *name, char const *value,
  1181. void *data) {
  1182. __kmp_stg_parse_int(name, value, 0, 1,
  1183. (int *)&__kmp_task_stealing_constraint);
  1184. } // __kmp_stg_parse_task_stealing
  1185. static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer,
  1186. char const *name, void *data) {
  1187. __kmp_stg_print_int(buffer, name, __kmp_task_stealing_constraint);
  1188. } // __kmp_stg_print_task_stealing
  1189. static void __kmp_stg_parse_max_active_levels(char const *name,
  1190. char const *value, void *data) {
  1191. kmp_uint64 tmp_dflt = 0;
  1192. char const *msg = NULL;
  1193. if (!__kmp_dflt_max_active_levels_set) {
  1194. // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting
  1195. __kmp_str_to_uint(value, &tmp_dflt, &msg);
  1196. if (msg != NULL) { // invalid setting; print warning and ignore
  1197. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  1198. } else if (tmp_dflt > KMP_MAX_ACTIVE_LEVELS_LIMIT) {
  1199. // invalid setting; print warning and ignore
  1200. msg = KMP_I18N_STR(ValueTooLarge);
  1201. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  1202. } else { // valid setting
  1203. __kmp_type_convert(tmp_dflt, &(__kmp_dflt_max_active_levels));
  1204. __kmp_dflt_max_active_levels_set = true;
  1205. }
  1206. }
  1207. } // __kmp_stg_parse_max_active_levels
  1208. static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer,
  1209. char const *name, void *data) {
  1210. __kmp_stg_print_int(buffer, name, __kmp_dflt_max_active_levels);
  1211. } // __kmp_stg_print_max_active_levels
  1212. // -----------------------------------------------------------------------------
  1213. // OpenMP 4.0: OMP_DEFAULT_DEVICE
  1214. static void __kmp_stg_parse_default_device(char const *name, char const *value,
  1215. void *data) {
  1216. __kmp_stg_parse_int(name, value, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT,
  1217. &__kmp_default_device);
  1218. } // __kmp_stg_parse_default_device
  1219. static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer,
  1220. char const *name, void *data) {
  1221. __kmp_stg_print_int(buffer, name, __kmp_default_device);
  1222. } // __kmp_stg_print_default_device
  1223. // -----------------------------------------------------------------------------
  1224. // OpenMP 5.0: OMP_TARGET_OFFLOAD
  1225. static void __kmp_stg_parse_target_offload(char const *name, char const *value,
  1226. void *data) {
  1227. const char *next = value;
  1228. const char *scan = next;
  1229. __kmp_target_offload = tgt_default;
  1230. SKIP_WS(next);
  1231. if (*next == '\0')
  1232. return;
  1233. scan = next;
  1234. if (!__kmp_strcasecmp_with_sentinel("mandatory", scan, 0)) {
  1235. __kmp_target_offload = tgt_mandatory;
  1236. } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan, 0)) {
  1237. __kmp_target_offload = tgt_disabled;
  1238. } else if (!__kmp_strcasecmp_with_sentinel("default", scan, 0)) {
  1239. __kmp_target_offload = tgt_default;
  1240. } else {
  1241. KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT");
  1242. }
  1243. } // __kmp_stg_parse_target_offload
  1244. static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer,
  1245. char const *name, void *data) {
  1246. const char *value = NULL;
  1247. if (__kmp_target_offload == tgt_default)
  1248. value = "DEFAULT";
  1249. else if (__kmp_target_offload == tgt_mandatory)
  1250. value = "MANDATORY";
  1251. else if (__kmp_target_offload == tgt_disabled)
  1252. value = "DISABLED";
  1253. KMP_DEBUG_ASSERT(value);
  1254. if (__kmp_env_format) {
  1255. KMP_STR_BUF_PRINT_NAME;
  1256. } else {
  1257. __kmp_str_buf_print(buffer, " %s", name);
  1258. }
  1259. __kmp_str_buf_print(buffer, "=%s\n", value);
  1260. } // __kmp_stg_print_target_offload
  1261. // -----------------------------------------------------------------------------
  1262. // OpenMP 4.5: OMP_MAX_TASK_PRIORITY
  1263. static void __kmp_stg_parse_max_task_priority(char const *name,
  1264. char const *value, void *data) {
  1265. __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT,
  1266. &__kmp_max_task_priority);
  1267. } // __kmp_stg_parse_max_task_priority
  1268. static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer,
  1269. char const *name, void *data) {
  1270. __kmp_stg_print_int(buffer, name, __kmp_max_task_priority);
  1271. } // __kmp_stg_print_max_task_priority
  1272. // KMP_TASKLOOP_MIN_TASKS
  1273. // taskloop threshold to switch from recursive to linear tasks creation
  1274. static void __kmp_stg_parse_taskloop_min_tasks(char const *name,
  1275. char const *value, void *data) {
  1276. int tmp;
  1277. __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp);
  1278. __kmp_taskloop_min_tasks = tmp;
  1279. } // __kmp_stg_parse_taskloop_min_tasks
  1280. static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer,
  1281. char const *name, void *data) {
  1282. __kmp_stg_print_uint64(buffer, name, __kmp_taskloop_min_tasks);
  1283. } // __kmp_stg_print_taskloop_min_tasks
  1284. // -----------------------------------------------------------------------------
  1285. // KMP_DISP_NUM_BUFFERS
  1286. static void __kmp_stg_parse_disp_buffers(char const *name, char const *value,
  1287. void *data) {
  1288. if (TCR_4(__kmp_init_serial)) {
  1289. KMP_WARNING(EnvSerialWarn, name);
  1290. return;
  1291. } // read value before serial initialization only
  1292. __kmp_stg_parse_int(name, value, KMP_MIN_DISP_NUM_BUFF, KMP_MAX_DISP_NUM_BUFF,
  1293. &__kmp_dispatch_num_buffers);
  1294. } // __kmp_stg_parse_disp_buffers
  1295. static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer,
  1296. char const *name, void *data) {
  1297. __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers);
  1298. } // __kmp_stg_print_disp_buffers
  1299. #if KMP_NESTED_HOT_TEAMS
  1300. // -----------------------------------------------------------------------------
  1301. // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
  1302. static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value,
  1303. void *data) {
  1304. if (TCR_4(__kmp_init_parallel)) {
  1305. KMP_WARNING(EnvParallelWarn, name);
  1306. return;
  1307. } // read value before first parallel only
  1308. __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
  1309. &__kmp_hot_teams_max_level);
  1310. } // __kmp_stg_parse_hot_teams_level
  1311. static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer,
  1312. char const *name, void *data) {
  1313. __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level);
  1314. } // __kmp_stg_print_hot_teams_level
  1315. static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value,
  1316. void *data) {
  1317. if (TCR_4(__kmp_init_parallel)) {
  1318. KMP_WARNING(EnvParallelWarn, name);
  1319. return;
  1320. } // read value before first parallel only
  1321. __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
  1322. &__kmp_hot_teams_mode);
  1323. } // __kmp_stg_parse_hot_teams_mode
  1324. static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer,
  1325. char const *name, void *data) {
  1326. __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode);
  1327. } // __kmp_stg_print_hot_teams_mode
  1328. #endif // KMP_NESTED_HOT_TEAMS
  1329. // -----------------------------------------------------------------------------
  1330. // KMP_HANDLE_SIGNALS
  1331. #if KMP_HANDLE_SIGNALS
  1332. static void __kmp_stg_parse_handle_signals(char const *name, char const *value,
  1333. void *data) {
  1334. __kmp_stg_parse_bool(name, value, &__kmp_handle_signals);
  1335. } // __kmp_stg_parse_handle_signals
  1336. static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer,
  1337. char const *name, void *data) {
  1338. __kmp_stg_print_bool(buffer, name, __kmp_handle_signals);
  1339. } // __kmp_stg_print_handle_signals
  1340. #endif // KMP_HANDLE_SIGNALS
  1341. // -----------------------------------------------------------------------------
  1342. // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
  1343. #ifdef KMP_DEBUG
  1344. #define KMP_STG_X_DEBUG(x) \
  1345. static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
  1346. void *data) { \
  1347. __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \
  1348. } /* __kmp_stg_parse_x_debug */ \
  1349. static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \
  1350. char const *name, void *data) { \
  1351. __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \
  1352. } /* __kmp_stg_print_x_debug */
  1353. KMP_STG_X_DEBUG(a)
  1354. KMP_STG_X_DEBUG(b)
  1355. KMP_STG_X_DEBUG(c)
  1356. KMP_STG_X_DEBUG(d)
  1357. KMP_STG_X_DEBUG(e)
  1358. KMP_STG_X_DEBUG(f)
  1359. #undef KMP_STG_X_DEBUG
  1360. static void __kmp_stg_parse_debug(char const *name, char const *value,
  1361. void *data) {
  1362. int debug = 0;
  1363. __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug);
  1364. if (kmp_a_debug < debug) {
  1365. kmp_a_debug = debug;
  1366. }
  1367. if (kmp_b_debug < debug) {
  1368. kmp_b_debug = debug;
  1369. }
  1370. if (kmp_c_debug < debug) {
  1371. kmp_c_debug = debug;
  1372. }
  1373. if (kmp_d_debug < debug) {
  1374. kmp_d_debug = debug;
  1375. }
  1376. if (kmp_e_debug < debug) {
  1377. kmp_e_debug = debug;
  1378. }
  1379. if (kmp_f_debug < debug) {
  1380. kmp_f_debug = debug;
  1381. }
  1382. } // __kmp_stg_parse_debug
  1383. static void __kmp_stg_parse_debug_buf(char const *name, char const *value,
  1384. void *data) {
  1385. __kmp_stg_parse_bool(name, value, &__kmp_debug_buf);
  1386. // !!! TODO: Move buffer initialization of of this file! It may works
  1387. // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
  1388. // KMP_DEBUG_BUF_CHARS.
  1389. if (__kmp_debug_buf) {
  1390. int i;
  1391. int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars;
  1392. /* allocate and initialize all entries in debug buffer to empty */
  1393. __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char));
  1394. for (i = 0; i < elements; i += __kmp_debug_buf_chars)
  1395. __kmp_debug_buffer[i] = '\0';
  1396. __kmp_debug_count = 0;
  1397. }
  1398. K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf));
  1399. } // __kmp_stg_parse_debug_buf
  1400. static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name,
  1401. void *data) {
  1402. __kmp_stg_print_bool(buffer, name, __kmp_debug_buf);
  1403. } // __kmp_stg_print_debug_buf
  1404. static void __kmp_stg_parse_debug_buf_atomic(char const *name,
  1405. char const *value, void *data) {
  1406. __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic);
  1407. } // __kmp_stg_parse_debug_buf_atomic
  1408. static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer,
  1409. char const *name, void *data) {
  1410. __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic);
  1411. } // __kmp_stg_print_debug_buf_atomic
  1412. static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value,
  1413. void *data) {
  1414. __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX,
  1415. &__kmp_debug_buf_chars);
  1416. } // __kmp_stg_debug_parse_buf_chars
  1417. static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer,
  1418. char const *name, void *data) {
  1419. __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars);
  1420. } // __kmp_stg_print_debug_buf_chars
  1421. static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value,
  1422. void *data) {
  1423. __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX,
  1424. &__kmp_debug_buf_lines);
  1425. } // __kmp_stg_parse_debug_buf_lines
  1426. static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer,
  1427. char const *name, void *data) {
  1428. __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines);
  1429. } // __kmp_stg_print_debug_buf_lines
  1430. static void __kmp_stg_parse_diag(char const *name, char const *value,
  1431. void *data) {
  1432. __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag);
  1433. } // __kmp_stg_parse_diag
  1434. static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name,
  1435. void *data) {
  1436. __kmp_stg_print_int(buffer, name, kmp_diag);
  1437. } // __kmp_stg_print_diag
  1438. #endif // KMP_DEBUG
  1439. // -----------------------------------------------------------------------------
  1440. // KMP_ALIGN_ALLOC
  1441. static void __kmp_stg_parse_align_alloc(char const *name, char const *value,
  1442. void *data) {
  1443. __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL,
  1444. &__kmp_align_alloc, 1);
  1445. } // __kmp_stg_parse_align_alloc
  1446. static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name,
  1447. void *data) {
  1448. __kmp_stg_print_size(buffer, name, __kmp_align_alloc);
  1449. } // __kmp_stg_print_align_alloc
  1450. // -----------------------------------------------------------------------------
  1451. // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
  1452. // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
  1453. // parse and print functions, pass required info through data argument.
  1454. static void __kmp_stg_parse_barrier_branch_bit(char const *name,
  1455. char const *value, void *data) {
  1456. const char *var;
  1457. /* ---------- Barrier branch bit control ------------ */
  1458. for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
  1459. var = __kmp_barrier_branch_bit_env_name[i];
  1460. if ((strcmp(var, name) == 0) && (value != 0)) {
  1461. char *comma;
  1462. comma = CCAST(char *, strchr(value, ','));
  1463. __kmp_barrier_gather_branch_bits[i] =
  1464. (kmp_uint32)__kmp_str_to_int(value, ',');
  1465. /* is there a specified release parameter? */
  1466. if (comma == NULL) {
  1467. __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
  1468. } else {
  1469. __kmp_barrier_release_branch_bits[i] =
  1470. (kmp_uint32)__kmp_str_to_int(comma + 1, 0);
  1471. if (__kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
  1472. __kmp_msg(kmp_ms_warning,
  1473. KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
  1474. __kmp_msg_null);
  1475. __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
  1476. }
  1477. }
  1478. if (__kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
  1479. KMP_WARNING(BarrGatherValueInvalid, name, value);
  1480. KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt);
  1481. __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt;
  1482. }
  1483. }
  1484. K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i],
  1485. __kmp_barrier_gather_branch_bits[i],
  1486. __kmp_barrier_release_branch_bits[i]))
  1487. }
  1488. } // __kmp_stg_parse_barrier_branch_bit
  1489. static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer,
  1490. char const *name, void *data) {
  1491. const char *var;
  1492. for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
  1493. var = __kmp_barrier_branch_bit_env_name[i];
  1494. if (strcmp(var, name) == 0) {
  1495. if (__kmp_env_format) {
  1496. KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]);
  1497. } else {
  1498. __kmp_str_buf_print(buffer, " %s='",
  1499. __kmp_barrier_branch_bit_env_name[i]);
  1500. }
  1501. __kmp_str_buf_print(buffer, "%d,%d'\n",
  1502. __kmp_barrier_gather_branch_bits[i],
  1503. __kmp_barrier_release_branch_bits[i]);
  1504. }
  1505. }
  1506. } // __kmp_stg_print_barrier_branch_bit
  1507. // ----------------------------------------------------------------------------
  1508. // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
  1509. // KMP_REDUCTION_BARRIER_PATTERN
  1510. // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
  1511. // print functions, pass required data to functions through data argument.
  1512. static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value,
  1513. void *data) {
  1514. const char *var;
  1515. /* ---------- Barrier method control ------------ */
  1516. static int dist_req = 0, non_dist_req = 0;
  1517. static bool warn = 1;
  1518. for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
  1519. var = __kmp_barrier_pattern_env_name[i];
  1520. if ((strcmp(var, name) == 0) && (value != 0)) {
  1521. int j;
  1522. char *comma = CCAST(char *, strchr(value, ','));
  1523. /* handle first parameter: gather pattern */
  1524. for (j = bp_linear_bar; j < bp_last_bar; j++) {
  1525. if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1,
  1526. ',')) {
  1527. if (j == bp_dist_bar) {
  1528. dist_req++;
  1529. } else {
  1530. non_dist_req++;
  1531. }
  1532. __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j;
  1533. break;
  1534. }
  1535. }
  1536. if (j == bp_last_bar) {
  1537. KMP_WARNING(BarrGatherValueInvalid, name, value);
  1538. KMP_INFORM(Using_str_Value, name,
  1539. __kmp_barrier_pattern_name[bp_linear_bar]);
  1540. }
  1541. /* handle second parameter: release pattern */
  1542. if (comma != NULL) {
  1543. for (j = bp_linear_bar; j < bp_last_bar; j++) {
  1544. if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) {
  1545. if (j == bp_dist_bar) {
  1546. dist_req++;
  1547. } else {
  1548. non_dist_req++;
  1549. }
  1550. __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j;
  1551. break;
  1552. }
  1553. }
  1554. if (j == bp_last_bar) {
  1555. __kmp_msg(kmp_ms_warning,
  1556. KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
  1557. __kmp_msg_null);
  1558. KMP_INFORM(Using_str_Value, name,
  1559. __kmp_barrier_pattern_name[bp_linear_bar]);
  1560. }
  1561. }
  1562. }
  1563. }
  1564. if (dist_req != 0) {
  1565. // set all barriers to dist
  1566. if ((non_dist_req != 0) && warn) {
  1567. KMP_INFORM(BarrierPatternOverride, name,
  1568. __kmp_barrier_pattern_name[bp_dist_bar]);
  1569. warn = 0;
  1570. }
  1571. for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
  1572. if (__kmp_barrier_release_pattern[i] != bp_dist_bar)
  1573. __kmp_barrier_release_pattern[i] = bp_dist_bar;
  1574. if (__kmp_barrier_gather_pattern[i] != bp_dist_bar)
  1575. __kmp_barrier_gather_pattern[i] = bp_dist_bar;
  1576. }
  1577. }
  1578. } // __kmp_stg_parse_barrier_pattern
  1579. static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer,
  1580. char const *name, void *data) {
  1581. const char *var;
  1582. for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
  1583. var = __kmp_barrier_pattern_env_name[i];
  1584. if (strcmp(var, name) == 0) {
  1585. int j = __kmp_barrier_gather_pattern[i];
  1586. int k = __kmp_barrier_release_pattern[i];
  1587. if (__kmp_env_format) {
  1588. KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]);
  1589. } else {
  1590. __kmp_str_buf_print(buffer, " %s='",
  1591. __kmp_barrier_pattern_env_name[i]);
  1592. }
  1593. KMP_DEBUG_ASSERT(j < bp_last_bar && k < bp_last_bar);
  1594. __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j],
  1595. __kmp_barrier_pattern_name[k]);
  1596. }
  1597. }
  1598. } // __kmp_stg_print_barrier_pattern
  1599. // -----------------------------------------------------------------------------
  1600. // KMP_ABORT_DELAY
  1601. static void __kmp_stg_parse_abort_delay(char const *name, char const *value,
  1602. void *data) {
  1603. // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
  1604. // milliseconds.
  1605. int delay = __kmp_abort_delay / 1000;
  1606. __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay);
  1607. __kmp_abort_delay = delay * 1000;
  1608. } // __kmp_stg_parse_abort_delay
  1609. static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name,
  1610. void *data) {
  1611. __kmp_stg_print_int(buffer, name, __kmp_abort_delay);
  1612. } // __kmp_stg_print_abort_delay
  1613. // -----------------------------------------------------------------------------
  1614. // KMP_CPUINFO_FILE
  1615. static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value,
  1616. void *data) {
  1617. #if KMP_AFFINITY_SUPPORTED
  1618. __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file);
  1619. K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file));
  1620. #endif
  1621. } //__kmp_stg_parse_cpuinfo_file
  1622. static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer,
  1623. char const *name, void *data) {
  1624. #if KMP_AFFINITY_SUPPORTED
  1625. if (__kmp_env_format) {
  1626. KMP_STR_BUF_PRINT_NAME;
  1627. } else {
  1628. __kmp_str_buf_print(buffer, " %s", name);
  1629. }
  1630. if (__kmp_cpuinfo_file) {
  1631. __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file);
  1632. } else {
  1633. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  1634. }
  1635. #endif
  1636. } //__kmp_stg_print_cpuinfo_file
  1637. // -----------------------------------------------------------------------------
  1638. // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
  1639. static void __kmp_stg_parse_force_reduction(char const *name, char const *value,
  1640. void *data) {
  1641. kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
  1642. int rc;
  1643. rc = __kmp_stg_check_rivals(name, value, reduction->rivals);
  1644. if (rc) {
  1645. return;
  1646. }
  1647. if (reduction->force) {
  1648. if (value != 0) {
  1649. if (__kmp_str_match("critical", 0, value))
  1650. __kmp_force_reduction_method = critical_reduce_block;
  1651. else if (__kmp_str_match("atomic", 0, value))
  1652. __kmp_force_reduction_method = atomic_reduce_block;
  1653. else if (__kmp_str_match("tree", 0, value))
  1654. __kmp_force_reduction_method = tree_reduce_block;
  1655. else {
  1656. KMP_FATAL(UnknownForceReduction, name, value);
  1657. }
  1658. }
  1659. } else {
  1660. __kmp_stg_parse_bool(name, value, &__kmp_determ_red);
  1661. if (__kmp_determ_red) {
  1662. __kmp_force_reduction_method = tree_reduce_block;
  1663. } else {
  1664. __kmp_force_reduction_method = reduction_method_not_defined;
  1665. }
  1666. }
  1667. K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
  1668. __kmp_force_reduction_method));
  1669. } // __kmp_stg_parse_force_reduction
  1670. static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer,
  1671. char const *name, void *data) {
  1672. kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
  1673. if (reduction->force) {
  1674. if (__kmp_force_reduction_method == critical_reduce_block) {
  1675. __kmp_stg_print_str(buffer, name, "critical");
  1676. } else if (__kmp_force_reduction_method == atomic_reduce_block) {
  1677. __kmp_stg_print_str(buffer, name, "atomic");
  1678. } else if (__kmp_force_reduction_method == tree_reduce_block) {
  1679. __kmp_stg_print_str(buffer, name, "tree");
  1680. } else {
  1681. if (__kmp_env_format) {
  1682. KMP_STR_BUF_PRINT_NAME;
  1683. } else {
  1684. __kmp_str_buf_print(buffer, " %s", name);
  1685. }
  1686. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  1687. }
  1688. } else {
  1689. __kmp_stg_print_bool(buffer, name, __kmp_determ_red);
  1690. }
  1691. } // __kmp_stg_print_force_reduction
  1692. // -----------------------------------------------------------------------------
  1693. // KMP_STORAGE_MAP
  1694. static void __kmp_stg_parse_storage_map(char const *name, char const *value,
  1695. void *data) {
  1696. if (__kmp_str_match("verbose", 1, value)) {
  1697. __kmp_storage_map = TRUE;
  1698. __kmp_storage_map_verbose = TRUE;
  1699. __kmp_storage_map_verbose_specified = TRUE;
  1700. } else {
  1701. __kmp_storage_map_verbose = FALSE;
  1702. __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!!
  1703. }
  1704. } // __kmp_stg_parse_storage_map
  1705. static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name,
  1706. void *data) {
  1707. if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) {
  1708. __kmp_stg_print_str(buffer, name, "verbose");
  1709. } else {
  1710. __kmp_stg_print_bool(buffer, name, __kmp_storage_map);
  1711. }
  1712. } // __kmp_stg_print_storage_map
  1713. // -----------------------------------------------------------------------------
  1714. // KMP_ALL_THREADPRIVATE
  1715. static void __kmp_stg_parse_all_threadprivate(char const *name,
  1716. char const *value, void *data) {
  1717. __kmp_stg_parse_int(name, value,
  1718. __kmp_allThreadsSpecified ? __kmp_max_nth : 1,
  1719. __kmp_max_nth, &__kmp_tp_capacity);
  1720. } // __kmp_stg_parse_all_threadprivate
  1721. static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer,
  1722. char const *name, void *data) {
  1723. __kmp_stg_print_int(buffer, name, __kmp_tp_capacity);
  1724. }
  1725. // -----------------------------------------------------------------------------
  1726. // KMP_FOREIGN_THREADS_THREADPRIVATE
  1727. static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name,
  1728. char const *value,
  1729. void *data) {
  1730. __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp);
  1731. } // __kmp_stg_parse_foreign_threads_threadprivate
  1732. static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer,
  1733. char const *name,
  1734. void *data) {
  1735. __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp);
  1736. } // __kmp_stg_print_foreign_threads_threadprivate
  1737. // -----------------------------------------------------------------------------
  1738. // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
  1739. #if KMP_AFFINITY_SUPPORTED
  1740. // Parse the proc id list. Return TRUE if successful, FALSE otherwise.
  1741. static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env,
  1742. const char **nextEnv,
  1743. char **proclist) {
  1744. const char *scan = env;
  1745. const char *next = scan;
  1746. int empty = TRUE;
  1747. *proclist = NULL;
  1748. for (;;) {
  1749. int start, end, stride;
  1750. SKIP_WS(scan);
  1751. next = scan;
  1752. if (*next == '\0') {
  1753. break;
  1754. }
  1755. if (*next == '{') {
  1756. int num;
  1757. next++; // skip '{'
  1758. SKIP_WS(next);
  1759. scan = next;
  1760. // Read the first integer in the set.
  1761. if ((*next < '0') || (*next > '9')) {
  1762. KMP_WARNING(AffSyntaxError, var);
  1763. return FALSE;
  1764. }
  1765. SKIP_DIGITS(next);
  1766. num = __kmp_str_to_int(scan, *next);
  1767. KMP_ASSERT(num >= 0);
  1768. for (;;) {
  1769. // Check for end of set.
  1770. SKIP_WS(next);
  1771. if (*next == '}') {
  1772. next++; // skip '}'
  1773. break;
  1774. }
  1775. // Skip optional comma.
  1776. if (*next == ',') {
  1777. next++;
  1778. }
  1779. SKIP_WS(next);
  1780. // Read the next integer in the set.
  1781. scan = next;
  1782. if ((*next < '0') || (*next > '9')) {
  1783. KMP_WARNING(AffSyntaxError, var);
  1784. return FALSE;
  1785. }
  1786. SKIP_DIGITS(next);
  1787. num = __kmp_str_to_int(scan, *next);
  1788. KMP_ASSERT(num >= 0);
  1789. }
  1790. empty = FALSE;
  1791. SKIP_WS(next);
  1792. if (*next == ',') {
  1793. next++;
  1794. }
  1795. scan = next;
  1796. continue;
  1797. }
  1798. // Next character is not an integer => end of list
  1799. if ((*next < '0') || (*next > '9')) {
  1800. if (empty) {
  1801. KMP_WARNING(AffSyntaxError, var);
  1802. return FALSE;
  1803. }
  1804. break;
  1805. }
  1806. // Read the first integer.
  1807. SKIP_DIGITS(next);
  1808. start = __kmp_str_to_int(scan, *next);
  1809. KMP_ASSERT(start >= 0);
  1810. SKIP_WS(next);
  1811. // If this isn't a range, then go on.
  1812. if (*next != '-') {
  1813. empty = FALSE;
  1814. // Skip optional comma.
  1815. if (*next == ',') {
  1816. next++;
  1817. }
  1818. scan = next;
  1819. continue;
  1820. }
  1821. // This is a range. Skip over the '-' and read in the 2nd int.
  1822. next++; // skip '-'
  1823. SKIP_WS(next);
  1824. scan = next;
  1825. if ((*next < '0') || (*next > '9')) {
  1826. KMP_WARNING(AffSyntaxError, var);
  1827. return FALSE;
  1828. }
  1829. SKIP_DIGITS(next);
  1830. end = __kmp_str_to_int(scan, *next);
  1831. KMP_ASSERT(end >= 0);
  1832. // Check for a stride parameter
  1833. stride = 1;
  1834. SKIP_WS(next);
  1835. if (*next == ':') {
  1836. // A stride is specified. Skip over the ':" and read the 3rd int.
  1837. int sign = +1;
  1838. next++; // skip ':'
  1839. SKIP_WS(next);
  1840. scan = next;
  1841. if (*next == '-') {
  1842. sign = -1;
  1843. next++;
  1844. SKIP_WS(next);
  1845. scan = next;
  1846. }
  1847. if ((*next < '0') || (*next > '9')) {
  1848. KMP_WARNING(AffSyntaxError, var);
  1849. return FALSE;
  1850. }
  1851. SKIP_DIGITS(next);
  1852. stride = __kmp_str_to_int(scan, *next);
  1853. KMP_ASSERT(stride >= 0);
  1854. stride *= sign;
  1855. }
  1856. // Do some range checks.
  1857. if (stride == 0) {
  1858. KMP_WARNING(AffZeroStride, var);
  1859. return FALSE;
  1860. }
  1861. if (stride > 0) {
  1862. if (start > end) {
  1863. KMP_WARNING(AffStartGreaterEnd, var, start, end);
  1864. return FALSE;
  1865. }
  1866. } else {
  1867. if (start < end) {
  1868. KMP_WARNING(AffStrideLessZero, var, start, end);
  1869. return FALSE;
  1870. }
  1871. }
  1872. if ((end - start) / stride > 65536) {
  1873. KMP_WARNING(AffRangeTooBig, var, end, start, stride);
  1874. return FALSE;
  1875. }
  1876. empty = FALSE;
  1877. // Skip optional comma.
  1878. SKIP_WS(next);
  1879. if (*next == ',') {
  1880. next++;
  1881. }
  1882. scan = next;
  1883. }
  1884. *nextEnv = next;
  1885. {
  1886. ptrdiff_t len = next - env;
  1887. char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
  1888. KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
  1889. retlist[len] = '\0';
  1890. *proclist = retlist;
  1891. }
  1892. return TRUE;
  1893. }
  1894. // If KMP_AFFINITY is specified without a type, then
  1895. // __kmp_affinity_notype should point to its setting.
  1896. static kmp_setting_t *__kmp_affinity_notype = NULL;
  1897. static void __kmp_parse_affinity_env(char const *name, char const *value,
  1898. enum affinity_type *out_type,
  1899. char **out_proclist, int *out_verbose,
  1900. int *out_warn, int *out_respect,
  1901. kmp_hw_t *out_gran, int *out_gran_levels,
  1902. int *out_dups, int *out_compact,
  1903. int *out_offset) {
  1904. char *buffer = NULL; // Copy of env var value.
  1905. char *buf = NULL; // Buffer for strtok_r() function.
  1906. char *next = NULL; // end of token / start of next.
  1907. const char *start; // start of current token (for err msgs)
  1908. int count = 0; // Counter of parsed integer numbers.
  1909. int number[2]; // Parsed numbers.
  1910. // Guards.
  1911. int type = 0;
  1912. int proclist = 0;
  1913. int verbose = 0;
  1914. int warnings = 0;
  1915. int respect = 0;
  1916. int gran = 0;
  1917. int dups = 0;
  1918. int reset = 0;
  1919. bool set = false;
  1920. KMP_ASSERT(value != NULL);
  1921. if (TCR_4(__kmp_init_middle)) {
  1922. KMP_WARNING(EnvMiddleWarn, name);
  1923. __kmp_env_toPrint(name, 0);
  1924. return;
  1925. }
  1926. __kmp_env_toPrint(name, 1);
  1927. buffer =
  1928. __kmp_str_format("%s", value); // Copy env var to keep original intact.
  1929. buf = buffer;
  1930. SKIP_WS(buf);
  1931. // Helper macros.
  1932. // If we see a parse error, emit a warning and scan to the next ",".
  1933. //
  1934. // FIXME - there's got to be a better way to print an error
  1935. // message, hopefully without overwriting peices of buf.
  1936. #define EMIT_WARN(skip, errlist) \
  1937. { \
  1938. char ch; \
  1939. if (skip) { \
  1940. SKIP_TO(next, ','); \
  1941. } \
  1942. ch = *next; \
  1943. *next = '\0'; \
  1944. KMP_WARNING errlist; \
  1945. *next = ch; \
  1946. if (skip) { \
  1947. if (ch == ',') \
  1948. next++; \
  1949. } \
  1950. buf = next; \
  1951. }
  1952. #define _set_param(_guard, _var, _val) \
  1953. { \
  1954. if (_guard == 0) { \
  1955. _var = _val; \
  1956. } else { \
  1957. EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
  1958. } \
  1959. ++_guard; \
  1960. }
  1961. #define set_type(val) _set_param(type, *out_type, val)
  1962. #define set_verbose(val) _set_param(verbose, *out_verbose, val)
  1963. #define set_warnings(val) _set_param(warnings, *out_warn, val)
  1964. #define set_respect(val) _set_param(respect, *out_respect, val)
  1965. #define set_dups(val) _set_param(dups, *out_dups, val)
  1966. #define set_proclist(val) _set_param(proclist, *out_proclist, val)
  1967. #define set_reset(val) _set_param(reset, __kmp_affin_reset, val)
  1968. #define set_gran(val, levels) \
  1969. { \
  1970. if (gran == 0) { \
  1971. *out_gran = val; \
  1972. *out_gran_levels = levels; \
  1973. } else { \
  1974. EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
  1975. } \
  1976. ++gran; \
  1977. }
  1978. KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
  1979. (__kmp_nested_proc_bind.used > 0));
  1980. while (*buf != '\0') {
  1981. start = next = buf;
  1982. if (__kmp_match_str("none", buf, CCAST(const char **, &next))) {
  1983. set_type(affinity_none);
  1984. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  1985. buf = next;
  1986. } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) {
  1987. set_type(affinity_scatter);
  1988. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  1989. buf = next;
  1990. } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) {
  1991. set_type(affinity_compact);
  1992. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  1993. buf = next;
  1994. } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) {
  1995. set_type(affinity_logical);
  1996. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  1997. buf = next;
  1998. } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) {
  1999. set_type(affinity_physical);
  2000. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  2001. buf = next;
  2002. } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) {
  2003. set_type(affinity_explicit);
  2004. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  2005. buf = next;
  2006. } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) {
  2007. set_type(affinity_balanced);
  2008. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  2009. buf = next;
  2010. } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) {
  2011. set_type(affinity_disabled);
  2012. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  2013. buf = next;
  2014. } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) {
  2015. set_verbose(TRUE);
  2016. buf = next;
  2017. } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) {
  2018. set_verbose(FALSE);
  2019. buf = next;
  2020. } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) {
  2021. set_warnings(TRUE);
  2022. buf = next;
  2023. } else if (__kmp_match_str("nowarnings", buf,
  2024. CCAST(const char **, &next))) {
  2025. set_warnings(FALSE);
  2026. buf = next;
  2027. } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) {
  2028. set_respect(TRUE);
  2029. buf = next;
  2030. } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) {
  2031. set_respect(FALSE);
  2032. buf = next;
  2033. } else if (__kmp_match_str("reset", buf, CCAST(const char **, &next))) {
  2034. set_reset(TRUE);
  2035. buf = next;
  2036. } else if (__kmp_match_str("noreset", buf, CCAST(const char **, &next))) {
  2037. set_reset(FALSE);
  2038. buf = next;
  2039. } else if (__kmp_match_str("duplicates", buf,
  2040. CCAST(const char **, &next)) ||
  2041. __kmp_match_str("dups", buf, CCAST(const char **, &next))) {
  2042. set_dups(TRUE);
  2043. buf = next;
  2044. } else if (__kmp_match_str("noduplicates", buf,
  2045. CCAST(const char **, &next)) ||
  2046. __kmp_match_str("nodups", buf, CCAST(const char **, &next))) {
  2047. set_dups(FALSE);
  2048. buf = next;
  2049. } else if (__kmp_match_str("granularity", buf,
  2050. CCAST(const char **, &next)) ||
  2051. __kmp_match_str("gran", buf, CCAST(const char **, &next))) {
  2052. SKIP_WS(next);
  2053. if (*next != '=') {
  2054. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2055. continue;
  2056. }
  2057. next++; // skip '='
  2058. SKIP_WS(next);
  2059. buf = next;
  2060. // Try any hardware topology type for granularity
  2061. KMP_FOREACH_HW_TYPE(type) {
  2062. const char *name = __kmp_hw_get_keyword(type);
  2063. if (__kmp_match_str(name, buf, CCAST(const char **, &next))) {
  2064. set_gran(type, -1);
  2065. buf = next;
  2066. set = true;
  2067. break;
  2068. }
  2069. }
  2070. if (!set) {
  2071. // Support older names for different granularity layers
  2072. if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) {
  2073. set_gran(KMP_HW_THREAD, -1);
  2074. buf = next;
  2075. set = true;
  2076. } else if (__kmp_match_str("package", buf,
  2077. CCAST(const char **, &next))) {
  2078. set_gran(KMP_HW_SOCKET, -1);
  2079. buf = next;
  2080. set = true;
  2081. } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) {
  2082. set_gran(KMP_HW_NUMA, -1);
  2083. buf = next;
  2084. set = true;
  2085. #if KMP_GROUP_AFFINITY
  2086. } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) {
  2087. set_gran(KMP_HW_PROC_GROUP, -1);
  2088. buf = next;
  2089. set = true;
  2090. #endif /* KMP_GROUP AFFINITY */
  2091. } else if ((*buf >= '0') && (*buf <= '9')) {
  2092. int n;
  2093. next = buf;
  2094. SKIP_DIGITS(next);
  2095. n = __kmp_str_to_int(buf, *next);
  2096. KMP_ASSERT(n >= 0);
  2097. buf = next;
  2098. set_gran(KMP_HW_UNKNOWN, n);
  2099. set = true;
  2100. } else {
  2101. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2102. continue;
  2103. }
  2104. }
  2105. } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) {
  2106. char *temp_proclist;
  2107. SKIP_WS(next);
  2108. if (*next != '=') {
  2109. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2110. continue;
  2111. }
  2112. next++; // skip '='
  2113. SKIP_WS(next);
  2114. if (*next != '[') {
  2115. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2116. continue;
  2117. }
  2118. next++; // skip '['
  2119. buf = next;
  2120. if (!__kmp_parse_affinity_proc_id_list(
  2121. name, buf, CCAST(const char **, &next), &temp_proclist)) {
  2122. // warning already emitted.
  2123. SKIP_TO(next, ']');
  2124. if (*next == ']')
  2125. next++;
  2126. SKIP_TO(next, ',');
  2127. if (*next == ',')
  2128. next++;
  2129. buf = next;
  2130. continue;
  2131. }
  2132. if (*next != ']') {
  2133. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2134. continue;
  2135. }
  2136. next++; // skip ']'
  2137. set_proclist(temp_proclist);
  2138. } else if ((*buf >= '0') && (*buf <= '9')) {
  2139. // Parse integer numbers -- permute and offset.
  2140. int n;
  2141. next = buf;
  2142. SKIP_DIGITS(next);
  2143. n = __kmp_str_to_int(buf, *next);
  2144. KMP_ASSERT(n >= 0);
  2145. buf = next;
  2146. if (count < 2) {
  2147. number[count] = n;
  2148. } else {
  2149. KMP_WARNING(AffManyParams, name, start);
  2150. }
  2151. ++count;
  2152. } else {
  2153. EMIT_WARN(TRUE, (AffInvalidParam, name, start));
  2154. continue;
  2155. }
  2156. SKIP_WS(next);
  2157. if (*next == ',') {
  2158. next++;
  2159. SKIP_WS(next);
  2160. } else if (*next != '\0') {
  2161. const char *temp = next;
  2162. EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp));
  2163. continue;
  2164. }
  2165. buf = next;
  2166. } // while
  2167. #undef EMIT_WARN
  2168. #undef _set_param
  2169. #undef set_type
  2170. #undef set_verbose
  2171. #undef set_warnings
  2172. #undef set_respect
  2173. #undef set_granularity
  2174. #undef set_reset
  2175. __kmp_str_free(&buffer);
  2176. if (proclist) {
  2177. if (!type) {
  2178. KMP_WARNING(AffProcListNoType, name);
  2179. *out_type = affinity_explicit;
  2180. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  2181. } else if (*out_type != affinity_explicit) {
  2182. KMP_WARNING(AffProcListNotExplicit, name);
  2183. KMP_ASSERT(*out_proclist != NULL);
  2184. KMP_INTERNAL_FREE(*out_proclist);
  2185. *out_proclist = NULL;
  2186. }
  2187. }
  2188. switch (*out_type) {
  2189. case affinity_logical:
  2190. case affinity_physical: {
  2191. if (count > 0) {
  2192. *out_offset = number[0];
  2193. }
  2194. if (count > 1) {
  2195. KMP_WARNING(AffManyParamsForLogic, name, number[1]);
  2196. }
  2197. } break;
  2198. case affinity_balanced: {
  2199. if (count > 0) {
  2200. *out_compact = number[0];
  2201. }
  2202. if (count > 1) {
  2203. *out_offset = number[1];
  2204. }
  2205. if (__kmp_affinity_gran == KMP_HW_UNKNOWN) {
  2206. #if KMP_MIC_SUPPORTED
  2207. if (__kmp_mic_type != non_mic) {
  2208. if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
  2209. KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "fine");
  2210. }
  2211. __kmp_affinity_gran = KMP_HW_THREAD;
  2212. } else
  2213. #endif
  2214. {
  2215. if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
  2216. KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "core");
  2217. }
  2218. __kmp_affinity_gran = KMP_HW_CORE;
  2219. }
  2220. }
  2221. } break;
  2222. case affinity_scatter:
  2223. case affinity_compact: {
  2224. if (count > 0) {
  2225. *out_compact = number[0];
  2226. }
  2227. if (count > 1) {
  2228. *out_offset = number[1];
  2229. }
  2230. } break;
  2231. case affinity_explicit: {
  2232. if (*out_proclist == NULL) {
  2233. KMP_WARNING(AffNoProcList, name);
  2234. __kmp_affinity_type = affinity_none;
  2235. }
  2236. if (count > 0) {
  2237. KMP_WARNING(AffNoParam, name, "explicit");
  2238. }
  2239. } break;
  2240. case affinity_none: {
  2241. if (count > 0) {
  2242. KMP_WARNING(AffNoParam, name, "none");
  2243. }
  2244. } break;
  2245. case affinity_disabled: {
  2246. if (count > 0) {
  2247. KMP_WARNING(AffNoParam, name, "disabled");
  2248. }
  2249. } break;
  2250. case affinity_default: {
  2251. if (count > 0) {
  2252. KMP_WARNING(AffNoParam, name, "default");
  2253. }
  2254. } break;
  2255. default: {
  2256. KMP_ASSERT(0);
  2257. }
  2258. }
  2259. } // __kmp_parse_affinity_env
  2260. static void __kmp_stg_parse_affinity(char const *name, char const *value,
  2261. void *data) {
  2262. kmp_setting_t **rivals = (kmp_setting_t **)data;
  2263. int rc;
  2264. rc = __kmp_stg_check_rivals(name, value, rivals);
  2265. if (rc) {
  2266. return;
  2267. }
  2268. __kmp_parse_affinity_env(name, value, &__kmp_affinity_type,
  2269. &__kmp_affinity_proclist, &__kmp_affinity_verbose,
  2270. &__kmp_affinity_warnings,
  2271. &__kmp_affinity_respect_mask, &__kmp_affinity_gran,
  2272. &__kmp_affinity_gran_levels, &__kmp_affinity_dups,
  2273. &__kmp_affinity_compact, &__kmp_affinity_offset);
  2274. } // __kmp_stg_parse_affinity
  2275. static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name,
  2276. void *data) {
  2277. if (__kmp_env_format) {
  2278. KMP_STR_BUF_PRINT_NAME_EX(name);
  2279. } else {
  2280. __kmp_str_buf_print(buffer, " %s='", name);
  2281. }
  2282. if (__kmp_affinity_verbose) {
  2283. __kmp_str_buf_print(buffer, "%s,", "verbose");
  2284. } else {
  2285. __kmp_str_buf_print(buffer, "%s,", "noverbose");
  2286. }
  2287. if (__kmp_affinity_warnings) {
  2288. __kmp_str_buf_print(buffer, "%s,", "warnings");
  2289. } else {
  2290. __kmp_str_buf_print(buffer, "%s,", "nowarnings");
  2291. }
  2292. if (KMP_AFFINITY_CAPABLE()) {
  2293. if (__kmp_affinity_respect_mask) {
  2294. __kmp_str_buf_print(buffer, "%s,", "respect");
  2295. } else {
  2296. __kmp_str_buf_print(buffer, "%s,", "norespect");
  2297. }
  2298. if (__kmp_affin_reset) {
  2299. __kmp_str_buf_print(buffer, "%s,", "reset");
  2300. } else {
  2301. __kmp_str_buf_print(buffer, "%s,", "noreset");
  2302. }
  2303. __kmp_str_buf_print(buffer, "granularity=%s,",
  2304. __kmp_hw_get_keyword(__kmp_affinity_gran, false));
  2305. }
  2306. if (!KMP_AFFINITY_CAPABLE()) {
  2307. __kmp_str_buf_print(buffer, "%s", "disabled");
  2308. } else
  2309. switch (__kmp_affinity_type) {
  2310. case affinity_none:
  2311. __kmp_str_buf_print(buffer, "%s", "none");
  2312. break;
  2313. case affinity_physical:
  2314. __kmp_str_buf_print(buffer, "%s,%d", "physical", __kmp_affinity_offset);
  2315. break;
  2316. case affinity_logical:
  2317. __kmp_str_buf_print(buffer, "%s,%d", "logical", __kmp_affinity_offset);
  2318. break;
  2319. case affinity_compact:
  2320. __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", __kmp_affinity_compact,
  2321. __kmp_affinity_offset);
  2322. break;
  2323. case affinity_scatter:
  2324. __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", __kmp_affinity_compact,
  2325. __kmp_affinity_offset);
  2326. break;
  2327. case affinity_explicit:
  2328. __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist",
  2329. __kmp_affinity_proclist, "explicit");
  2330. break;
  2331. case affinity_balanced:
  2332. __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced",
  2333. __kmp_affinity_compact, __kmp_affinity_offset);
  2334. break;
  2335. case affinity_disabled:
  2336. __kmp_str_buf_print(buffer, "%s", "disabled");
  2337. break;
  2338. case affinity_default:
  2339. __kmp_str_buf_print(buffer, "%s", "default");
  2340. break;
  2341. default:
  2342. __kmp_str_buf_print(buffer, "%s", "<unknown>");
  2343. break;
  2344. }
  2345. __kmp_str_buf_print(buffer, "'\n");
  2346. } //__kmp_stg_print_affinity
  2347. #ifdef KMP_GOMP_COMPAT
  2348. static void __kmp_stg_parse_gomp_cpu_affinity(char const *name,
  2349. char const *value, void *data) {
  2350. const char *next = NULL;
  2351. char *temp_proclist;
  2352. kmp_setting_t **rivals = (kmp_setting_t **)data;
  2353. int rc;
  2354. rc = __kmp_stg_check_rivals(name, value, rivals);
  2355. if (rc) {
  2356. return;
  2357. }
  2358. if (TCR_4(__kmp_init_middle)) {
  2359. KMP_WARNING(EnvMiddleWarn, name);
  2360. __kmp_env_toPrint(name, 0);
  2361. return;
  2362. }
  2363. __kmp_env_toPrint(name, 1);
  2364. if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) {
  2365. SKIP_WS(next);
  2366. if (*next == '\0') {
  2367. // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
  2368. __kmp_affinity_proclist = temp_proclist;
  2369. __kmp_affinity_type = affinity_explicit;
  2370. __kmp_affinity_gran = KMP_HW_THREAD;
  2371. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  2372. } else {
  2373. KMP_WARNING(AffSyntaxError, name);
  2374. if (temp_proclist != NULL) {
  2375. KMP_INTERNAL_FREE((void *)temp_proclist);
  2376. }
  2377. }
  2378. } else {
  2379. // Warning already emitted
  2380. __kmp_affinity_type = affinity_none;
  2381. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  2382. }
  2383. } // __kmp_stg_parse_gomp_cpu_affinity
  2384. #endif /* KMP_GOMP_COMPAT */
  2385. /*-----------------------------------------------------------------------------
  2386. The OMP_PLACES proc id list parser. Here is the grammar:
  2387. place_list := place
  2388. place_list := place , place_list
  2389. place := num
  2390. place := place : num
  2391. place := place : num : signed
  2392. place := { subplacelist }
  2393. place := ! place // (lowest priority)
  2394. subplace_list := subplace
  2395. subplace_list := subplace , subplace_list
  2396. subplace := num
  2397. subplace := num : num
  2398. subplace := num : num : signed
  2399. signed := num
  2400. signed := + signed
  2401. signed := - signed
  2402. -----------------------------------------------------------------------------*/
  2403. // Warning to issue for syntax error during parsing of OMP_PLACES
  2404. static inline void __kmp_omp_places_syntax_warn(const char *var) {
  2405. KMP_WARNING(SyntaxErrorUsing, var, "\"cores\"");
  2406. }
  2407. static int __kmp_parse_subplace_list(const char *var, const char **scan) {
  2408. const char *next;
  2409. for (;;) {
  2410. int start, count, stride;
  2411. //
  2412. // Read in the starting proc id
  2413. //
  2414. SKIP_WS(*scan);
  2415. if ((**scan < '0') || (**scan > '9')) {
  2416. __kmp_omp_places_syntax_warn(var);
  2417. return FALSE;
  2418. }
  2419. next = *scan;
  2420. SKIP_DIGITS(next);
  2421. start = __kmp_str_to_int(*scan, *next);
  2422. KMP_ASSERT(start >= 0);
  2423. *scan = next;
  2424. // valid follow sets are ',' ':' and '}'
  2425. SKIP_WS(*scan);
  2426. if (**scan == '}') {
  2427. break;
  2428. }
  2429. if (**scan == ',') {
  2430. (*scan)++; // skip ','
  2431. continue;
  2432. }
  2433. if (**scan != ':') {
  2434. __kmp_omp_places_syntax_warn(var);
  2435. return FALSE;
  2436. }
  2437. (*scan)++; // skip ':'
  2438. // Read count parameter
  2439. SKIP_WS(*scan);
  2440. if ((**scan < '0') || (**scan > '9')) {
  2441. __kmp_omp_places_syntax_warn(var);
  2442. return FALSE;
  2443. }
  2444. next = *scan;
  2445. SKIP_DIGITS(next);
  2446. count = __kmp_str_to_int(*scan, *next);
  2447. KMP_ASSERT(count >= 0);
  2448. *scan = next;
  2449. // valid follow sets are ',' ':' and '}'
  2450. SKIP_WS(*scan);
  2451. if (**scan == '}') {
  2452. break;
  2453. }
  2454. if (**scan == ',') {
  2455. (*scan)++; // skip ','
  2456. continue;
  2457. }
  2458. if (**scan != ':') {
  2459. __kmp_omp_places_syntax_warn(var);
  2460. return FALSE;
  2461. }
  2462. (*scan)++; // skip ':'
  2463. // Read stride parameter
  2464. int sign = +1;
  2465. for (;;) {
  2466. SKIP_WS(*scan);
  2467. if (**scan == '+') {
  2468. (*scan)++; // skip '+'
  2469. continue;
  2470. }
  2471. if (**scan == '-') {
  2472. sign *= -1;
  2473. (*scan)++; // skip '-'
  2474. continue;
  2475. }
  2476. break;
  2477. }
  2478. SKIP_WS(*scan);
  2479. if ((**scan < '0') || (**scan > '9')) {
  2480. __kmp_omp_places_syntax_warn(var);
  2481. return FALSE;
  2482. }
  2483. next = *scan;
  2484. SKIP_DIGITS(next);
  2485. stride = __kmp_str_to_int(*scan, *next);
  2486. KMP_ASSERT(stride >= 0);
  2487. *scan = next;
  2488. stride *= sign;
  2489. // valid follow sets are ',' and '}'
  2490. SKIP_WS(*scan);
  2491. if (**scan == '}') {
  2492. break;
  2493. }
  2494. if (**scan == ',') {
  2495. (*scan)++; // skip ','
  2496. continue;
  2497. }
  2498. __kmp_omp_places_syntax_warn(var);
  2499. return FALSE;
  2500. }
  2501. return TRUE;
  2502. }
  2503. static int __kmp_parse_place(const char *var, const char **scan) {
  2504. const char *next;
  2505. // valid follow sets are '{' '!' and num
  2506. SKIP_WS(*scan);
  2507. if (**scan == '{') {
  2508. (*scan)++; // skip '{'
  2509. if (!__kmp_parse_subplace_list(var, scan)) {
  2510. return FALSE;
  2511. }
  2512. if (**scan != '}') {
  2513. __kmp_omp_places_syntax_warn(var);
  2514. return FALSE;
  2515. }
  2516. (*scan)++; // skip '}'
  2517. } else if (**scan == '!') {
  2518. (*scan)++; // skip '!'
  2519. return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'
  2520. } else if ((**scan >= '0') && (**scan <= '9')) {
  2521. next = *scan;
  2522. SKIP_DIGITS(next);
  2523. int proc = __kmp_str_to_int(*scan, *next);
  2524. KMP_ASSERT(proc >= 0);
  2525. *scan = next;
  2526. } else {
  2527. __kmp_omp_places_syntax_warn(var);
  2528. return FALSE;
  2529. }
  2530. return TRUE;
  2531. }
  2532. static int __kmp_parse_place_list(const char *var, const char *env,
  2533. char **place_list) {
  2534. const char *scan = env;
  2535. const char *next = scan;
  2536. for (;;) {
  2537. int count, stride;
  2538. if (!__kmp_parse_place(var, &scan)) {
  2539. return FALSE;
  2540. }
  2541. // valid follow sets are ',' ':' and EOL
  2542. SKIP_WS(scan);
  2543. if (*scan == '\0') {
  2544. break;
  2545. }
  2546. if (*scan == ',') {
  2547. scan++; // skip ','
  2548. continue;
  2549. }
  2550. if (*scan != ':') {
  2551. __kmp_omp_places_syntax_warn(var);
  2552. return FALSE;
  2553. }
  2554. scan++; // skip ':'
  2555. // Read count parameter
  2556. SKIP_WS(scan);
  2557. if ((*scan < '0') || (*scan > '9')) {
  2558. __kmp_omp_places_syntax_warn(var);
  2559. return FALSE;
  2560. }
  2561. next = scan;
  2562. SKIP_DIGITS(next);
  2563. count = __kmp_str_to_int(scan, *next);
  2564. KMP_ASSERT(count >= 0);
  2565. scan = next;
  2566. // valid follow sets are ',' ':' and EOL
  2567. SKIP_WS(scan);
  2568. if (*scan == '\0') {
  2569. break;
  2570. }
  2571. if (*scan == ',') {
  2572. scan++; // skip ','
  2573. continue;
  2574. }
  2575. if (*scan != ':') {
  2576. __kmp_omp_places_syntax_warn(var);
  2577. return FALSE;
  2578. }
  2579. scan++; // skip ':'
  2580. // Read stride parameter
  2581. int sign = +1;
  2582. for (;;) {
  2583. SKIP_WS(scan);
  2584. if (*scan == '+') {
  2585. scan++; // skip '+'
  2586. continue;
  2587. }
  2588. if (*scan == '-') {
  2589. sign *= -1;
  2590. scan++; // skip '-'
  2591. continue;
  2592. }
  2593. break;
  2594. }
  2595. SKIP_WS(scan);
  2596. if ((*scan < '0') || (*scan > '9')) {
  2597. __kmp_omp_places_syntax_warn(var);
  2598. return FALSE;
  2599. }
  2600. next = scan;
  2601. SKIP_DIGITS(next);
  2602. stride = __kmp_str_to_int(scan, *next);
  2603. KMP_ASSERT(stride >= 0);
  2604. scan = next;
  2605. stride *= sign;
  2606. // valid follow sets are ',' and EOL
  2607. SKIP_WS(scan);
  2608. if (*scan == '\0') {
  2609. break;
  2610. }
  2611. if (*scan == ',') {
  2612. scan++; // skip ','
  2613. continue;
  2614. }
  2615. __kmp_omp_places_syntax_warn(var);
  2616. return FALSE;
  2617. }
  2618. {
  2619. ptrdiff_t len = scan - env;
  2620. char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
  2621. KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
  2622. retlist[len] = '\0';
  2623. *place_list = retlist;
  2624. }
  2625. return TRUE;
  2626. }
  2627. static void __kmp_stg_parse_places(char const *name, char const *value,
  2628. void *data) {
  2629. struct kmp_place_t {
  2630. const char *name;
  2631. kmp_hw_t type;
  2632. };
  2633. int count;
  2634. bool set = false;
  2635. const char *scan = value;
  2636. const char *next = scan;
  2637. const char *kind = "\"threads\"";
  2638. kmp_place_t std_places[] = {{"threads", KMP_HW_THREAD},
  2639. {"cores", KMP_HW_CORE},
  2640. {"numa_domains", KMP_HW_NUMA},
  2641. {"ll_caches", KMP_HW_LLC},
  2642. {"sockets", KMP_HW_SOCKET}};
  2643. kmp_setting_t **rivals = (kmp_setting_t **)data;
  2644. int rc;
  2645. rc = __kmp_stg_check_rivals(name, value, rivals);
  2646. if (rc) {
  2647. return;
  2648. }
  2649. // Standard choices
  2650. for (size_t i = 0; i < sizeof(std_places) / sizeof(std_places[0]); ++i) {
  2651. const kmp_place_t &place = std_places[i];
  2652. if (__kmp_match_str(place.name, scan, &next)) {
  2653. scan = next;
  2654. __kmp_affinity_type = affinity_compact;
  2655. __kmp_affinity_gran = place.type;
  2656. __kmp_affinity_dups = FALSE;
  2657. set = true;
  2658. break;
  2659. }
  2660. }
  2661. // Implementation choices for OMP_PLACES based on internal types
  2662. if (!set) {
  2663. KMP_FOREACH_HW_TYPE(type) {
  2664. const char *name = __kmp_hw_get_keyword(type, true);
  2665. if (__kmp_match_str("unknowns", scan, &next))
  2666. continue;
  2667. if (__kmp_match_str(name, scan, &next)) {
  2668. scan = next;
  2669. __kmp_affinity_type = affinity_compact;
  2670. __kmp_affinity_gran = type;
  2671. __kmp_affinity_dups = FALSE;
  2672. set = true;
  2673. break;
  2674. }
  2675. }
  2676. }
  2677. if (!set) {
  2678. if (__kmp_affinity_proclist != NULL) {
  2679. KMP_INTERNAL_FREE((void *)__kmp_affinity_proclist);
  2680. __kmp_affinity_proclist = NULL;
  2681. }
  2682. if (__kmp_parse_place_list(name, value, &__kmp_affinity_proclist)) {
  2683. __kmp_affinity_type = affinity_explicit;
  2684. __kmp_affinity_gran = KMP_HW_THREAD;
  2685. __kmp_affinity_dups = FALSE;
  2686. } else {
  2687. // Syntax error fallback
  2688. __kmp_affinity_type = affinity_compact;
  2689. __kmp_affinity_gran = KMP_HW_CORE;
  2690. __kmp_affinity_dups = FALSE;
  2691. }
  2692. if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
  2693. __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
  2694. }
  2695. return;
  2696. }
  2697. if (__kmp_affinity_gran != KMP_HW_UNKNOWN) {
  2698. kind = __kmp_hw_get_keyword(__kmp_affinity_gran);
  2699. }
  2700. if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
  2701. __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
  2702. }
  2703. SKIP_WS(scan);
  2704. if (*scan == '\0') {
  2705. return;
  2706. }
  2707. // Parse option count parameter in parentheses
  2708. if (*scan != '(') {
  2709. KMP_WARNING(SyntaxErrorUsing, name, kind);
  2710. return;
  2711. }
  2712. scan++; // skip '('
  2713. SKIP_WS(scan);
  2714. next = scan;
  2715. SKIP_DIGITS(next);
  2716. count = __kmp_str_to_int(scan, *next);
  2717. KMP_ASSERT(count >= 0);
  2718. scan = next;
  2719. SKIP_WS(scan);
  2720. if (*scan != ')') {
  2721. KMP_WARNING(SyntaxErrorUsing, name, kind);
  2722. return;
  2723. }
  2724. scan++; // skip ')'
  2725. SKIP_WS(scan);
  2726. if (*scan != '\0') {
  2727. KMP_WARNING(ParseExtraCharsWarn, name, scan);
  2728. }
  2729. __kmp_affinity_num_places = count;
  2730. }
  2731. static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name,
  2732. void *data) {
  2733. if (__kmp_env_format) {
  2734. KMP_STR_BUF_PRINT_NAME;
  2735. } else {
  2736. __kmp_str_buf_print(buffer, " %s", name);
  2737. }
  2738. if ((__kmp_nested_proc_bind.used == 0) ||
  2739. (__kmp_nested_proc_bind.bind_types == NULL) ||
  2740. (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) {
  2741. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  2742. } else if (__kmp_affinity_type == affinity_explicit) {
  2743. if (__kmp_affinity_proclist != NULL) {
  2744. __kmp_str_buf_print(buffer, "='%s'\n", __kmp_affinity_proclist);
  2745. } else {
  2746. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  2747. }
  2748. } else if (__kmp_affinity_type == affinity_compact) {
  2749. int num;
  2750. if (__kmp_affinity_num_masks > 0) {
  2751. num = __kmp_affinity_num_masks;
  2752. } else if (__kmp_affinity_num_places > 0) {
  2753. num = __kmp_affinity_num_places;
  2754. } else {
  2755. num = 0;
  2756. }
  2757. if (__kmp_affinity_gran != KMP_HW_UNKNOWN) {
  2758. const char *name = __kmp_hw_get_keyword(__kmp_affinity_gran, true);
  2759. if (num > 0) {
  2760. __kmp_str_buf_print(buffer, "='%s(%d)'\n", name, num);
  2761. } else {
  2762. __kmp_str_buf_print(buffer, "='%s'\n", name);
  2763. }
  2764. } else {
  2765. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  2766. }
  2767. } else {
  2768. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  2769. }
  2770. }
  2771. static void __kmp_stg_parse_topology_method(char const *name, char const *value,
  2772. void *data) {
  2773. if (__kmp_str_match("all", 1, value)) {
  2774. __kmp_affinity_top_method = affinity_top_method_all;
  2775. }
  2776. #if KMP_USE_HWLOC
  2777. else if (__kmp_str_match("hwloc", 1, value)) {
  2778. __kmp_affinity_top_method = affinity_top_method_hwloc;
  2779. }
  2780. #endif
  2781. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  2782. else if (__kmp_str_match("cpuid_leaf31", 12, value) ||
  2783. __kmp_str_match("cpuid 1f", 8, value) ||
  2784. __kmp_str_match("cpuid 31", 8, value) ||
  2785. __kmp_str_match("cpuid1f", 7, value) ||
  2786. __kmp_str_match("cpuid31", 7, value) ||
  2787. __kmp_str_match("leaf 1f", 7, value) ||
  2788. __kmp_str_match("leaf 31", 7, value) ||
  2789. __kmp_str_match("leaf1f", 6, value) ||
  2790. __kmp_str_match("leaf31", 6, value)) {
  2791. __kmp_affinity_top_method = affinity_top_method_x2apicid_1f;
  2792. } else if (__kmp_str_match("x2apic id", 9, value) ||
  2793. __kmp_str_match("x2apic_id", 9, value) ||
  2794. __kmp_str_match("x2apic-id", 9, value) ||
  2795. __kmp_str_match("x2apicid", 8, value) ||
  2796. __kmp_str_match("cpuid leaf 11", 13, value) ||
  2797. __kmp_str_match("cpuid_leaf_11", 13, value) ||
  2798. __kmp_str_match("cpuid-leaf-11", 13, value) ||
  2799. __kmp_str_match("cpuid leaf11", 12, value) ||
  2800. __kmp_str_match("cpuid_leaf11", 12, value) ||
  2801. __kmp_str_match("cpuid-leaf11", 12, value) ||
  2802. __kmp_str_match("cpuidleaf 11", 12, value) ||
  2803. __kmp_str_match("cpuidleaf_11", 12, value) ||
  2804. __kmp_str_match("cpuidleaf-11", 12, value) ||
  2805. __kmp_str_match("cpuidleaf11", 11, value) ||
  2806. __kmp_str_match("cpuid 11", 8, value) ||
  2807. __kmp_str_match("cpuid_11", 8, value) ||
  2808. __kmp_str_match("cpuid-11", 8, value) ||
  2809. __kmp_str_match("cpuid11", 7, value) ||
  2810. __kmp_str_match("leaf 11", 7, value) ||
  2811. __kmp_str_match("leaf_11", 7, value) ||
  2812. __kmp_str_match("leaf-11", 7, value) ||
  2813. __kmp_str_match("leaf11", 6, value)) {
  2814. __kmp_affinity_top_method = affinity_top_method_x2apicid;
  2815. } else if (__kmp_str_match("apic id", 7, value) ||
  2816. __kmp_str_match("apic_id", 7, value) ||
  2817. __kmp_str_match("apic-id", 7, value) ||
  2818. __kmp_str_match("apicid", 6, value) ||
  2819. __kmp_str_match("cpuid leaf 4", 12, value) ||
  2820. __kmp_str_match("cpuid_leaf_4", 12, value) ||
  2821. __kmp_str_match("cpuid-leaf-4", 12, value) ||
  2822. __kmp_str_match("cpuid leaf4", 11, value) ||
  2823. __kmp_str_match("cpuid_leaf4", 11, value) ||
  2824. __kmp_str_match("cpuid-leaf4", 11, value) ||
  2825. __kmp_str_match("cpuidleaf 4", 11, value) ||
  2826. __kmp_str_match("cpuidleaf_4", 11, value) ||
  2827. __kmp_str_match("cpuidleaf-4", 11, value) ||
  2828. __kmp_str_match("cpuidleaf4", 10, value) ||
  2829. __kmp_str_match("cpuid 4", 7, value) ||
  2830. __kmp_str_match("cpuid_4", 7, value) ||
  2831. __kmp_str_match("cpuid-4", 7, value) ||
  2832. __kmp_str_match("cpuid4", 6, value) ||
  2833. __kmp_str_match("leaf 4", 6, value) ||
  2834. __kmp_str_match("leaf_4", 6, value) ||
  2835. __kmp_str_match("leaf-4", 6, value) ||
  2836. __kmp_str_match("leaf4", 5, value)) {
  2837. __kmp_affinity_top_method = affinity_top_method_apicid;
  2838. }
  2839. #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
  2840. else if (__kmp_str_match("/proc/cpuinfo", 2, value) ||
  2841. __kmp_str_match("cpuinfo", 5, value)) {
  2842. __kmp_affinity_top_method = affinity_top_method_cpuinfo;
  2843. }
  2844. #if KMP_GROUP_AFFINITY
  2845. else if (__kmp_str_match("group", 1, value)) {
  2846. KMP_WARNING(StgDeprecatedValue, name, value, "all");
  2847. __kmp_affinity_top_method = affinity_top_method_group;
  2848. }
  2849. #endif /* KMP_GROUP_AFFINITY */
  2850. else if (__kmp_str_match("flat", 1, value)) {
  2851. __kmp_affinity_top_method = affinity_top_method_flat;
  2852. } else {
  2853. KMP_WARNING(StgInvalidValue, name, value);
  2854. }
  2855. } // __kmp_stg_parse_topology_method
  2856. static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer,
  2857. char const *name, void *data) {
  2858. char const *value = NULL;
  2859. switch (__kmp_affinity_top_method) {
  2860. case affinity_top_method_default:
  2861. value = "default";
  2862. break;
  2863. case affinity_top_method_all:
  2864. value = "all";
  2865. break;
  2866. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  2867. case affinity_top_method_x2apicid_1f:
  2868. value = "x2APIC id leaf 0x1f";
  2869. break;
  2870. case affinity_top_method_x2apicid:
  2871. value = "x2APIC id leaf 0xb";
  2872. break;
  2873. case affinity_top_method_apicid:
  2874. value = "APIC id";
  2875. break;
  2876. #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
  2877. #if KMP_USE_HWLOC
  2878. case affinity_top_method_hwloc:
  2879. value = "hwloc";
  2880. break;
  2881. #endif
  2882. case affinity_top_method_cpuinfo:
  2883. value = "cpuinfo";
  2884. break;
  2885. #if KMP_GROUP_AFFINITY
  2886. case affinity_top_method_group:
  2887. value = "group";
  2888. break;
  2889. #endif /* KMP_GROUP_AFFINITY */
  2890. case affinity_top_method_flat:
  2891. value = "flat";
  2892. break;
  2893. }
  2894. if (value != NULL) {
  2895. __kmp_stg_print_str(buffer, name, value);
  2896. }
  2897. } // __kmp_stg_print_topology_method
  2898. // KMP_TEAMS_PROC_BIND
  2899. struct kmp_proc_bind_info_t {
  2900. const char *name;
  2901. kmp_proc_bind_t proc_bind;
  2902. };
  2903. static kmp_proc_bind_info_t proc_bind_table[] = {
  2904. {"spread", proc_bind_spread},
  2905. {"true", proc_bind_spread},
  2906. {"close", proc_bind_close},
  2907. // teams-bind = false means "replicate the primary thread's affinity"
  2908. {"false", proc_bind_primary},
  2909. {"primary", proc_bind_primary}};
  2910. static void __kmp_stg_parse_teams_proc_bind(char const *name, char const *value,
  2911. void *data) {
  2912. int valid;
  2913. const char *end;
  2914. valid = 0;
  2915. for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);
  2916. ++i) {
  2917. if (__kmp_match_str(proc_bind_table[i].name, value, &end)) {
  2918. __kmp_teams_proc_bind = proc_bind_table[i].proc_bind;
  2919. valid = 1;
  2920. break;
  2921. }
  2922. }
  2923. if (!valid) {
  2924. KMP_WARNING(StgInvalidValue, name, value);
  2925. }
  2926. }
  2927. static void __kmp_stg_print_teams_proc_bind(kmp_str_buf_t *buffer,
  2928. char const *name, void *data) {
  2929. const char *value = KMP_I18N_STR(NotDefined);
  2930. for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);
  2931. ++i) {
  2932. if (__kmp_teams_proc_bind == proc_bind_table[i].proc_bind) {
  2933. value = proc_bind_table[i].name;
  2934. break;
  2935. }
  2936. }
  2937. __kmp_stg_print_str(buffer, name, value);
  2938. }
  2939. #endif /* KMP_AFFINITY_SUPPORTED */
  2940. // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
  2941. // OMP_PLACES / place-partition-var is not.
  2942. static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
  2943. void *data) {
  2944. kmp_setting_t **rivals = (kmp_setting_t **)data;
  2945. int rc;
  2946. rc = __kmp_stg_check_rivals(name, value, rivals);
  2947. if (rc) {
  2948. return;
  2949. }
  2950. // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
  2951. KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
  2952. (__kmp_nested_proc_bind.used > 0));
  2953. const char *buf = value;
  2954. const char *next;
  2955. int num;
  2956. SKIP_WS(buf);
  2957. if ((*buf >= '0') && (*buf <= '9')) {
  2958. next = buf;
  2959. SKIP_DIGITS(next);
  2960. num = __kmp_str_to_int(buf, *next);
  2961. KMP_ASSERT(num >= 0);
  2962. buf = next;
  2963. SKIP_WS(buf);
  2964. } else {
  2965. num = -1;
  2966. }
  2967. next = buf;
  2968. if (__kmp_match_str("disabled", buf, &next)) {
  2969. buf = next;
  2970. SKIP_WS(buf);
  2971. #if KMP_AFFINITY_SUPPORTED
  2972. __kmp_affinity_type = affinity_disabled;
  2973. #endif /* KMP_AFFINITY_SUPPORTED */
  2974. __kmp_nested_proc_bind.used = 1;
  2975. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  2976. } else if ((num == (int)proc_bind_false) ||
  2977. __kmp_match_str("false", buf, &next)) {
  2978. buf = next;
  2979. SKIP_WS(buf);
  2980. #if KMP_AFFINITY_SUPPORTED
  2981. __kmp_affinity_type = affinity_none;
  2982. #endif /* KMP_AFFINITY_SUPPORTED */
  2983. __kmp_nested_proc_bind.used = 1;
  2984. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  2985. } else if ((num == (int)proc_bind_true) ||
  2986. __kmp_match_str("true", buf, &next)) {
  2987. buf = next;
  2988. SKIP_WS(buf);
  2989. __kmp_nested_proc_bind.used = 1;
  2990. __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
  2991. } else {
  2992. // Count the number of values in the env var string
  2993. const char *scan;
  2994. int nelem = 1;
  2995. for (scan = buf; *scan != '\0'; scan++) {
  2996. if (*scan == ',') {
  2997. nelem++;
  2998. }
  2999. }
  3000. // Create / expand the nested proc_bind array as needed
  3001. if (__kmp_nested_proc_bind.size < nelem) {
  3002. __kmp_nested_proc_bind.bind_types =
  3003. (kmp_proc_bind_t *)KMP_INTERNAL_REALLOC(
  3004. __kmp_nested_proc_bind.bind_types,
  3005. sizeof(kmp_proc_bind_t) * nelem);
  3006. if (__kmp_nested_proc_bind.bind_types == NULL) {
  3007. KMP_FATAL(MemoryAllocFailed);
  3008. }
  3009. __kmp_nested_proc_bind.size = nelem;
  3010. }
  3011. __kmp_nested_proc_bind.used = nelem;
  3012. if (nelem > 1 && !__kmp_dflt_max_active_levels_set)
  3013. __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;
  3014. // Save values in the nested proc_bind array
  3015. int i = 0;
  3016. for (;;) {
  3017. enum kmp_proc_bind_t bind;
  3018. if ((num == (int)proc_bind_primary) ||
  3019. __kmp_match_str("master", buf, &next) ||
  3020. __kmp_match_str("primary", buf, &next)) {
  3021. buf = next;
  3022. SKIP_WS(buf);
  3023. bind = proc_bind_primary;
  3024. } else if ((num == (int)proc_bind_close) ||
  3025. __kmp_match_str("close", buf, &next)) {
  3026. buf = next;
  3027. SKIP_WS(buf);
  3028. bind = proc_bind_close;
  3029. } else if ((num == (int)proc_bind_spread) ||
  3030. __kmp_match_str("spread", buf, &next)) {
  3031. buf = next;
  3032. SKIP_WS(buf);
  3033. bind = proc_bind_spread;
  3034. } else {
  3035. KMP_WARNING(StgInvalidValue, name, value);
  3036. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  3037. __kmp_nested_proc_bind.used = 1;
  3038. return;
  3039. }
  3040. __kmp_nested_proc_bind.bind_types[i++] = bind;
  3041. if (i >= nelem) {
  3042. break;
  3043. }
  3044. KMP_DEBUG_ASSERT(*buf == ',');
  3045. buf++;
  3046. SKIP_WS(buf);
  3047. // Read next value if it was specified as an integer
  3048. if ((*buf >= '0') && (*buf <= '9')) {
  3049. next = buf;
  3050. SKIP_DIGITS(next);
  3051. num = __kmp_str_to_int(buf, *next);
  3052. KMP_ASSERT(num >= 0);
  3053. buf = next;
  3054. SKIP_WS(buf);
  3055. } else {
  3056. num = -1;
  3057. }
  3058. }
  3059. SKIP_WS(buf);
  3060. }
  3061. if (*buf != '\0') {
  3062. KMP_WARNING(ParseExtraCharsWarn, name, buf);
  3063. }
  3064. }
  3065. static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name,
  3066. void *data) {
  3067. int nelem = __kmp_nested_proc_bind.used;
  3068. if (__kmp_env_format) {
  3069. KMP_STR_BUF_PRINT_NAME;
  3070. } else {
  3071. __kmp_str_buf_print(buffer, " %s", name);
  3072. }
  3073. if (nelem == 0) {
  3074. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  3075. } else {
  3076. int i;
  3077. __kmp_str_buf_print(buffer, "='", name);
  3078. for (i = 0; i < nelem; i++) {
  3079. switch (__kmp_nested_proc_bind.bind_types[i]) {
  3080. case proc_bind_false:
  3081. __kmp_str_buf_print(buffer, "false");
  3082. break;
  3083. case proc_bind_true:
  3084. __kmp_str_buf_print(buffer, "true");
  3085. break;
  3086. case proc_bind_primary:
  3087. __kmp_str_buf_print(buffer, "primary");
  3088. break;
  3089. case proc_bind_close:
  3090. __kmp_str_buf_print(buffer, "close");
  3091. break;
  3092. case proc_bind_spread:
  3093. __kmp_str_buf_print(buffer, "spread");
  3094. break;
  3095. case proc_bind_intel:
  3096. __kmp_str_buf_print(buffer, "intel");
  3097. break;
  3098. case proc_bind_default:
  3099. __kmp_str_buf_print(buffer, "default");
  3100. break;
  3101. }
  3102. if (i < nelem - 1) {
  3103. __kmp_str_buf_print(buffer, ",");
  3104. }
  3105. }
  3106. __kmp_str_buf_print(buffer, "'\n");
  3107. }
  3108. }
  3109. static void __kmp_stg_parse_display_affinity(char const *name,
  3110. char const *value, void *data) {
  3111. __kmp_stg_parse_bool(name, value, &__kmp_display_affinity);
  3112. }
  3113. static void __kmp_stg_print_display_affinity(kmp_str_buf_t *buffer,
  3114. char const *name, void *data) {
  3115. __kmp_stg_print_bool(buffer, name, __kmp_display_affinity);
  3116. }
  3117. static void __kmp_stg_parse_affinity_format(char const *name, char const *value,
  3118. void *data) {
  3119. size_t length = KMP_STRLEN(value);
  3120. __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, value,
  3121. length);
  3122. }
  3123. static void __kmp_stg_print_affinity_format(kmp_str_buf_t *buffer,
  3124. char const *name, void *data) {
  3125. if (__kmp_env_format) {
  3126. KMP_STR_BUF_PRINT_NAME_EX(name);
  3127. } else {
  3128. __kmp_str_buf_print(buffer, " %s='", name);
  3129. }
  3130. __kmp_str_buf_print(buffer, "%s'\n", __kmp_affinity_format);
  3131. }
  3132. /*-----------------------------------------------------------------------------
  3133. OMP_ALLOCATOR sets default allocator. Here is the grammar:
  3134. <allocator> |= <predef-allocator> | <predef-mem-space> |
  3135. <predef-mem-space>:<traits>
  3136. <traits> |= <trait>=<value> | <trait>=<value>,<traits>
  3137. <predef-allocator> |= omp_default_mem_alloc | omp_large_cap_mem_alloc |
  3138. omp_const_mem_alloc | omp_high_bw_mem_alloc |
  3139. omp_low_lat_mem_alloc | omp_cgroup_mem_alloc |
  3140. omp_pteam_mem_alloc | omp_thread_mem_alloc
  3141. <predef-mem-space> |= omp_default_mem_space | omp_large_cap_mem_space |
  3142. omp_const_mem_space | omp_high_bw_mem_space |
  3143. omp_low_lat_mem_space
  3144. <trait> |= sync_hint | alignment | access | pool_size | fallback |
  3145. fb_data | pinned | partition
  3146. <value> |= one of the allowed values of trait |
  3147. non-negative integer | <predef-allocator>
  3148. -----------------------------------------------------------------------------*/
  3149. static void __kmp_stg_parse_allocator(char const *name, char const *value,
  3150. void *data) {
  3151. const char *buf = value;
  3152. const char *next, *scan, *start;
  3153. char *key;
  3154. omp_allocator_handle_t al;
  3155. omp_memspace_handle_t ms = omp_default_mem_space;
  3156. bool is_memspace = false;
  3157. int ntraits = 0, count = 0;
  3158. SKIP_WS(buf);
  3159. next = buf;
  3160. const char *delim = strchr(buf, ':');
  3161. const char *predef_mem_space = strstr(buf, "mem_space");
  3162. bool is_memalloc = (!predef_mem_space && !delim) ? true : false;
  3163. // Count the number of traits in the env var string
  3164. if (delim) {
  3165. ntraits = 1;
  3166. for (scan = buf; *scan != '\0'; scan++) {
  3167. if (*scan == ',')
  3168. ntraits++;
  3169. }
  3170. }
  3171. omp_alloctrait_t *traits =
  3172. (omp_alloctrait_t *)KMP_ALLOCA(ntraits * sizeof(omp_alloctrait_t));
  3173. // Helper macros
  3174. #define IS_POWER_OF_TWO(n) (((n) & ((n)-1)) == 0)
  3175. #define GET_NEXT(sentinel) \
  3176. { \
  3177. SKIP_WS(next); \
  3178. if (*next == sentinel) \
  3179. next++; \
  3180. SKIP_WS(next); \
  3181. scan = next; \
  3182. }
  3183. #define SKIP_PAIR(key) \
  3184. { \
  3185. char const str_delimiter[] = {',', 0}; \
  3186. char *value = __kmp_str_token(CCAST(char *, scan), str_delimiter, \
  3187. CCAST(char **, &next)); \
  3188. KMP_WARNING(StgInvalidValue, key, value); \
  3189. ntraits--; \
  3190. SKIP_WS(next); \
  3191. scan = next; \
  3192. }
  3193. #define SET_KEY() \
  3194. { \
  3195. char const str_delimiter[] = {'=', 0}; \
  3196. key = __kmp_str_token(CCAST(char *, start), str_delimiter, \
  3197. CCAST(char **, &next)); \
  3198. scan = next; \
  3199. }
  3200. scan = next;
  3201. while (*next != '\0') {
  3202. if (is_memalloc ||
  3203. __kmp_match_str("fb_data", scan, &next)) { // allocator check
  3204. start = scan;
  3205. GET_NEXT('=');
  3206. // check HBW and LCAP first as the only non-default supported
  3207. if (__kmp_match_str("omp_high_bw_mem_alloc", scan, &next)) {
  3208. SKIP_WS(next);
  3209. if (is_memalloc) {
  3210. if (__kmp_memkind_available) {
  3211. __kmp_def_allocator = omp_high_bw_mem_alloc;
  3212. return;
  3213. } else {
  3214. KMP_WARNING(OmpNoAllocator, "omp_high_bw_mem_alloc");
  3215. }
  3216. } else {
  3217. traits[count].key = omp_atk_fb_data;
  3218. traits[count].value = RCAST(omp_uintptr_t, omp_high_bw_mem_alloc);
  3219. }
  3220. } else if (__kmp_match_str("omp_large_cap_mem_alloc", scan, &next)) {
  3221. SKIP_WS(next);
  3222. if (is_memalloc) {
  3223. if (__kmp_memkind_available) {
  3224. __kmp_def_allocator = omp_large_cap_mem_alloc;
  3225. return;
  3226. } else {
  3227. KMP_WARNING(OmpNoAllocator, "omp_large_cap_mem_alloc");
  3228. }
  3229. } else {
  3230. traits[count].key = omp_atk_fb_data;
  3231. traits[count].value = RCAST(omp_uintptr_t, omp_large_cap_mem_alloc);
  3232. }
  3233. } else if (__kmp_match_str("omp_default_mem_alloc", scan, &next)) {
  3234. // default requested
  3235. SKIP_WS(next);
  3236. if (!is_memalloc) {
  3237. traits[count].key = omp_atk_fb_data;
  3238. traits[count].value = RCAST(omp_uintptr_t, omp_default_mem_alloc);
  3239. }
  3240. } else if (__kmp_match_str("omp_const_mem_alloc", scan, &next)) {
  3241. SKIP_WS(next);
  3242. if (is_memalloc) {
  3243. KMP_WARNING(OmpNoAllocator, "omp_const_mem_alloc");
  3244. } else {
  3245. traits[count].key = omp_atk_fb_data;
  3246. traits[count].value = RCAST(omp_uintptr_t, omp_const_mem_alloc);
  3247. }
  3248. } else if (__kmp_match_str("omp_low_lat_mem_alloc", scan, &next)) {
  3249. SKIP_WS(next);
  3250. if (is_memalloc) {
  3251. KMP_WARNING(OmpNoAllocator, "omp_low_lat_mem_alloc");
  3252. } else {
  3253. traits[count].key = omp_atk_fb_data;
  3254. traits[count].value = RCAST(omp_uintptr_t, omp_low_lat_mem_alloc);
  3255. }
  3256. } else if (__kmp_match_str("omp_cgroup_mem_alloc", scan, &next)) {
  3257. SKIP_WS(next);
  3258. if (is_memalloc) {
  3259. KMP_WARNING(OmpNoAllocator, "omp_cgroup_mem_alloc");
  3260. } else {
  3261. traits[count].key = omp_atk_fb_data;
  3262. traits[count].value = RCAST(omp_uintptr_t, omp_cgroup_mem_alloc);
  3263. }
  3264. } else if (__kmp_match_str("omp_pteam_mem_alloc", scan, &next)) {
  3265. SKIP_WS(next);
  3266. if (is_memalloc) {
  3267. KMP_WARNING(OmpNoAllocator, "omp_pteam_mem_alloc");
  3268. } else {
  3269. traits[count].key = omp_atk_fb_data;
  3270. traits[count].value = RCAST(omp_uintptr_t, omp_pteam_mem_alloc);
  3271. }
  3272. } else if (__kmp_match_str("omp_thread_mem_alloc", scan, &next)) {
  3273. SKIP_WS(next);
  3274. if (is_memalloc) {
  3275. KMP_WARNING(OmpNoAllocator, "omp_thread_mem_alloc");
  3276. } else {
  3277. traits[count].key = omp_atk_fb_data;
  3278. traits[count].value = RCAST(omp_uintptr_t, omp_thread_mem_alloc);
  3279. }
  3280. } else {
  3281. if (!is_memalloc) {
  3282. SET_KEY();
  3283. SKIP_PAIR(key);
  3284. continue;
  3285. }
  3286. }
  3287. if (is_memalloc) {
  3288. __kmp_def_allocator = omp_default_mem_alloc;
  3289. if (next == buf || *next != '\0') {
  3290. // either no match or extra symbols present after the matched token
  3291. KMP_WARNING(StgInvalidValue, name, value);
  3292. }
  3293. return;
  3294. } else {
  3295. ++count;
  3296. if (count == ntraits)
  3297. break;
  3298. GET_NEXT(',');
  3299. }
  3300. } else { // memspace
  3301. if (!is_memspace) {
  3302. if (__kmp_match_str("omp_default_mem_space", scan, &next)) {
  3303. SKIP_WS(next);
  3304. ms = omp_default_mem_space;
  3305. } else if (__kmp_match_str("omp_large_cap_mem_space", scan, &next)) {
  3306. SKIP_WS(next);
  3307. ms = omp_large_cap_mem_space;
  3308. } else if (__kmp_match_str("omp_const_mem_space", scan, &next)) {
  3309. SKIP_WS(next);
  3310. ms = omp_const_mem_space;
  3311. } else if (__kmp_match_str("omp_high_bw_mem_space", scan, &next)) {
  3312. SKIP_WS(next);
  3313. ms = omp_high_bw_mem_space;
  3314. } else if (__kmp_match_str("omp_low_lat_mem_space", scan, &next)) {
  3315. SKIP_WS(next);
  3316. ms = omp_low_lat_mem_space;
  3317. } else {
  3318. __kmp_def_allocator = omp_default_mem_alloc;
  3319. if (next == buf || *next != '\0') {
  3320. // either no match or extra symbols present after the matched token
  3321. KMP_WARNING(StgInvalidValue, name, value);
  3322. }
  3323. return;
  3324. }
  3325. is_memspace = true;
  3326. }
  3327. if (delim) { // traits
  3328. GET_NEXT(':');
  3329. start = scan;
  3330. if (__kmp_match_str("sync_hint", scan, &next)) {
  3331. GET_NEXT('=');
  3332. traits[count].key = omp_atk_sync_hint;
  3333. if (__kmp_match_str("contended", scan, &next)) {
  3334. traits[count].value = omp_atv_contended;
  3335. } else if (__kmp_match_str("uncontended", scan, &next)) {
  3336. traits[count].value = omp_atv_uncontended;
  3337. } else if (__kmp_match_str("serialized", scan, &next)) {
  3338. traits[count].value = omp_atv_serialized;
  3339. } else if (__kmp_match_str("private", scan, &next)) {
  3340. traits[count].value = omp_atv_private;
  3341. } else {
  3342. SET_KEY();
  3343. SKIP_PAIR(key);
  3344. continue;
  3345. }
  3346. } else if (__kmp_match_str("alignment", scan, &next)) {
  3347. GET_NEXT('=');
  3348. if (!isdigit(*next)) {
  3349. SET_KEY();
  3350. SKIP_PAIR(key);
  3351. continue;
  3352. }
  3353. SKIP_DIGITS(next);
  3354. int n = __kmp_str_to_int(scan, ',');
  3355. if (n < 0 || !IS_POWER_OF_TWO(n)) {
  3356. SET_KEY();
  3357. SKIP_PAIR(key);
  3358. continue;
  3359. }
  3360. traits[count].key = omp_atk_alignment;
  3361. traits[count].value = n;
  3362. } else if (__kmp_match_str("access", scan, &next)) {
  3363. GET_NEXT('=');
  3364. traits[count].key = omp_atk_access;
  3365. if (__kmp_match_str("all", scan, &next)) {
  3366. traits[count].value = omp_atv_all;
  3367. } else if (__kmp_match_str("cgroup", scan, &next)) {
  3368. traits[count].value = omp_atv_cgroup;
  3369. } else if (__kmp_match_str("pteam", scan, &next)) {
  3370. traits[count].value = omp_atv_pteam;
  3371. } else if (__kmp_match_str("thread", scan, &next)) {
  3372. traits[count].value = omp_atv_thread;
  3373. } else {
  3374. SET_KEY();
  3375. SKIP_PAIR(key);
  3376. continue;
  3377. }
  3378. } else if (__kmp_match_str("pool_size", scan, &next)) {
  3379. GET_NEXT('=');
  3380. if (!isdigit(*next)) {
  3381. SET_KEY();
  3382. SKIP_PAIR(key);
  3383. continue;
  3384. }
  3385. SKIP_DIGITS(next);
  3386. int n = __kmp_str_to_int(scan, ',');
  3387. if (n < 0) {
  3388. SET_KEY();
  3389. SKIP_PAIR(key);
  3390. continue;
  3391. }
  3392. traits[count].key = omp_atk_pool_size;
  3393. traits[count].value = n;
  3394. } else if (__kmp_match_str("fallback", scan, &next)) {
  3395. GET_NEXT('=');
  3396. traits[count].key = omp_atk_fallback;
  3397. if (__kmp_match_str("default_mem_fb", scan, &next)) {
  3398. traits[count].value = omp_atv_default_mem_fb;
  3399. } else if (__kmp_match_str("null_fb", scan, &next)) {
  3400. traits[count].value = omp_atv_null_fb;
  3401. } else if (__kmp_match_str("abort_fb", scan, &next)) {
  3402. traits[count].value = omp_atv_abort_fb;
  3403. } else if (__kmp_match_str("allocator_fb", scan, &next)) {
  3404. traits[count].value = omp_atv_allocator_fb;
  3405. } else {
  3406. SET_KEY();
  3407. SKIP_PAIR(key);
  3408. continue;
  3409. }
  3410. } else if (__kmp_match_str("pinned", scan, &next)) {
  3411. GET_NEXT('=');
  3412. traits[count].key = omp_atk_pinned;
  3413. if (__kmp_str_match_true(next)) {
  3414. traits[count].value = omp_atv_true;
  3415. } else if (__kmp_str_match_false(next)) {
  3416. traits[count].value = omp_atv_false;
  3417. } else {
  3418. SET_KEY();
  3419. SKIP_PAIR(key);
  3420. continue;
  3421. }
  3422. } else if (__kmp_match_str("partition", scan, &next)) {
  3423. GET_NEXT('=');
  3424. traits[count].key = omp_atk_partition;
  3425. if (__kmp_match_str("environment", scan, &next)) {
  3426. traits[count].value = omp_atv_environment;
  3427. } else if (__kmp_match_str("nearest", scan, &next)) {
  3428. traits[count].value = omp_atv_nearest;
  3429. } else if (__kmp_match_str("blocked", scan, &next)) {
  3430. traits[count].value = omp_atv_blocked;
  3431. } else if (__kmp_match_str("interleaved", scan, &next)) {
  3432. traits[count].value = omp_atv_interleaved;
  3433. } else {
  3434. SET_KEY();
  3435. SKIP_PAIR(key);
  3436. continue;
  3437. }
  3438. } else {
  3439. SET_KEY();
  3440. SKIP_PAIR(key);
  3441. continue;
  3442. }
  3443. SKIP_WS(next);
  3444. ++count;
  3445. if (count == ntraits)
  3446. break;
  3447. GET_NEXT(',');
  3448. } // traits
  3449. } // memspace
  3450. } // while
  3451. al = __kmpc_init_allocator(__kmp_get_gtid(), ms, ntraits, traits);
  3452. __kmp_def_allocator = (al == omp_null_allocator) ? omp_default_mem_alloc : al;
  3453. }
  3454. static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name,
  3455. void *data) {
  3456. if (__kmp_def_allocator == omp_default_mem_alloc) {
  3457. __kmp_stg_print_str(buffer, name, "omp_default_mem_alloc");
  3458. } else if (__kmp_def_allocator == omp_high_bw_mem_alloc) {
  3459. __kmp_stg_print_str(buffer, name, "omp_high_bw_mem_alloc");
  3460. } else if (__kmp_def_allocator == omp_large_cap_mem_alloc) {
  3461. __kmp_stg_print_str(buffer, name, "omp_large_cap_mem_alloc");
  3462. } else if (__kmp_def_allocator == omp_const_mem_alloc) {
  3463. __kmp_stg_print_str(buffer, name, "omp_const_mem_alloc");
  3464. } else if (__kmp_def_allocator == omp_low_lat_mem_alloc) {
  3465. __kmp_stg_print_str(buffer, name, "omp_low_lat_mem_alloc");
  3466. } else if (__kmp_def_allocator == omp_cgroup_mem_alloc) {
  3467. __kmp_stg_print_str(buffer, name, "omp_cgroup_mem_alloc");
  3468. } else if (__kmp_def_allocator == omp_pteam_mem_alloc) {
  3469. __kmp_stg_print_str(buffer, name, "omp_pteam_mem_alloc");
  3470. } else if (__kmp_def_allocator == omp_thread_mem_alloc) {
  3471. __kmp_stg_print_str(buffer, name, "omp_thread_mem_alloc");
  3472. }
  3473. }
  3474. // -----------------------------------------------------------------------------
  3475. // OMP_DYNAMIC
  3476. static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value,
  3477. void *data) {
  3478. __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic));
  3479. } // __kmp_stg_parse_omp_dynamic
  3480. static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name,
  3481. void *data) {
  3482. __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic);
  3483. } // __kmp_stg_print_omp_dynamic
  3484. static void __kmp_stg_parse_kmp_dynamic_mode(char const *name,
  3485. char const *value, void *data) {
  3486. if (TCR_4(__kmp_init_parallel)) {
  3487. KMP_WARNING(EnvParallelWarn, name);
  3488. __kmp_env_toPrint(name, 0);
  3489. return;
  3490. }
  3491. #ifdef USE_LOAD_BALANCE
  3492. else if (__kmp_str_match("load balance", 2, value) ||
  3493. __kmp_str_match("load_balance", 2, value) ||
  3494. __kmp_str_match("load-balance", 2, value) ||
  3495. __kmp_str_match("loadbalance", 2, value) ||
  3496. __kmp_str_match("balance", 1, value)) {
  3497. __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
  3498. }
  3499. #endif /* USE_LOAD_BALANCE */
  3500. else if (__kmp_str_match("thread limit", 1, value) ||
  3501. __kmp_str_match("thread_limit", 1, value) ||
  3502. __kmp_str_match("thread-limit", 1, value) ||
  3503. __kmp_str_match("threadlimit", 1, value) ||
  3504. __kmp_str_match("limit", 2, value)) {
  3505. __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
  3506. } else if (__kmp_str_match("random", 1, value)) {
  3507. __kmp_global.g.g_dynamic_mode = dynamic_random;
  3508. } else {
  3509. KMP_WARNING(StgInvalidValue, name, value);
  3510. }
  3511. } //__kmp_stg_parse_kmp_dynamic_mode
  3512. static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer,
  3513. char const *name, void *data) {
  3514. #if KMP_DEBUG
  3515. if (__kmp_global.g.g_dynamic_mode == dynamic_default) {
  3516. __kmp_str_buf_print(buffer, " %s: %s \n", name, KMP_I18N_STR(NotDefined));
  3517. }
  3518. #ifdef USE_LOAD_BALANCE
  3519. else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) {
  3520. __kmp_stg_print_str(buffer, name, "load balance");
  3521. }
  3522. #endif /* USE_LOAD_BALANCE */
  3523. else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) {
  3524. __kmp_stg_print_str(buffer, name, "thread limit");
  3525. } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) {
  3526. __kmp_stg_print_str(buffer, name, "random");
  3527. } else {
  3528. KMP_ASSERT(0);
  3529. }
  3530. #endif /* KMP_DEBUG */
  3531. } // __kmp_stg_print_kmp_dynamic_mode
  3532. #ifdef USE_LOAD_BALANCE
  3533. // -----------------------------------------------------------------------------
  3534. // KMP_LOAD_BALANCE_INTERVAL
  3535. static void __kmp_stg_parse_ld_balance_interval(char const *name,
  3536. char const *value, void *data) {
  3537. double interval = __kmp_convert_to_double(value);
  3538. if (interval >= 0) {
  3539. __kmp_load_balance_interval = interval;
  3540. } else {
  3541. KMP_WARNING(StgInvalidValue, name, value);
  3542. }
  3543. } // __kmp_stg_parse_load_balance_interval
  3544. static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer,
  3545. char const *name, void *data) {
  3546. #if KMP_DEBUG
  3547. __kmp_str_buf_print(buffer, " %s=%8.6f\n", name,
  3548. __kmp_load_balance_interval);
  3549. #endif /* KMP_DEBUG */
  3550. } // __kmp_stg_print_load_balance_interval
  3551. #endif /* USE_LOAD_BALANCE */
  3552. // -----------------------------------------------------------------------------
  3553. // KMP_INIT_AT_FORK
  3554. static void __kmp_stg_parse_init_at_fork(char const *name, char const *value,
  3555. void *data) {
  3556. __kmp_stg_parse_bool(name, value, &__kmp_need_register_atfork);
  3557. if (__kmp_need_register_atfork) {
  3558. __kmp_need_register_atfork_specified = TRUE;
  3559. }
  3560. } // __kmp_stg_parse_init_at_fork
  3561. static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer,
  3562. char const *name, void *data) {
  3563. __kmp_stg_print_bool(buffer, name, __kmp_need_register_atfork_specified);
  3564. } // __kmp_stg_print_init_at_fork
  3565. // -----------------------------------------------------------------------------
  3566. // KMP_SCHEDULE
  3567. static void __kmp_stg_parse_schedule(char const *name, char const *value,
  3568. void *data) {
  3569. if (value != NULL) {
  3570. size_t length = KMP_STRLEN(value);
  3571. if (length > INT_MAX) {
  3572. KMP_WARNING(LongValue, name);
  3573. } else {
  3574. const char *semicolon;
  3575. if (value[length - 1] == '"' || value[length - 1] == '\'')
  3576. KMP_WARNING(UnbalancedQuotes, name);
  3577. do {
  3578. char sentinel;
  3579. semicolon = strchr(value, ';');
  3580. if (*value && semicolon != value) {
  3581. const char *comma = strchr(value, ',');
  3582. if (comma) {
  3583. ++comma;
  3584. sentinel = ',';
  3585. } else
  3586. sentinel = ';';
  3587. if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) {
  3588. if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) {
  3589. __kmp_static = kmp_sch_static_greedy;
  3590. continue;
  3591. } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma,
  3592. ';')) {
  3593. __kmp_static = kmp_sch_static_balanced;
  3594. continue;
  3595. }
  3596. } else if (!__kmp_strcasecmp_with_sentinel("guided", value,
  3597. sentinel)) {
  3598. if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) {
  3599. __kmp_guided = kmp_sch_guided_iterative_chunked;
  3600. continue;
  3601. } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma,
  3602. ';')) {
  3603. /* analytical not allowed for too many threads */
  3604. __kmp_guided = kmp_sch_guided_analytical_chunked;
  3605. continue;
  3606. }
  3607. }
  3608. KMP_WARNING(InvalidClause, name, value);
  3609. } else
  3610. KMP_WARNING(EmptyClause, name);
  3611. } while ((value = semicolon ? semicolon + 1 : NULL));
  3612. }
  3613. }
  3614. } // __kmp_stg_parse__schedule
  3615. static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name,
  3616. void *data) {
  3617. if (__kmp_env_format) {
  3618. KMP_STR_BUF_PRINT_NAME_EX(name);
  3619. } else {
  3620. __kmp_str_buf_print(buffer, " %s='", name);
  3621. }
  3622. if (__kmp_static == kmp_sch_static_greedy) {
  3623. __kmp_str_buf_print(buffer, "%s", "static,greedy");
  3624. } else if (__kmp_static == kmp_sch_static_balanced) {
  3625. __kmp_str_buf_print(buffer, "%s", "static,balanced");
  3626. }
  3627. if (__kmp_guided == kmp_sch_guided_iterative_chunked) {
  3628. __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative");
  3629. } else if (__kmp_guided == kmp_sch_guided_analytical_chunked) {
  3630. __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical");
  3631. }
  3632. } // __kmp_stg_print_schedule
  3633. // -----------------------------------------------------------------------------
  3634. // OMP_SCHEDULE
  3635. static inline void __kmp_omp_schedule_restore() {
  3636. #if KMP_USE_HIER_SCHED
  3637. __kmp_hier_scheds.deallocate();
  3638. #endif
  3639. __kmp_chunk = 0;
  3640. __kmp_sched = kmp_sch_default;
  3641. }
  3642. // if parse_hier = true:
  3643. // Parse [HW,][modifier:]kind[,chunk]
  3644. // else:
  3645. // Parse [modifier:]kind[,chunk]
  3646. static const char *__kmp_parse_single_omp_schedule(const char *name,
  3647. const char *value,
  3648. bool parse_hier = false) {
  3649. /* get the specified scheduling style */
  3650. const char *ptr = value;
  3651. const char *delim;
  3652. int chunk = 0;
  3653. enum sched_type sched = kmp_sch_default;
  3654. if (*ptr == '\0')
  3655. return NULL;
  3656. delim = ptr;
  3657. while (*delim != ',' && *delim != ':' && *delim != '\0')
  3658. delim++;
  3659. #if KMP_USE_HIER_SCHED
  3660. kmp_hier_layer_e layer = kmp_hier_layer_e::LAYER_THREAD;
  3661. if (parse_hier) {
  3662. if (*delim == ',') {
  3663. if (!__kmp_strcasecmp_with_sentinel("L1", ptr, ',')) {
  3664. layer = kmp_hier_layer_e::LAYER_L1;
  3665. } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr, ',')) {
  3666. layer = kmp_hier_layer_e::LAYER_L2;
  3667. } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr, ',')) {
  3668. layer = kmp_hier_layer_e::LAYER_L3;
  3669. } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr, ',')) {
  3670. layer = kmp_hier_layer_e::LAYER_NUMA;
  3671. }
  3672. }
  3673. if (layer != kmp_hier_layer_e::LAYER_THREAD && *delim != ',') {
  3674. // If there is no comma after the layer, then this schedule is invalid
  3675. KMP_WARNING(StgInvalidValue, name, value);
  3676. __kmp_omp_schedule_restore();
  3677. return NULL;
  3678. } else if (layer != kmp_hier_layer_e::LAYER_THREAD) {
  3679. ptr = ++delim;
  3680. while (*delim != ',' && *delim != ':' && *delim != '\0')
  3681. delim++;
  3682. }
  3683. }
  3684. #endif // KMP_USE_HIER_SCHED
  3685. // Read in schedule modifier if specified
  3686. enum sched_type sched_modifier = (enum sched_type)0;
  3687. if (*delim == ':') {
  3688. if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr, *delim)) {
  3689. sched_modifier = sched_type::kmp_sch_modifier_monotonic;
  3690. ptr = ++delim;
  3691. while (*delim != ',' && *delim != ':' && *delim != '\0')
  3692. delim++;
  3693. } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr, *delim)) {
  3694. sched_modifier = sched_type::kmp_sch_modifier_nonmonotonic;
  3695. ptr = ++delim;
  3696. while (*delim != ',' && *delim != ':' && *delim != '\0')
  3697. delim++;
  3698. } else if (!parse_hier) {
  3699. // If there is no proper schedule modifier, then this schedule is invalid
  3700. KMP_WARNING(StgInvalidValue, name, value);
  3701. __kmp_omp_schedule_restore();
  3702. return NULL;
  3703. }
  3704. }
  3705. // Read in schedule kind (required)
  3706. if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr, *delim))
  3707. sched = kmp_sch_dynamic_chunked;
  3708. else if (!__kmp_strcasecmp_with_sentinel("guided", ptr, *delim))
  3709. sched = kmp_sch_guided_chunked;
  3710. // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
  3711. else if (!__kmp_strcasecmp_with_sentinel("auto", ptr, *delim))
  3712. sched = kmp_sch_auto;
  3713. else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr, *delim))
  3714. sched = kmp_sch_trapezoidal;
  3715. else if (!__kmp_strcasecmp_with_sentinel("static", ptr, *delim))
  3716. sched = kmp_sch_static;
  3717. #if KMP_STATIC_STEAL_ENABLED
  3718. else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr, *delim)) {
  3719. // replace static_steal with dynamic to better cope with ordered loops
  3720. sched = kmp_sch_dynamic_chunked;
  3721. sched_modifier = sched_type::kmp_sch_modifier_nonmonotonic;
  3722. }
  3723. #endif
  3724. else {
  3725. // If there is no proper schedule kind, then this schedule is invalid
  3726. KMP_WARNING(StgInvalidValue, name, value);
  3727. __kmp_omp_schedule_restore();
  3728. return NULL;
  3729. }
  3730. // Read in schedule chunk size if specified
  3731. if (*delim == ',') {
  3732. ptr = delim + 1;
  3733. SKIP_WS(ptr);
  3734. if (!isdigit(*ptr)) {
  3735. // If there is no chunk after comma, then this schedule is invalid
  3736. KMP_WARNING(StgInvalidValue, name, value);
  3737. __kmp_omp_schedule_restore();
  3738. return NULL;
  3739. }
  3740. SKIP_DIGITS(ptr);
  3741. // auto schedule should not specify chunk size
  3742. if (sched == kmp_sch_auto) {
  3743. __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, delim),
  3744. __kmp_msg_null);
  3745. } else {
  3746. if (sched == kmp_sch_static)
  3747. sched = kmp_sch_static_chunked;
  3748. chunk = __kmp_str_to_int(delim + 1, *ptr);
  3749. if (chunk < 1) {
  3750. chunk = KMP_DEFAULT_CHUNK;
  3751. __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, delim),
  3752. __kmp_msg_null);
  3753. KMP_INFORM(Using_int_Value, name, __kmp_chunk);
  3754. // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK
  3755. // (to improve code coverage :)
  3756. // The default chunk size is 1 according to standard, thus making
  3757. // KMP_MIN_CHUNK not 1 we would introduce mess:
  3758. // wrong chunk becomes 1, but it will be impossible to explicitly set
  3759. // to 1 because it becomes KMP_MIN_CHUNK...
  3760. // } else if ( chunk < KMP_MIN_CHUNK ) {
  3761. // chunk = KMP_MIN_CHUNK;
  3762. } else if (chunk > KMP_MAX_CHUNK) {
  3763. chunk = KMP_MAX_CHUNK;
  3764. __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, delim),
  3765. __kmp_msg_null);
  3766. KMP_INFORM(Using_int_Value, name, chunk);
  3767. }
  3768. }
  3769. } else {
  3770. ptr = delim;
  3771. }
  3772. SCHEDULE_SET_MODIFIERS(sched, sched_modifier);
  3773. #if KMP_USE_HIER_SCHED
  3774. if (layer != kmp_hier_layer_e::LAYER_THREAD) {
  3775. __kmp_hier_scheds.append(sched, chunk, layer);
  3776. } else
  3777. #endif
  3778. {
  3779. __kmp_chunk = chunk;
  3780. __kmp_sched = sched;
  3781. }
  3782. return ptr;
  3783. }
  3784. static void __kmp_stg_parse_omp_schedule(char const *name, char const *value,
  3785. void *data) {
  3786. size_t length;
  3787. const char *ptr = value;
  3788. SKIP_WS(ptr);
  3789. if (value) {
  3790. length = KMP_STRLEN(value);
  3791. if (length) {
  3792. if (value[length - 1] == '"' || value[length - 1] == '\'')
  3793. KMP_WARNING(UnbalancedQuotes, name);
  3794. /* get the specified scheduling style */
  3795. #if KMP_USE_HIER_SCHED
  3796. if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr, ' ')) {
  3797. SKIP_TOKEN(ptr);
  3798. SKIP_WS(ptr);
  3799. while ((ptr = __kmp_parse_single_omp_schedule(name, ptr, true))) {
  3800. while (*ptr == ' ' || *ptr == '\t' || *ptr == ':')
  3801. ptr++;
  3802. if (*ptr == '\0')
  3803. break;
  3804. }
  3805. } else
  3806. #endif
  3807. __kmp_parse_single_omp_schedule(name, ptr);
  3808. } else
  3809. KMP_WARNING(EmptyString, name);
  3810. }
  3811. #if KMP_USE_HIER_SCHED
  3812. __kmp_hier_scheds.sort();
  3813. #endif
  3814. K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
  3815. K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
  3816. K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
  3817. K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
  3818. } // __kmp_stg_parse_omp_schedule
  3819. static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer,
  3820. char const *name, void *data) {
  3821. if (__kmp_env_format) {
  3822. KMP_STR_BUF_PRINT_NAME_EX(name);
  3823. } else {
  3824. __kmp_str_buf_print(buffer, " %s='", name);
  3825. }
  3826. enum sched_type sched = SCHEDULE_WITHOUT_MODIFIERS(__kmp_sched);
  3827. if (SCHEDULE_HAS_MONOTONIC(__kmp_sched)) {
  3828. __kmp_str_buf_print(buffer, "monotonic:");
  3829. } else if (SCHEDULE_HAS_NONMONOTONIC(__kmp_sched)) {
  3830. __kmp_str_buf_print(buffer, "nonmonotonic:");
  3831. }
  3832. if (__kmp_chunk) {
  3833. switch (sched) {
  3834. case kmp_sch_dynamic_chunked:
  3835. __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk);
  3836. break;
  3837. case kmp_sch_guided_iterative_chunked:
  3838. case kmp_sch_guided_analytical_chunked:
  3839. __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk);
  3840. break;
  3841. case kmp_sch_trapezoidal:
  3842. __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);
  3843. break;
  3844. case kmp_sch_static:
  3845. case kmp_sch_static_chunked:
  3846. case kmp_sch_static_balanced:
  3847. case kmp_sch_static_greedy:
  3848. __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk);
  3849. break;
  3850. case kmp_sch_static_steal:
  3851. __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk);
  3852. break;
  3853. case kmp_sch_auto:
  3854. __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk);
  3855. break;
  3856. }
  3857. } else {
  3858. switch (sched) {
  3859. case kmp_sch_dynamic_chunked:
  3860. __kmp_str_buf_print(buffer, "%s'\n", "dynamic");
  3861. break;
  3862. case kmp_sch_guided_iterative_chunked:
  3863. case kmp_sch_guided_analytical_chunked:
  3864. __kmp_str_buf_print(buffer, "%s'\n", "guided");
  3865. break;
  3866. case kmp_sch_trapezoidal:
  3867. __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal");
  3868. break;
  3869. case kmp_sch_static:
  3870. case kmp_sch_static_chunked:
  3871. case kmp_sch_static_balanced:
  3872. case kmp_sch_static_greedy:
  3873. __kmp_str_buf_print(buffer, "%s'\n", "static");
  3874. break;
  3875. case kmp_sch_static_steal:
  3876. __kmp_str_buf_print(buffer, "%s'\n", "static_steal");
  3877. break;
  3878. case kmp_sch_auto:
  3879. __kmp_str_buf_print(buffer, "%s'\n", "auto");
  3880. break;
  3881. }
  3882. }
  3883. } // __kmp_stg_print_omp_schedule
  3884. #if KMP_USE_HIER_SCHED
  3885. // -----------------------------------------------------------------------------
  3886. // KMP_DISP_HAND_THREAD
  3887. static void __kmp_stg_parse_kmp_hand_thread(char const *name, char const *value,
  3888. void *data) {
  3889. __kmp_stg_parse_bool(name, value, &(__kmp_dispatch_hand_threading));
  3890. } // __kmp_stg_parse_kmp_hand_thread
  3891. static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t *buffer,
  3892. char const *name, void *data) {
  3893. __kmp_stg_print_bool(buffer, name, __kmp_dispatch_hand_threading);
  3894. } // __kmp_stg_print_kmp_hand_thread
  3895. #endif
  3896. // -----------------------------------------------------------------------------
  3897. // KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE
  3898. static void __kmp_stg_parse_kmp_force_monotonic(char const *name,
  3899. char const *value, void *data) {
  3900. __kmp_stg_parse_bool(name, value, &(__kmp_force_monotonic));
  3901. } // __kmp_stg_parse_kmp_force_monotonic
  3902. static void __kmp_stg_print_kmp_force_monotonic(kmp_str_buf_t *buffer,
  3903. char const *name, void *data) {
  3904. __kmp_stg_print_bool(buffer, name, __kmp_force_monotonic);
  3905. } // __kmp_stg_print_kmp_force_monotonic
  3906. // -----------------------------------------------------------------------------
  3907. // KMP_ATOMIC_MODE
  3908. static void __kmp_stg_parse_atomic_mode(char const *name, char const *value,
  3909. void *data) {
  3910. // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
  3911. // compatibility mode.
  3912. int mode = 0;
  3913. int max = 1;
  3914. #ifdef KMP_GOMP_COMPAT
  3915. max = 2;
  3916. #endif /* KMP_GOMP_COMPAT */
  3917. __kmp_stg_parse_int(name, value, 0, max, &mode);
  3918. // TODO; parse_int is not very suitable for this case. In case of overflow it
  3919. // is better to use
  3920. // 0 rather that max value.
  3921. if (mode > 0) {
  3922. __kmp_atomic_mode = mode;
  3923. }
  3924. } // __kmp_stg_parse_atomic_mode
  3925. static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name,
  3926. void *data) {
  3927. __kmp_stg_print_int(buffer, name, __kmp_atomic_mode);
  3928. } // __kmp_stg_print_atomic_mode
  3929. // -----------------------------------------------------------------------------
  3930. // KMP_CONSISTENCY_CHECK
  3931. static void __kmp_stg_parse_consistency_check(char const *name,
  3932. char const *value, void *data) {
  3933. if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
  3934. // Note, this will not work from kmp_set_defaults because th_cons stack was
  3935. // not allocated
  3936. // for existed thread(s) thus the first __kmp_push_<construct> will break
  3937. // with assertion.
  3938. // TODO: allocate th_cons if called from kmp_set_defaults.
  3939. __kmp_env_consistency_check = TRUE;
  3940. } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) {
  3941. __kmp_env_consistency_check = FALSE;
  3942. } else {
  3943. KMP_WARNING(StgInvalidValue, name, value);
  3944. }
  3945. } // __kmp_stg_parse_consistency_check
  3946. static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer,
  3947. char const *name, void *data) {
  3948. #if KMP_DEBUG
  3949. const char *value = NULL;
  3950. if (__kmp_env_consistency_check) {
  3951. value = "all";
  3952. } else {
  3953. value = "none";
  3954. }
  3955. if (value != NULL) {
  3956. __kmp_stg_print_str(buffer, name, value);
  3957. }
  3958. #endif /* KMP_DEBUG */
  3959. } // __kmp_stg_print_consistency_check
  3960. #if USE_ITT_BUILD
  3961. // -----------------------------------------------------------------------------
  3962. // KMP_ITT_PREPARE_DELAY
  3963. #if USE_ITT_NOTIFY
  3964. static void __kmp_stg_parse_itt_prepare_delay(char const *name,
  3965. char const *value, void *data) {
  3966. // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
  3967. // iterations.
  3968. int delay = 0;
  3969. __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay);
  3970. __kmp_itt_prepare_delay = delay;
  3971. } // __kmp_str_parse_itt_prepare_delay
  3972. static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer,
  3973. char const *name, void *data) {
  3974. __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay);
  3975. } // __kmp_str_print_itt_prepare_delay
  3976. #endif // USE_ITT_NOTIFY
  3977. #endif /* USE_ITT_BUILD */
  3978. // -----------------------------------------------------------------------------
  3979. // KMP_MALLOC_POOL_INCR
  3980. static void __kmp_stg_parse_malloc_pool_incr(char const *name,
  3981. char const *value, void *data) {
  3982. __kmp_stg_parse_size(name, value, KMP_MIN_MALLOC_POOL_INCR,
  3983. KMP_MAX_MALLOC_POOL_INCR, NULL, &__kmp_malloc_pool_incr,
  3984. 1);
  3985. } // __kmp_stg_parse_malloc_pool_incr
  3986. static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer,
  3987. char const *name, void *data) {
  3988. __kmp_stg_print_size(buffer, name, __kmp_malloc_pool_incr);
  3989. } // _kmp_stg_print_malloc_pool_incr
  3990. #ifdef KMP_DEBUG
  3991. // -----------------------------------------------------------------------------
  3992. // KMP_PAR_RANGE
  3993. static void __kmp_stg_parse_par_range_env(char const *name, char const *value,
  3994. void *data) {
  3995. __kmp_stg_parse_par_range(name, value, &__kmp_par_range,
  3996. __kmp_par_range_routine, __kmp_par_range_filename,
  3997. &__kmp_par_range_lb, &__kmp_par_range_ub);
  3998. } // __kmp_stg_parse_par_range_env
  3999. static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer,
  4000. char const *name, void *data) {
  4001. if (__kmp_par_range != 0) {
  4002. __kmp_stg_print_str(buffer, name, par_range_to_print);
  4003. }
  4004. } // __kmp_stg_print_par_range_env
  4005. #endif
  4006. // -----------------------------------------------------------------------------
  4007. // KMP_GTID_MODE
  4008. static void __kmp_stg_parse_gtid_mode(char const *name, char const *value,
  4009. void *data) {
  4010. // Modes:
  4011. // 0 -- do not change default
  4012. // 1 -- sp search
  4013. // 2 -- use "keyed" TLS var, i.e.
  4014. // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
  4015. // 3 -- __declspec(thread) TLS var in tdata section
  4016. int mode = 0;
  4017. int max = 2;
  4018. #ifdef KMP_TDATA_GTID
  4019. max = 3;
  4020. #endif /* KMP_TDATA_GTID */
  4021. __kmp_stg_parse_int(name, value, 0, max, &mode);
  4022. // TODO; parse_int is not very suitable for this case. In case of overflow it
  4023. // is better to use 0 rather that max value.
  4024. if (mode == 0) {
  4025. __kmp_adjust_gtid_mode = TRUE;
  4026. } else {
  4027. __kmp_gtid_mode = mode;
  4028. __kmp_adjust_gtid_mode = FALSE;
  4029. }
  4030. } // __kmp_str_parse_gtid_mode
  4031. static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name,
  4032. void *data) {
  4033. if (__kmp_adjust_gtid_mode) {
  4034. __kmp_stg_print_int(buffer, name, 0);
  4035. } else {
  4036. __kmp_stg_print_int(buffer, name, __kmp_gtid_mode);
  4037. }
  4038. } // __kmp_stg_print_gtid_mode
  4039. // -----------------------------------------------------------------------------
  4040. // KMP_NUM_LOCKS_IN_BLOCK
  4041. static void __kmp_stg_parse_lock_block(char const *name, char const *value,
  4042. void *data) {
  4043. __kmp_stg_parse_int(name, value, 0, KMP_INT_MAX, &__kmp_num_locks_in_block);
  4044. } // __kmp_str_parse_lock_block
  4045. static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name,
  4046. void *data) {
  4047. __kmp_stg_print_int(buffer, name, __kmp_num_locks_in_block);
  4048. } // __kmp_stg_print_lock_block
  4049. // -----------------------------------------------------------------------------
  4050. // KMP_LOCK_KIND
  4051. #if KMP_USE_DYNAMIC_LOCK
  4052. #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
  4053. #else
  4054. #define KMP_STORE_LOCK_SEQ(a)
  4055. #endif
  4056. static void __kmp_stg_parse_lock_kind(char const *name, char const *value,
  4057. void *data) {
  4058. if (__kmp_init_user_locks) {
  4059. KMP_WARNING(EnvLockWarn, name);
  4060. return;
  4061. }
  4062. if (__kmp_str_match("tas", 2, value) ||
  4063. __kmp_str_match("test and set", 2, value) ||
  4064. __kmp_str_match("test_and_set", 2, value) ||
  4065. __kmp_str_match("test-and-set", 2, value) ||
  4066. __kmp_str_match("test andset", 2, value) ||
  4067. __kmp_str_match("test_andset", 2, value) ||
  4068. __kmp_str_match("test-andset", 2, value) ||
  4069. __kmp_str_match("testand set", 2, value) ||
  4070. __kmp_str_match("testand_set", 2, value) ||
  4071. __kmp_str_match("testand-set", 2, value) ||
  4072. __kmp_str_match("testandset", 2, value)) {
  4073. __kmp_user_lock_kind = lk_tas;
  4074. KMP_STORE_LOCK_SEQ(tas);
  4075. }
  4076. #if KMP_USE_FUTEX
  4077. else if (__kmp_str_match("futex", 1, value)) {
  4078. if (__kmp_futex_determine_capable()) {
  4079. __kmp_user_lock_kind = lk_futex;
  4080. KMP_STORE_LOCK_SEQ(futex);
  4081. } else {
  4082. KMP_WARNING(FutexNotSupported, name, value);
  4083. }
  4084. }
  4085. #endif
  4086. else if (__kmp_str_match("ticket", 2, value)) {
  4087. __kmp_user_lock_kind = lk_ticket;
  4088. KMP_STORE_LOCK_SEQ(ticket);
  4089. } else if (__kmp_str_match("queuing", 1, value) ||
  4090. __kmp_str_match("queue", 1, value)) {
  4091. __kmp_user_lock_kind = lk_queuing;
  4092. KMP_STORE_LOCK_SEQ(queuing);
  4093. } else if (__kmp_str_match("drdpa ticket", 1, value) ||
  4094. __kmp_str_match("drdpa_ticket", 1, value) ||
  4095. __kmp_str_match("drdpa-ticket", 1, value) ||
  4096. __kmp_str_match("drdpaticket", 1, value) ||
  4097. __kmp_str_match("drdpa", 1, value)) {
  4098. __kmp_user_lock_kind = lk_drdpa;
  4099. KMP_STORE_LOCK_SEQ(drdpa);
  4100. }
  4101. #if KMP_USE_ADAPTIVE_LOCKS
  4102. else if (__kmp_str_match("adaptive", 1, value)) {
  4103. if (__kmp_cpuinfo.flags.rtm) { // ??? Is cpuinfo available here?
  4104. __kmp_user_lock_kind = lk_adaptive;
  4105. KMP_STORE_LOCK_SEQ(adaptive);
  4106. } else {
  4107. KMP_WARNING(AdaptiveNotSupported, name, value);
  4108. __kmp_user_lock_kind = lk_queuing;
  4109. KMP_STORE_LOCK_SEQ(queuing);
  4110. }
  4111. }
  4112. #endif // KMP_USE_ADAPTIVE_LOCKS
  4113. #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
  4114. else if (__kmp_str_match("rtm_queuing", 1, value)) {
  4115. if (__kmp_cpuinfo.flags.rtm) {
  4116. __kmp_user_lock_kind = lk_rtm_queuing;
  4117. KMP_STORE_LOCK_SEQ(rtm_queuing);
  4118. } else {
  4119. KMP_WARNING(AdaptiveNotSupported, name, value);
  4120. __kmp_user_lock_kind = lk_queuing;
  4121. KMP_STORE_LOCK_SEQ(queuing);
  4122. }
  4123. } else if (__kmp_str_match("rtm_spin", 1, value)) {
  4124. if (__kmp_cpuinfo.flags.rtm) {
  4125. __kmp_user_lock_kind = lk_rtm_spin;
  4126. KMP_STORE_LOCK_SEQ(rtm_spin);
  4127. } else {
  4128. KMP_WARNING(AdaptiveNotSupported, name, value);
  4129. __kmp_user_lock_kind = lk_tas;
  4130. KMP_STORE_LOCK_SEQ(queuing);
  4131. }
  4132. } else if (__kmp_str_match("hle", 1, value)) {
  4133. __kmp_user_lock_kind = lk_hle;
  4134. KMP_STORE_LOCK_SEQ(hle);
  4135. }
  4136. #endif
  4137. else {
  4138. KMP_WARNING(StgInvalidValue, name, value);
  4139. }
  4140. }
  4141. static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name,
  4142. void *data) {
  4143. const char *value = NULL;
  4144. switch (__kmp_user_lock_kind) {
  4145. case lk_default:
  4146. value = "default";
  4147. break;
  4148. case lk_tas:
  4149. value = "tas";
  4150. break;
  4151. #if KMP_USE_FUTEX
  4152. case lk_futex:
  4153. value = "futex";
  4154. break;
  4155. #endif
  4156. #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
  4157. case lk_rtm_queuing:
  4158. value = "rtm_queuing";
  4159. break;
  4160. case lk_rtm_spin:
  4161. value = "rtm_spin";
  4162. break;
  4163. case lk_hle:
  4164. value = "hle";
  4165. break;
  4166. #endif
  4167. case lk_ticket:
  4168. value = "ticket";
  4169. break;
  4170. case lk_queuing:
  4171. value = "queuing";
  4172. break;
  4173. case lk_drdpa:
  4174. value = "drdpa";
  4175. break;
  4176. #if KMP_USE_ADAPTIVE_LOCKS
  4177. case lk_adaptive:
  4178. value = "adaptive";
  4179. break;
  4180. #endif
  4181. }
  4182. if (value != NULL) {
  4183. __kmp_stg_print_str(buffer, name, value);
  4184. }
  4185. }
  4186. // -----------------------------------------------------------------------------
  4187. // KMP_SPIN_BACKOFF_PARAMS
  4188. // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
  4189. // for machine pause)
  4190. static void __kmp_stg_parse_spin_backoff_params(const char *name,
  4191. const char *value, void *data) {
  4192. const char *next = value;
  4193. int total = 0; // Count elements that were set. It'll be used as an array size
  4194. int prev_comma = FALSE; // For correct processing sequential commas
  4195. int i;
  4196. kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff;
  4197. kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick;
  4198. // Run only 3 iterations because it is enough to read two values or find a
  4199. // syntax error
  4200. for (i = 0; i < 3; i++) {
  4201. SKIP_WS(next);
  4202. if (*next == '\0') {
  4203. break;
  4204. }
  4205. // Next character is not an integer or not a comma OR number of values > 2
  4206. // => end of list
  4207. if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
  4208. KMP_WARNING(EnvSyntaxError, name, value);
  4209. return;
  4210. }
  4211. // The next character is ','
  4212. if (*next == ',') {
  4213. // ',' is the first character
  4214. if (total == 0 || prev_comma) {
  4215. total++;
  4216. }
  4217. prev_comma = TRUE;
  4218. next++; // skip ','
  4219. SKIP_WS(next);
  4220. }
  4221. // Next character is a digit
  4222. if (*next >= '0' && *next <= '9') {
  4223. int num;
  4224. const char *buf = next;
  4225. char const *msg = NULL;
  4226. prev_comma = FALSE;
  4227. SKIP_DIGITS(next);
  4228. total++;
  4229. const char *tmp = next;
  4230. SKIP_WS(tmp);
  4231. if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
  4232. KMP_WARNING(EnvSpacesNotAllowed, name, value);
  4233. return;
  4234. }
  4235. num = __kmp_str_to_int(buf, *next);
  4236. if (num <= 0) { // The number of retries should be > 0
  4237. msg = KMP_I18N_STR(ValueTooSmall);
  4238. num = 1;
  4239. } else if (num > KMP_INT_MAX) {
  4240. msg = KMP_I18N_STR(ValueTooLarge);
  4241. num = KMP_INT_MAX;
  4242. }
  4243. if (msg != NULL) {
  4244. // Message is not empty. Print warning.
  4245. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  4246. KMP_INFORM(Using_int_Value, name, num);
  4247. }
  4248. if (total == 1) {
  4249. max_backoff = num;
  4250. } else if (total == 2) {
  4251. min_tick = num;
  4252. }
  4253. }
  4254. }
  4255. KMP_DEBUG_ASSERT(total > 0);
  4256. if (total <= 0) {
  4257. KMP_WARNING(EnvSyntaxError, name, value);
  4258. return;
  4259. }
  4260. __kmp_spin_backoff_params.max_backoff = max_backoff;
  4261. __kmp_spin_backoff_params.min_tick = min_tick;
  4262. }
  4263. static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer,
  4264. char const *name, void *data) {
  4265. if (__kmp_env_format) {
  4266. KMP_STR_BUF_PRINT_NAME_EX(name);
  4267. } else {
  4268. __kmp_str_buf_print(buffer, " %s='", name);
  4269. }
  4270. __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff,
  4271. __kmp_spin_backoff_params.min_tick);
  4272. }
  4273. #if KMP_USE_ADAPTIVE_LOCKS
  4274. // -----------------------------------------------------------------------------
  4275. // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
  4276. // Parse out values for the tunable parameters from a string of the form
  4277. // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
  4278. static void __kmp_stg_parse_adaptive_lock_props(const char *name,
  4279. const char *value, void *data) {
  4280. int max_retries = 0;
  4281. int max_badness = 0;
  4282. const char *next = value;
  4283. int total = 0; // Count elements that were set. It'll be used as an array size
  4284. int prev_comma = FALSE; // For correct processing sequential commas
  4285. int i;
  4286. // Save values in the structure __kmp_speculative_backoff_params
  4287. // Run only 3 iterations because it is enough to read two values or find a
  4288. // syntax error
  4289. for (i = 0; i < 3; i++) {
  4290. SKIP_WS(next);
  4291. if (*next == '\0') {
  4292. break;
  4293. }
  4294. // Next character is not an integer or not a comma OR number of values > 2
  4295. // => end of list
  4296. if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
  4297. KMP_WARNING(EnvSyntaxError, name, value);
  4298. return;
  4299. }
  4300. // The next character is ','
  4301. if (*next == ',') {
  4302. // ',' is the first character
  4303. if (total == 0 || prev_comma) {
  4304. total++;
  4305. }
  4306. prev_comma = TRUE;
  4307. next++; // skip ','
  4308. SKIP_WS(next);
  4309. }
  4310. // Next character is a digit
  4311. if (*next >= '0' && *next <= '9') {
  4312. int num;
  4313. const char *buf = next;
  4314. char const *msg = NULL;
  4315. prev_comma = FALSE;
  4316. SKIP_DIGITS(next);
  4317. total++;
  4318. const char *tmp = next;
  4319. SKIP_WS(tmp);
  4320. if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
  4321. KMP_WARNING(EnvSpacesNotAllowed, name, value);
  4322. return;
  4323. }
  4324. num = __kmp_str_to_int(buf, *next);
  4325. if (num < 0) { // The number of retries should be >= 0
  4326. msg = KMP_I18N_STR(ValueTooSmall);
  4327. num = 1;
  4328. } else if (num > KMP_INT_MAX) {
  4329. msg = KMP_I18N_STR(ValueTooLarge);
  4330. num = KMP_INT_MAX;
  4331. }
  4332. if (msg != NULL) {
  4333. // Message is not empty. Print warning.
  4334. KMP_WARNING(ParseSizeIntWarn, name, value, msg);
  4335. KMP_INFORM(Using_int_Value, name, num);
  4336. }
  4337. if (total == 1) {
  4338. max_retries = num;
  4339. } else if (total == 2) {
  4340. max_badness = num;
  4341. }
  4342. }
  4343. }
  4344. KMP_DEBUG_ASSERT(total > 0);
  4345. if (total <= 0) {
  4346. KMP_WARNING(EnvSyntaxError, name, value);
  4347. return;
  4348. }
  4349. __kmp_adaptive_backoff_params.max_soft_retries = max_retries;
  4350. __kmp_adaptive_backoff_params.max_badness = max_badness;
  4351. }
  4352. static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer,
  4353. char const *name, void *data) {
  4354. if (__kmp_env_format) {
  4355. KMP_STR_BUF_PRINT_NAME_EX(name);
  4356. } else {
  4357. __kmp_str_buf_print(buffer, " %s='", name);
  4358. }
  4359. __kmp_str_buf_print(buffer, "%d,%d'\n",
  4360. __kmp_adaptive_backoff_params.max_soft_retries,
  4361. __kmp_adaptive_backoff_params.max_badness);
  4362. } // __kmp_stg_print_adaptive_lock_props
  4363. #if KMP_DEBUG_ADAPTIVE_LOCKS
  4364. static void __kmp_stg_parse_speculative_statsfile(char const *name,
  4365. char const *value,
  4366. void *data) {
  4367. __kmp_stg_parse_file(name, value, "",
  4368. CCAST(char **, &__kmp_speculative_statsfile));
  4369. } // __kmp_stg_parse_speculative_statsfile
  4370. static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer,
  4371. char const *name,
  4372. void *data) {
  4373. if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) {
  4374. __kmp_stg_print_str(buffer, name, "stdout");
  4375. } else {
  4376. __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile);
  4377. }
  4378. } // __kmp_stg_print_speculative_statsfile
  4379. #endif // KMP_DEBUG_ADAPTIVE_LOCKS
  4380. #endif // KMP_USE_ADAPTIVE_LOCKS
  4381. // -----------------------------------------------------------------------------
  4382. // KMP_HW_SUBSET (was KMP_PLACE_THREADS)
  4383. // 2s16c,2t => 2S16C,2T => 2S16C \0 2T
  4384. // Return KMP_HW_SUBSET preferred hardware type in case a token is ambiguously
  4385. // short. The original KMP_HW_SUBSET environment variable had single letters:
  4386. // s, c, t for sockets, cores, threads repsectively.
  4387. static kmp_hw_t __kmp_hw_subset_break_tie(const kmp_hw_t *possible,
  4388. size_t num_possible) {
  4389. for (size_t i = 0; i < num_possible; ++i) {
  4390. if (possible[i] == KMP_HW_THREAD)
  4391. return KMP_HW_THREAD;
  4392. else if (possible[i] == KMP_HW_CORE)
  4393. return KMP_HW_CORE;
  4394. else if (possible[i] == KMP_HW_SOCKET)
  4395. return KMP_HW_SOCKET;
  4396. }
  4397. return KMP_HW_UNKNOWN;
  4398. }
  4399. // Return hardware type from string or HW_UNKNOWN if string cannot be parsed
  4400. // This algorithm is very forgiving to the user in that, the instant it can
  4401. // reduce the search space to one, it assumes that is the topology level the
  4402. // user wanted, even if it is misspelled later in the token.
  4403. static kmp_hw_t __kmp_stg_parse_hw_subset_name(char const *token) {
  4404. size_t index, num_possible, token_length;
  4405. kmp_hw_t possible[KMP_HW_LAST];
  4406. const char *end;
  4407. // Find the end of the hardware token string
  4408. end = token;
  4409. token_length = 0;
  4410. while (isalnum(*end) || *end == '_') {
  4411. token_length++;
  4412. end++;
  4413. }
  4414. // Set the possibilities to all hardware types
  4415. num_possible = 0;
  4416. KMP_FOREACH_HW_TYPE(type) { possible[num_possible++] = type; }
  4417. // Eliminate hardware types by comparing the front of the token
  4418. // with hardware names
  4419. // In most cases, the first letter in the token will indicate exactly
  4420. // which hardware type is parsed, e.g., 'C' = Core
  4421. index = 0;
  4422. while (num_possible > 1 && index < token_length) {
  4423. size_t n = num_possible;
  4424. char token_char = (char)toupper(token[index]);
  4425. for (size_t i = 0; i < n; ++i) {
  4426. const char *s;
  4427. kmp_hw_t type = possible[i];
  4428. s = __kmp_hw_get_keyword(type, false);
  4429. if (index < KMP_STRLEN(s)) {
  4430. char c = (char)toupper(s[index]);
  4431. // Mark hardware types for removal when the characters do not match
  4432. if (c != token_char) {
  4433. possible[i] = KMP_HW_UNKNOWN;
  4434. num_possible--;
  4435. }
  4436. }
  4437. }
  4438. // Remove hardware types that this token cannot be
  4439. size_t start = 0;
  4440. for (size_t i = 0; i < n; ++i) {
  4441. if (possible[i] != KMP_HW_UNKNOWN) {
  4442. kmp_hw_t temp = possible[i];
  4443. possible[i] = possible[start];
  4444. possible[start] = temp;
  4445. start++;
  4446. }
  4447. }
  4448. KMP_ASSERT(start == num_possible);
  4449. index++;
  4450. }
  4451. // Attempt to break a tie if user has very short token
  4452. // (e.g., is 'T' tile or thread?)
  4453. if (num_possible > 1)
  4454. return __kmp_hw_subset_break_tie(possible, num_possible);
  4455. if (num_possible == 1)
  4456. return possible[0];
  4457. return KMP_HW_UNKNOWN;
  4458. }
  4459. // The longest observable sequence of items can only be HW_LAST length
  4460. // The input string is usually short enough, let's use 512 limit for now
  4461. #define MAX_T_LEVEL KMP_HW_LAST
  4462. #define MAX_STR_LEN 512
  4463. static void __kmp_stg_parse_hw_subset(char const *name, char const *value,
  4464. void *data) {
  4465. // Value example: 1s,5c@3,2T
  4466. // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
  4467. kmp_setting_t **rivals = (kmp_setting_t **)data;
  4468. if (strcmp(name, "KMP_PLACE_THREADS") == 0) {
  4469. KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET");
  4470. }
  4471. if (__kmp_stg_check_rivals(name, value, rivals)) {
  4472. return;
  4473. }
  4474. char *components[MAX_T_LEVEL];
  4475. char const *digits = "0123456789";
  4476. char input[MAX_STR_LEN];
  4477. size_t len = 0, mlen = MAX_STR_LEN;
  4478. int level = 0;
  4479. bool absolute = false;
  4480. // Canonicalize the string (remove spaces, unify delimiters, etc.)
  4481. char *pos = CCAST(char *, value);
  4482. while (*pos && mlen) {
  4483. if (*pos != ' ') { // skip spaces
  4484. if (len == 0 && *pos == ':') {
  4485. absolute = true;
  4486. } else {
  4487. input[len] = (char)(toupper(*pos));
  4488. if (input[len] == 'X')
  4489. input[len] = ','; // unify delimiters of levels
  4490. if (input[len] == 'O' && strchr(digits, *(pos + 1)))
  4491. input[len] = '@'; // unify delimiters of offset
  4492. len++;
  4493. }
  4494. }
  4495. mlen--;
  4496. pos++;
  4497. }
  4498. if (len == 0 || mlen == 0) {
  4499. goto err; // contents is either empty or too long
  4500. }
  4501. input[len] = '\0';
  4502. // Split by delimiter
  4503. pos = input;
  4504. components[level++] = pos;
  4505. while ((pos = strchr(pos, ','))) {
  4506. if (level >= MAX_T_LEVEL)
  4507. goto err; // too many components provided
  4508. *pos = '\0'; // modify input and avoid more copying
  4509. components[level++] = ++pos; // expect something after ","
  4510. }
  4511. __kmp_hw_subset = kmp_hw_subset_t::allocate();
  4512. if (absolute)
  4513. __kmp_hw_subset->set_absolute();
  4514. // Check each component
  4515. for (int i = 0; i < level; ++i) {
  4516. int core_level = 0;
  4517. char *core_components[MAX_T_LEVEL];
  4518. // Split possible core components by '&' delimiter
  4519. pos = components[i];
  4520. core_components[core_level++] = pos;
  4521. while ((pos = strchr(pos, '&'))) {
  4522. if (core_level >= MAX_T_LEVEL)
  4523. goto err; // too many different core types
  4524. *pos = '\0'; // modify input and avoid more copying
  4525. core_components[core_level++] = ++pos; // expect something after '&'
  4526. }
  4527. for (int j = 0; j < core_level; ++j) {
  4528. char *offset_ptr;
  4529. char *attr_ptr;
  4530. int offset = 0;
  4531. kmp_hw_attr_t attr;
  4532. int num;
  4533. // components may begin with an optional count of the number of resources
  4534. if (isdigit(*core_components[j])) {
  4535. num = atoi(core_components[j]);
  4536. if (num <= 0) {
  4537. goto err; // only positive integers are valid for count
  4538. }
  4539. pos = core_components[j] + strspn(core_components[j], digits);
  4540. } else if (*core_components[j] == '*') {
  4541. num = kmp_hw_subset_t::USE_ALL;
  4542. pos = core_components[j] + 1;
  4543. } else {
  4544. num = kmp_hw_subset_t::USE_ALL;
  4545. pos = core_components[j];
  4546. }
  4547. offset_ptr = strchr(core_components[j], '@');
  4548. attr_ptr = strchr(core_components[j], ':');
  4549. if (offset_ptr) {
  4550. offset = atoi(offset_ptr + 1); // save offset
  4551. *offset_ptr = '\0'; // cut the offset from the component
  4552. }
  4553. if (attr_ptr) {
  4554. attr.clear();
  4555. // save the attribute
  4556. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  4557. if (__kmp_str_match("intel_core", -1, attr_ptr + 1)) {
  4558. attr.set_core_type(KMP_HW_CORE_TYPE_CORE);
  4559. } else if (__kmp_str_match("intel_atom", -1, attr_ptr + 1)) {
  4560. attr.set_core_type(KMP_HW_CORE_TYPE_ATOM);
  4561. } else
  4562. #endif
  4563. if (__kmp_str_match("eff", 3, attr_ptr + 1)) {
  4564. const char *number = attr_ptr + 1;
  4565. // skip the eff[iciency] token
  4566. while (isalpha(*number))
  4567. number++;
  4568. if (!isdigit(*number)) {
  4569. goto err;
  4570. }
  4571. int efficiency = atoi(number);
  4572. attr.set_core_eff(efficiency);
  4573. } else {
  4574. goto err;
  4575. }
  4576. *attr_ptr = '\0'; // cut the attribute from the component
  4577. }
  4578. // detect the component type
  4579. kmp_hw_t type = __kmp_stg_parse_hw_subset_name(pos);
  4580. if (type == KMP_HW_UNKNOWN) {
  4581. goto err;
  4582. }
  4583. // Only the core type can have attributes
  4584. if (attr && type != KMP_HW_CORE)
  4585. goto err;
  4586. // Must allow core be specified more than once
  4587. if (type != KMP_HW_CORE && __kmp_hw_subset->specified(type)) {
  4588. goto err;
  4589. }
  4590. __kmp_hw_subset->push_back(num, type, offset, attr);
  4591. }
  4592. }
  4593. return;
  4594. err:
  4595. KMP_WARNING(AffHWSubsetInvalid, name, value);
  4596. if (__kmp_hw_subset) {
  4597. kmp_hw_subset_t::deallocate(__kmp_hw_subset);
  4598. __kmp_hw_subset = nullptr;
  4599. }
  4600. return;
  4601. }
  4602. static inline const char *
  4603. __kmp_hw_get_core_type_keyword(kmp_hw_core_type_t type) {
  4604. switch (type) {
  4605. case KMP_HW_CORE_TYPE_UNKNOWN:
  4606. return "unknown";
  4607. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  4608. case KMP_HW_CORE_TYPE_ATOM:
  4609. return "intel_atom";
  4610. case KMP_HW_CORE_TYPE_CORE:
  4611. return "intel_core";
  4612. #endif
  4613. }
  4614. return "unknown";
  4615. }
  4616. static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name,
  4617. void *data) {
  4618. kmp_str_buf_t buf;
  4619. int depth;
  4620. if (!__kmp_hw_subset)
  4621. return;
  4622. __kmp_str_buf_init(&buf);
  4623. if (__kmp_env_format)
  4624. KMP_STR_BUF_PRINT_NAME_EX(name);
  4625. else
  4626. __kmp_str_buf_print(buffer, " %s='", name);
  4627. depth = __kmp_hw_subset->get_depth();
  4628. for (int i = 0; i < depth; ++i) {
  4629. const auto &item = __kmp_hw_subset->at(i);
  4630. if (i > 0)
  4631. __kmp_str_buf_print(&buf, "%c", ',');
  4632. for (int j = 0; j < item.num_attrs; ++j) {
  4633. __kmp_str_buf_print(&buf, "%s%d%s", (j > 0 ? "&" : ""), item.num[j],
  4634. __kmp_hw_get_keyword(item.type));
  4635. if (item.attr[j].is_core_type_valid())
  4636. __kmp_str_buf_print(
  4637. &buf, ":%s",
  4638. __kmp_hw_get_core_type_keyword(item.attr[j].get_core_type()));
  4639. if (item.attr[j].is_core_eff_valid())
  4640. __kmp_str_buf_print(&buf, ":eff%d", item.attr[j].get_core_eff());
  4641. if (item.offset[j])
  4642. __kmp_str_buf_print(&buf, "@%d", item.offset[j]);
  4643. }
  4644. }
  4645. __kmp_str_buf_print(buffer, "%s'\n", buf.str);
  4646. __kmp_str_buf_free(&buf);
  4647. }
  4648. #if USE_ITT_BUILD
  4649. // -----------------------------------------------------------------------------
  4650. // KMP_FORKJOIN_FRAMES
  4651. static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value,
  4652. void *data) {
  4653. __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames);
  4654. } // __kmp_stg_parse_forkjoin_frames
  4655. static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer,
  4656. char const *name, void *data) {
  4657. __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames);
  4658. } // __kmp_stg_print_forkjoin_frames
  4659. // -----------------------------------------------------------------------------
  4660. // KMP_FORKJOIN_FRAMES_MODE
  4661. static void __kmp_stg_parse_forkjoin_frames_mode(char const *name,
  4662. char const *value,
  4663. void *data) {
  4664. __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode);
  4665. } // __kmp_stg_parse_forkjoin_frames
  4666. static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer,
  4667. char const *name, void *data) {
  4668. __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode);
  4669. } // __kmp_stg_print_forkjoin_frames
  4670. #endif /* USE_ITT_BUILD */
  4671. // -----------------------------------------------------------------------------
  4672. // KMP_ENABLE_TASK_THROTTLING
  4673. static void __kmp_stg_parse_task_throttling(char const *name, char const *value,
  4674. void *data) {
  4675. __kmp_stg_parse_bool(name, value, &__kmp_enable_task_throttling);
  4676. } // __kmp_stg_parse_task_throttling
  4677. static void __kmp_stg_print_task_throttling(kmp_str_buf_t *buffer,
  4678. char const *name, void *data) {
  4679. __kmp_stg_print_bool(buffer, name, __kmp_enable_task_throttling);
  4680. } // __kmp_stg_print_task_throttling
  4681. #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
  4682. // -----------------------------------------------------------------------------
  4683. // KMP_USER_LEVEL_MWAIT
  4684. static void __kmp_stg_parse_user_level_mwait(char const *name,
  4685. char const *value, void *data) {
  4686. __kmp_stg_parse_bool(name, value, &__kmp_user_level_mwait);
  4687. } // __kmp_stg_parse_user_level_mwait
  4688. static void __kmp_stg_print_user_level_mwait(kmp_str_buf_t *buffer,
  4689. char const *name, void *data) {
  4690. __kmp_stg_print_bool(buffer, name, __kmp_user_level_mwait);
  4691. } // __kmp_stg_print_user_level_mwait
  4692. // -----------------------------------------------------------------------------
  4693. // KMP_MWAIT_HINTS
  4694. static void __kmp_stg_parse_mwait_hints(char const *name, char const *value,
  4695. void *data) {
  4696. __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_mwait_hints);
  4697. } // __kmp_stg_parse_mwait_hints
  4698. static void __kmp_stg_print_mwait_hints(kmp_str_buf_t *buffer, char const *name,
  4699. void *data) {
  4700. __kmp_stg_print_int(buffer, name, __kmp_mwait_hints);
  4701. } // __kmp_stg_print_mwait_hints
  4702. #endif // KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
  4703. #if KMP_HAVE_UMWAIT
  4704. // -----------------------------------------------------------------------------
  4705. // KMP_TPAUSE
  4706. // 0 = don't use TPAUSE, 1 = use C0.1 state, 2 = use C0.2 state
  4707. static void __kmp_stg_parse_tpause(char const *name, char const *value,
  4708. void *data) {
  4709. __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_tpause_state);
  4710. if (__kmp_tpause_state != 0) {
  4711. // The actual hint passed to tpause is: 0 for C0.2 and 1 for C0.1
  4712. if (__kmp_tpause_state == 2) // use C0.2
  4713. __kmp_tpause_hint = 0; // default was set to 1 for C0.1
  4714. }
  4715. } // __kmp_stg_parse_tpause
  4716. static void __kmp_stg_print_tpause(kmp_str_buf_t *buffer, char const *name,
  4717. void *data) {
  4718. __kmp_stg_print_int(buffer, name, __kmp_tpause_state);
  4719. } // __kmp_stg_print_tpause
  4720. #endif // KMP_HAVE_UMWAIT
  4721. // -----------------------------------------------------------------------------
  4722. // OMP_DISPLAY_ENV
  4723. static void __kmp_stg_parse_omp_display_env(char const *name, char const *value,
  4724. void *data) {
  4725. if (__kmp_str_match("VERBOSE", 1, value)) {
  4726. __kmp_display_env_verbose = TRUE;
  4727. } else {
  4728. __kmp_stg_parse_bool(name, value, &__kmp_display_env);
  4729. }
  4730. } // __kmp_stg_parse_omp_display_env
  4731. static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer,
  4732. char const *name, void *data) {
  4733. if (__kmp_display_env_verbose) {
  4734. __kmp_stg_print_str(buffer, name, "VERBOSE");
  4735. } else {
  4736. __kmp_stg_print_bool(buffer, name, __kmp_display_env);
  4737. }
  4738. } // __kmp_stg_print_omp_display_env
  4739. static void __kmp_stg_parse_omp_cancellation(char const *name,
  4740. char const *value, void *data) {
  4741. if (TCR_4(__kmp_init_parallel)) {
  4742. KMP_WARNING(EnvParallelWarn, name);
  4743. return;
  4744. } // read value before first parallel only
  4745. __kmp_stg_parse_bool(name, value, &__kmp_omp_cancellation);
  4746. } // __kmp_stg_parse_omp_cancellation
  4747. static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer,
  4748. char const *name, void *data) {
  4749. __kmp_stg_print_bool(buffer, name, __kmp_omp_cancellation);
  4750. } // __kmp_stg_print_omp_cancellation
  4751. #if OMPT_SUPPORT
  4752. int __kmp_tool = 1;
  4753. static void __kmp_stg_parse_omp_tool(char const *name, char const *value,
  4754. void *data) {
  4755. __kmp_stg_parse_bool(name, value, &__kmp_tool);
  4756. } // __kmp_stg_parse_omp_tool
  4757. static void __kmp_stg_print_omp_tool(kmp_str_buf_t *buffer, char const *name,
  4758. void *data) {
  4759. if (__kmp_env_format) {
  4760. KMP_STR_BUF_PRINT_BOOL_EX(name, __kmp_tool, "enabled", "disabled");
  4761. } else {
  4762. __kmp_str_buf_print(buffer, " %s=%s\n", name,
  4763. __kmp_tool ? "enabled" : "disabled");
  4764. }
  4765. } // __kmp_stg_print_omp_tool
  4766. char *__kmp_tool_libraries = NULL;
  4767. static void __kmp_stg_parse_omp_tool_libraries(char const *name,
  4768. char const *value, void *data) {
  4769. __kmp_stg_parse_str(name, value, &__kmp_tool_libraries);
  4770. } // __kmp_stg_parse_omp_tool_libraries
  4771. static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer,
  4772. char const *name, void *data) {
  4773. if (__kmp_tool_libraries)
  4774. __kmp_stg_print_str(buffer, name, __kmp_tool_libraries);
  4775. else {
  4776. if (__kmp_env_format) {
  4777. KMP_STR_BUF_PRINT_NAME;
  4778. } else {
  4779. __kmp_str_buf_print(buffer, " %s", name);
  4780. }
  4781. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  4782. }
  4783. } // __kmp_stg_print_omp_tool_libraries
  4784. char *__kmp_tool_verbose_init = NULL;
  4785. static void __kmp_stg_parse_omp_tool_verbose_init(char const *name,
  4786. char const *value,
  4787. void *data) {
  4788. __kmp_stg_parse_str(name, value, &__kmp_tool_verbose_init);
  4789. } // __kmp_stg_parse_omp_tool_libraries
  4790. static void __kmp_stg_print_omp_tool_verbose_init(kmp_str_buf_t *buffer,
  4791. char const *name,
  4792. void *data) {
  4793. if (__kmp_tool_verbose_init)
  4794. __kmp_stg_print_str(buffer, name, __kmp_tool_verbose_init);
  4795. else {
  4796. if (__kmp_env_format) {
  4797. KMP_STR_BUF_PRINT_NAME;
  4798. } else {
  4799. __kmp_str_buf_print(buffer, " %s", name);
  4800. }
  4801. __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
  4802. }
  4803. } // __kmp_stg_print_omp_tool_verbose_init
  4804. #endif
  4805. // Table.
  4806. static kmp_setting_t __kmp_stg_table[] = {
  4807. {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0},
  4808. {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime,
  4809. NULL, 0, 0},
  4810. {"KMP_USE_YIELD", __kmp_stg_parse_use_yield, __kmp_stg_print_use_yield,
  4811. NULL, 0, 0},
  4812. {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok,
  4813. __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0},
  4814. {"KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy,
  4815. NULL, 0, 0},
  4816. {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit,
  4817. __kmp_stg_print_device_thread_limit, NULL, 0, 0},
  4818. #if KMP_USE_MONITOR
  4819. {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize,
  4820. __kmp_stg_print_monitor_stacksize, NULL, 0, 0},
  4821. #endif
  4822. {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL,
  4823. 0, 0},
  4824. {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset,
  4825. __kmp_stg_print_stackoffset, NULL, 0, 0},
  4826. {"KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
  4827. NULL, 0, 0},
  4828. {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL,
  4829. 0, 0},
  4830. {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0,
  4831. 0},
  4832. {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL,
  4833. 0, 0},
  4834. {"KMP_NESTING_MODE", __kmp_stg_parse_nesting_mode,
  4835. __kmp_stg_print_nesting_mode, NULL, 0, 0},
  4836. {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0},
  4837. {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads,
  4838. __kmp_stg_print_num_threads, NULL, 0, 0},
  4839. {"OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
  4840. NULL, 0, 0},
  4841. {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0,
  4842. 0},
  4843. {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing,
  4844. __kmp_stg_print_task_stealing, NULL, 0, 0},
  4845. {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels,
  4846. __kmp_stg_print_max_active_levels, NULL, 0, 0},
  4847. {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device,
  4848. __kmp_stg_print_default_device, NULL, 0, 0},
  4849. {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload,
  4850. __kmp_stg_print_target_offload, NULL, 0, 0},
  4851. {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority,
  4852. __kmp_stg_print_max_task_priority, NULL, 0, 0},
  4853. {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks,
  4854. __kmp_stg_print_taskloop_min_tasks, NULL, 0, 0},
  4855. {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit,
  4856. __kmp_stg_print_thread_limit, NULL, 0, 0},
  4857. {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit,
  4858. __kmp_stg_print_teams_thread_limit, NULL, 0, 0},
  4859. {"OMP_NUM_TEAMS", __kmp_stg_parse_nteams, __kmp_stg_print_nteams, NULL, 0,
  4860. 0},
  4861. {"OMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_th_limit,
  4862. __kmp_stg_print_teams_th_limit, NULL, 0, 0},
  4863. {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy,
  4864. __kmp_stg_print_wait_policy, NULL, 0, 0},
  4865. {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers,
  4866. __kmp_stg_print_disp_buffers, NULL, 0, 0},
  4867. #if KMP_NESTED_HOT_TEAMS
  4868. {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level,
  4869. __kmp_stg_print_hot_teams_level, NULL, 0, 0},
  4870. {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode,
  4871. __kmp_stg_print_hot_teams_mode, NULL, 0, 0},
  4872. #endif // KMP_NESTED_HOT_TEAMS
  4873. #if KMP_HANDLE_SIGNALS
  4874. {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals,
  4875. __kmp_stg_print_handle_signals, NULL, 0, 0},
  4876. #endif
  4877. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  4878. {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control,
  4879. __kmp_stg_print_inherit_fp_control, NULL, 0, 0},
  4880. #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
  4881. #ifdef KMP_GOMP_COMPAT
  4882. {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0},
  4883. #endif
  4884. #ifdef KMP_DEBUG
  4885. {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0,
  4886. 0},
  4887. {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0,
  4888. 0},
  4889. {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0,
  4890. 0},
  4891. {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0,
  4892. 0},
  4893. {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0,
  4894. 0},
  4895. {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0,
  4896. 0},
  4897. {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0},
  4898. {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf,
  4899. NULL, 0, 0},
  4900. {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic,
  4901. __kmp_stg_print_debug_buf_atomic, NULL, 0, 0},
  4902. {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars,
  4903. __kmp_stg_print_debug_buf_chars, NULL, 0, 0},
  4904. {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines,
  4905. __kmp_stg_print_debug_buf_lines, NULL, 0, 0},
  4906. {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0},
  4907. {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env,
  4908. __kmp_stg_print_par_range_env, NULL, 0, 0},
  4909. #endif // KMP_DEBUG
  4910. {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc,
  4911. __kmp_stg_print_align_alloc, NULL, 0, 0},
  4912. {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
  4913. __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
  4914. {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
  4915. __kmp_stg_print_barrier_pattern, NULL, 0, 0},
  4916. {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
  4917. __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
  4918. {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
  4919. __kmp_stg_print_barrier_pattern, NULL, 0, 0},
  4920. #if KMP_FAST_REDUCTION_BARRIER
  4921. {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit,
  4922. __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
  4923. {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
  4924. __kmp_stg_print_barrier_pattern, NULL, 0, 0},
  4925. #endif
  4926. {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay,
  4927. __kmp_stg_print_abort_delay, NULL, 0, 0},
  4928. {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file,
  4929. __kmp_stg_print_cpuinfo_file, NULL, 0, 0},
  4930. {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction,
  4931. __kmp_stg_print_force_reduction, NULL, 0, 0},
  4932. {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction,
  4933. __kmp_stg_print_force_reduction, NULL, 0, 0},
  4934. {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map,
  4935. __kmp_stg_print_storage_map, NULL, 0, 0},
  4936. {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate,
  4937. __kmp_stg_print_all_threadprivate, NULL, 0, 0},
  4938. {"KMP_FOREIGN_THREADS_THREADPRIVATE",
  4939. __kmp_stg_parse_foreign_threads_threadprivate,
  4940. __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0},
  4941. #if KMP_AFFINITY_SUPPORTED
  4942. {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL,
  4943. 0, 0},
  4944. #ifdef KMP_GOMP_COMPAT
  4945. {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL,
  4946. /* no print */ NULL, 0, 0},
  4947. #endif /* KMP_GOMP_COMPAT */
  4948. {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
  4949. NULL, 0, 0},
  4950. {"KMP_TEAMS_PROC_BIND", __kmp_stg_parse_teams_proc_bind,
  4951. __kmp_stg_print_teams_proc_bind, NULL, 0, 0},
  4952. {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0},
  4953. {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method,
  4954. __kmp_stg_print_topology_method, NULL, 0, 0},
  4955. #else
  4956. // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
  4957. // OMP_PROC_BIND and proc-bind-var are supported, however.
  4958. {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
  4959. NULL, 0, 0},
  4960. #endif // KMP_AFFINITY_SUPPORTED
  4961. {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity,
  4962. __kmp_stg_print_display_affinity, NULL, 0, 0},
  4963. {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format,
  4964. __kmp_stg_print_affinity_format, NULL, 0, 0},
  4965. {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork,
  4966. __kmp_stg_print_init_at_fork, NULL, 0, 0},
  4967. {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL,
  4968. 0, 0},
  4969. {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule,
  4970. NULL, 0, 0},
  4971. #if KMP_USE_HIER_SCHED
  4972. {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread,
  4973. __kmp_stg_print_kmp_hand_thread, NULL, 0, 0},
  4974. #endif
  4975. {"KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE",
  4976. __kmp_stg_parse_kmp_force_monotonic, __kmp_stg_print_kmp_force_monotonic,
  4977. NULL, 0, 0},
  4978. {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode,
  4979. __kmp_stg_print_atomic_mode, NULL, 0, 0},
  4980. {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check,
  4981. __kmp_stg_print_consistency_check, NULL, 0, 0},
  4982. #if USE_ITT_BUILD && USE_ITT_NOTIFY
  4983. {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay,
  4984. __kmp_stg_print_itt_prepare_delay, NULL, 0, 0},
  4985. #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
  4986. {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr,
  4987. __kmp_stg_print_malloc_pool_incr, NULL, 0, 0},
  4988. {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode,
  4989. NULL, 0, 0},
  4990. {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic,
  4991. NULL, 0, 0},
  4992. {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode,
  4993. __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0},
  4994. #ifdef USE_LOAD_BALANCE
  4995. {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,
  4996. __kmp_stg_print_ld_balance_interval, NULL, 0, 0},
  4997. #endif
  4998. {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block,
  4999. __kmp_stg_print_lock_block, NULL, 0, 0},
  5000. {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind,
  5001. NULL, 0, 0},
  5002. {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params,
  5003. __kmp_stg_print_spin_backoff_params, NULL, 0, 0},
  5004. #if KMP_USE_ADAPTIVE_LOCKS
  5005. {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,
  5006. __kmp_stg_print_adaptive_lock_props, NULL, 0, 0},
  5007. #if KMP_DEBUG_ADAPTIVE_LOCKS
  5008. {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,
  5009. __kmp_stg_print_speculative_statsfile, NULL, 0, 0},
  5010. #endif
  5011. #endif // KMP_USE_ADAPTIVE_LOCKS
  5012. {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
  5013. NULL, 0, 0},
  5014. {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
  5015. NULL, 0, 0},
  5016. #if USE_ITT_BUILD
  5017. {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames,
  5018. __kmp_stg_print_forkjoin_frames, NULL, 0, 0},
  5019. {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,
  5020. __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0},
  5021. #endif
  5022. {"KMP_ENABLE_TASK_THROTTLING", __kmp_stg_parse_task_throttling,
  5023. __kmp_stg_print_task_throttling, NULL, 0, 0},
  5024. {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env,
  5025. __kmp_stg_print_omp_display_env, NULL, 0, 0},
  5026. {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation,
  5027. __kmp_stg_print_omp_cancellation, NULL, 0, 0},
  5028. {"OMP_ALLOCATOR", __kmp_stg_parse_allocator, __kmp_stg_print_allocator,
  5029. NULL, 0, 0},
  5030. {"LIBOMP_USE_HIDDEN_HELPER_TASK", __kmp_stg_parse_use_hidden_helper,
  5031. __kmp_stg_print_use_hidden_helper, NULL, 0, 0},
  5032. {"LIBOMP_NUM_HIDDEN_HELPER_THREADS",
  5033. __kmp_stg_parse_num_hidden_helper_threads,
  5034. __kmp_stg_print_num_hidden_helper_threads, NULL, 0, 0},
  5035. #if OMPT_SUPPORT
  5036. {"OMP_TOOL", __kmp_stg_parse_omp_tool, __kmp_stg_print_omp_tool, NULL, 0,
  5037. 0},
  5038. {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries,
  5039. __kmp_stg_print_omp_tool_libraries, NULL, 0, 0},
  5040. {"OMP_TOOL_VERBOSE_INIT", __kmp_stg_parse_omp_tool_verbose_init,
  5041. __kmp_stg_print_omp_tool_verbose_init, NULL, 0, 0},
  5042. #endif
  5043. #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
  5044. {"KMP_USER_LEVEL_MWAIT", __kmp_stg_parse_user_level_mwait,
  5045. __kmp_stg_print_user_level_mwait, NULL, 0, 0},
  5046. {"KMP_MWAIT_HINTS", __kmp_stg_parse_mwait_hints,
  5047. __kmp_stg_print_mwait_hints, NULL, 0, 0},
  5048. #endif
  5049. #if KMP_HAVE_UMWAIT
  5050. {"KMP_TPAUSE", __kmp_stg_parse_tpause, __kmp_stg_print_tpause, NULL, 0, 0},
  5051. #endif
  5052. {"", NULL, NULL, NULL, 0, 0}}; // settings
  5053. static int const __kmp_stg_count =
  5054. sizeof(__kmp_stg_table) / sizeof(kmp_setting_t);
  5055. static inline kmp_setting_t *__kmp_stg_find(char const *name) {
  5056. int i;
  5057. if (name != NULL) {
  5058. for (i = 0; i < __kmp_stg_count; ++i) {
  5059. if (strcmp(__kmp_stg_table[i].name, name) == 0) {
  5060. return &__kmp_stg_table[i];
  5061. }
  5062. }
  5063. }
  5064. return NULL;
  5065. } // __kmp_stg_find
  5066. static int __kmp_stg_cmp(void const *_a, void const *_b) {
  5067. const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a);
  5068. const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b);
  5069. // Process KMP_AFFINITY last.
  5070. // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
  5071. if (strcmp(a->name, "KMP_AFFINITY") == 0) {
  5072. if (strcmp(b->name, "KMP_AFFINITY") == 0) {
  5073. return 0;
  5074. }
  5075. return 1;
  5076. } else if (strcmp(b->name, "KMP_AFFINITY") == 0) {
  5077. return -1;
  5078. }
  5079. return strcmp(a->name, b->name);
  5080. } // __kmp_stg_cmp
  5081. static void __kmp_stg_init(void) {
  5082. static int initialized = 0;
  5083. if (!initialized) {
  5084. // Sort table.
  5085. qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t),
  5086. __kmp_stg_cmp);
  5087. { // Initialize *_STACKSIZE data.
  5088. kmp_setting_t *kmp_stacksize =
  5089. __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
  5090. #ifdef KMP_GOMP_COMPAT
  5091. kmp_setting_t *gomp_stacksize =
  5092. __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
  5093. #endif
  5094. kmp_setting_t *omp_stacksize =
  5095. __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
  5096. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5097. // !!! Compiler does not understand rivals is used and optimizes out
  5098. // assignments
  5099. // !!! rivals[ i ++ ] = ...;
  5100. static kmp_setting_t *volatile rivals[4];
  5101. static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)};
  5102. #ifdef KMP_GOMP_COMPAT
  5103. static kmp_stg_ss_data_t gomp_data = {1024,
  5104. CCAST(kmp_setting_t **, rivals)};
  5105. #endif
  5106. static kmp_stg_ss_data_t omp_data = {1024,
  5107. CCAST(kmp_setting_t **, rivals)};
  5108. int i = 0;
  5109. rivals[i++] = kmp_stacksize;
  5110. #ifdef KMP_GOMP_COMPAT
  5111. if (gomp_stacksize != NULL) {
  5112. rivals[i++] = gomp_stacksize;
  5113. }
  5114. #endif
  5115. rivals[i++] = omp_stacksize;
  5116. rivals[i++] = NULL;
  5117. kmp_stacksize->data = &kmp_data;
  5118. #ifdef KMP_GOMP_COMPAT
  5119. if (gomp_stacksize != NULL) {
  5120. gomp_stacksize->data = &gomp_data;
  5121. }
  5122. #endif
  5123. omp_stacksize->data = &omp_data;
  5124. }
  5125. { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
  5126. kmp_setting_t *kmp_library =
  5127. __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
  5128. kmp_setting_t *omp_wait_policy =
  5129. __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
  5130. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5131. static kmp_setting_t *volatile rivals[3];
  5132. static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)};
  5133. static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)};
  5134. int i = 0;
  5135. rivals[i++] = kmp_library;
  5136. if (omp_wait_policy != NULL) {
  5137. rivals[i++] = omp_wait_policy;
  5138. }
  5139. rivals[i++] = NULL;
  5140. kmp_library->data = &kmp_data;
  5141. if (omp_wait_policy != NULL) {
  5142. omp_wait_policy->data = &omp_data;
  5143. }
  5144. }
  5145. { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
  5146. kmp_setting_t *kmp_device_thread_limit =
  5147. __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
  5148. kmp_setting_t *kmp_all_threads =
  5149. __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
  5150. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5151. static kmp_setting_t *volatile rivals[3];
  5152. int i = 0;
  5153. rivals[i++] = kmp_device_thread_limit;
  5154. rivals[i++] = kmp_all_threads;
  5155. rivals[i++] = NULL;
  5156. kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals);
  5157. kmp_all_threads->data = CCAST(kmp_setting_t **, rivals);
  5158. }
  5159. { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
  5160. // 1st priority
  5161. kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET");
  5162. // 2nd priority
  5163. kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS");
  5164. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5165. static kmp_setting_t *volatile rivals[3];
  5166. int i = 0;
  5167. rivals[i++] = kmp_hw_subset;
  5168. rivals[i++] = kmp_place_threads;
  5169. rivals[i++] = NULL;
  5170. kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals);
  5171. kmp_place_threads->data = CCAST(kmp_setting_t **, rivals);
  5172. }
  5173. #if KMP_AFFINITY_SUPPORTED
  5174. { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
  5175. kmp_setting_t *kmp_affinity =
  5176. __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
  5177. KMP_DEBUG_ASSERT(kmp_affinity != NULL);
  5178. #ifdef KMP_GOMP_COMPAT
  5179. kmp_setting_t *gomp_cpu_affinity =
  5180. __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
  5181. KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL);
  5182. #endif
  5183. kmp_setting_t *omp_proc_bind =
  5184. __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
  5185. KMP_DEBUG_ASSERT(omp_proc_bind != NULL);
  5186. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5187. static kmp_setting_t *volatile rivals[4];
  5188. int i = 0;
  5189. rivals[i++] = kmp_affinity;
  5190. #ifdef KMP_GOMP_COMPAT
  5191. rivals[i++] = gomp_cpu_affinity;
  5192. gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals);
  5193. #endif
  5194. rivals[i++] = omp_proc_bind;
  5195. omp_proc_bind->data = CCAST(kmp_setting_t **, rivals);
  5196. rivals[i++] = NULL;
  5197. static kmp_setting_t *volatile places_rivals[4];
  5198. i = 0;
  5199. kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority.
  5200. KMP_DEBUG_ASSERT(omp_places != NULL);
  5201. places_rivals[i++] = kmp_affinity;
  5202. #ifdef KMP_GOMP_COMPAT
  5203. places_rivals[i++] = gomp_cpu_affinity;
  5204. #endif
  5205. places_rivals[i++] = omp_places;
  5206. omp_places->data = CCAST(kmp_setting_t **, places_rivals);
  5207. places_rivals[i++] = NULL;
  5208. }
  5209. #else
  5210. // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
  5211. // OMP_PLACES not supported yet.
  5212. #endif // KMP_AFFINITY_SUPPORTED
  5213. { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
  5214. kmp_setting_t *kmp_force_red =
  5215. __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
  5216. kmp_setting_t *kmp_determ_red =
  5217. __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
  5218. // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
  5219. static kmp_setting_t *volatile rivals[3];
  5220. static kmp_stg_fr_data_t force_data = {1,
  5221. CCAST(kmp_setting_t **, rivals)};
  5222. static kmp_stg_fr_data_t determ_data = {0,
  5223. CCAST(kmp_setting_t **, rivals)};
  5224. int i = 0;
  5225. rivals[i++] = kmp_force_red;
  5226. if (kmp_determ_red != NULL) {
  5227. rivals[i++] = kmp_determ_red;
  5228. }
  5229. rivals[i++] = NULL;
  5230. kmp_force_red->data = &force_data;
  5231. if (kmp_determ_red != NULL) {
  5232. kmp_determ_red->data = &determ_data;
  5233. }
  5234. }
  5235. initialized = 1;
  5236. }
  5237. // Reset flags.
  5238. int i;
  5239. for (i = 0; i < __kmp_stg_count; ++i) {
  5240. __kmp_stg_table[i].set = 0;
  5241. }
  5242. } // __kmp_stg_init
  5243. static void __kmp_stg_parse(char const *name, char const *value) {
  5244. // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
  5245. // really nameless, they are presented in environment block as
  5246. // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
  5247. if (name[0] == 0) {
  5248. return;
  5249. }
  5250. if (value != NULL) {
  5251. kmp_setting_t *setting = __kmp_stg_find(name);
  5252. if (setting != NULL) {
  5253. setting->parse(name, value, setting->data);
  5254. setting->defined = 1;
  5255. }
  5256. }
  5257. } // __kmp_stg_parse
  5258. static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
  5259. char const *name, // Name of variable.
  5260. char const *value, // Value of the variable.
  5261. kmp_setting_t **rivals // List of rival settings (must include current one).
  5262. ) {
  5263. if (rivals == NULL) {
  5264. return 0;
  5265. }
  5266. // Loop thru higher priority settings (listed before current).
  5267. int i = 0;
  5268. for (; strcmp(rivals[i]->name, name) != 0; i++) {
  5269. KMP_DEBUG_ASSERT(rivals[i] != NULL);
  5270. #if KMP_AFFINITY_SUPPORTED
  5271. if (rivals[i] == __kmp_affinity_notype) {
  5272. // If KMP_AFFINITY is specified without a type name,
  5273. // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
  5274. continue;
  5275. }
  5276. #endif
  5277. if (rivals[i]->set) {
  5278. KMP_WARNING(StgIgnored, name, rivals[i]->name);
  5279. return 1;
  5280. }
  5281. }
  5282. ++i; // Skip current setting.
  5283. return 0;
  5284. } // __kmp_stg_check_rivals
  5285. static int __kmp_env_toPrint(char const *name, int flag) {
  5286. int rc = 0;
  5287. kmp_setting_t *setting = __kmp_stg_find(name);
  5288. if (setting != NULL) {
  5289. rc = setting->defined;
  5290. if (flag >= 0) {
  5291. setting->defined = flag;
  5292. }
  5293. }
  5294. return rc;
  5295. }
  5296. static void __kmp_aux_env_initialize(kmp_env_blk_t *block) {
  5297. char const *value;
  5298. /* OMP_NUM_THREADS */
  5299. value = __kmp_env_blk_var(block, "OMP_NUM_THREADS");
  5300. if (value) {
  5301. ompc_set_num_threads(__kmp_dflt_team_nth);
  5302. }
  5303. /* KMP_BLOCKTIME */
  5304. value = __kmp_env_blk_var(block, "KMP_BLOCKTIME");
  5305. if (value) {
  5306. kmpc_set_blocktime(__kmp_dflt_blocktime);
  5307. }
  5308. /* OMP_NESTED */
  5309. value = __kmp_env_blk_var(block, "OMP_NESTED");
  5310. if (value) {
  5311. ompc_set_nested(__kmp_dflt_max_active_levels > 1);
  5312. }
  5313. /* OMP_DYNAMIC */
  5314. value = __kmp_env_blk_var(block, "OMP_DYNAMIC");
  5315. if (value) {
  5316. ompc_set_dynamic(__kmp_global.g.g_dynamic);
  5317. }
  5318. }
  5319. void __kmp_env_initialize(char const *string) {
  5320. kmp_env_blk_t block;
  5321. int i;
  5322. __kmp_stg_init();
  5323. // Hack!!!
  5324. if (string == NULL) {
  5325. // __kmp_max_nth = __kmp_sys_max_nth;
  5326. __kmp_threads_capacity =
  5327. __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub);
  5328. }
  5329. __kmp_env_blk_init(&block, string);
  5330. // update the set flag on all entries that have an env var
  5331. for (i = 0; i < block.count; ++i) {
  5332. if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) {
  5333. continue;
  5334. }
  5335. if (block.vars[i].value == NULL) {
  5336. continue;
  5337. }
  5338. kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name);
  5339. if (setting != NULL) {
  5340. setting->set = 1;
  5341. }
  5342. }
  5343. // We need to know if blocktime was set when processing OMP_WAIT_POLICY
  5344. blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME");
  5345. // Special case. If we parse environment, not a string, process KMP_WARNINGS
  5346. // first.
  5347. if (string == NULL) {
  5348. char const *name = "KMP_WARNINGS";
  5349. char const *value = __kmp_env_blk_var(&block, name);
  5350. __kmp_stg_parse(name, value);
  5351. }
  5352. #if KMP_AFFINITY_SUPPORTED
  5353. // Special case. KMP_AFFINITY is not a rival to other affinity env vars
  5354. // if no affinity type is specified. We want to allow
  5355. // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
  5356. // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
  5357. // affinity mechanism.
  5358. __kmp_affinity_notype = NULL;
  5359. char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY");
  5360. if (aff_str != NULL) {
  5361. // Check if the KMP_AFFINITY type is specified in the string.
  5362. // We just search the string for "compact", "scatter", etc.
  5363. // without really parsing the string. The syntax of the
  5364. // KMP_AFFINITY env var is such that none of the affinity
  5365. // type names can appear anywhere other that the type
  5366. // specifier, even as substrings.
  5367. //
  5368. // I can't find a case-insensitive version of strstr on Windows* OS.
  5369. // Use the case-sensitive version for now.
  5370. #if KMP_OS_WINDOWS
  5371. #define FIND strstr
  5372. #else
  5373. #define FIND strcasestr
  5374. #endif
  5375. if ((FIND(aff_str, "none") == NULL) &&
  5376. (FIND(aff_str, "physical") == NULL) &&
  5377. (FIND(aff_str, "logical") == NULL) &&
  5378. (FIND(aff_str, "compact") == NULL) &&
  5379. (FIND(aff_str, "scatter") == NULL) &&
  5380. (FIND(aff_str, "explicit") == NULL) &&
  5381. (FIND(aff_str, "balanced") == NULL) &&
  5382. (FIND(aff_str, "disabled") == NULL)) {
  5383. __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY");
  5384. } else {
  5385. // A new affinity type is specified.
  5386. // Reset the affinity flags to their default values,
  5387. // in case this is called from kmp_set_defaults().
  5388. __kmp_affinity_type = affinity_default;
  5389. __kmp_affinity_gran = KMP_HW_UNKNOWN;
  5390. __kmp_affinity_top_method = affinity_top_method_default;
  5391. __kmp_affinity_respect_mask = affinity_respect_mask_default;
  5392. }
  5393. #undef FIND
  5394. // Also reset the affinity flags if OMP_PROC_BIND is specified.
  5395. aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND");
  5396. if (aff_str != NULL) {
  5397. __kmp_affinity_type = affinity_default;
  5398. __kmp_affinity_gran = KMP_HW_UNKNOWN;
  5399. __kmp_affinity_top_method = affinity_top_method_default;
  5400. __kmp_affinity_respect_mask = affinity_respect_mask_default;
  5401. }
  5402. }
  5403. #endif /* KMP_AFFINITY_SUPPORTED */
  5404. // Set up the nested proc bind type vector.
  5405. if (__kmp_nested_proc_bind.bind_types == NULL) {
  5406. __kmp_nested_proc_bind.bind_types =
  5407. (kmp_proc_bind_t *)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t));
  5408. if (__kmp_nested_proc_bind.bind_types == NULL) {
  5409. KMP_FATAL(MemoryAllocFailed);
  5410. }
  5411. __kmp_nested_proc_bind.size = 1;
  5412. __kmp_nested_proc_bind.used = 1;
  5413. #if KMP_AFFINITY_SUPPORTED
  5414. __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
  5415. #else
  5416. // default proc bind is false if affinity not supported
  5417. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  5418. #endif
  5419. }
  5420. // Set up the affinity format ICV
  5421. // Grab the default affinity format string from the message catalog
  5422. kmp_msg_t m =
  5423. __kmp_msg_format(kmp_i18n_msg_AffFormatDefault, "%P", "%i", "%n", "%A");
  5424. KMP_DEBUG_ASSERT(KMP_STRLEN(m.str) < KMP_AFFINITY_FORMAT_SIZE);
  5425. if (__kmp_affinity_format == NULL) {
  5426. __kmp_affinity_format =
  5427. (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE);
  5428. }
  5429. KMP_STRCPY_S(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, m.str);
  5430. __kmp_str_free(&m.str);
  5431. // Now process all of the settings.
  5432. for (i = 0; i < block.count; ++i) {
  5433. __kmp_stg_parse(block.vars[i].name, block.vars[i].value);
  5434. }
  5435. // If user locks have been allocated yet, don't reset the lock vptr table.
  5436. if (!__kmp_init_user_locks) {
  5437. if (__kmp_user_lock_kind == lk_default) {
  5438. __kmp_user_lock_kind = lk_queuing;
  5439. }
  5440. #if KMP_USE_DYNAMIC_LOCK
  5441. __kmp_init_dynamic_user_locks();
  5442. #else
  5443. __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
  5444. #endif
  5445. } else {
  5446. KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called
  5447. KMP_DEBUG_ASSERT(__kmp_user_lock_kind != lk_default);
  5448. // Binds lock functions again to follow the transition between different
  5449. // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
  5450. // as we do not allow lock kind changes after making a call to any
  5451. // user lock functions (true).
  5452. #if KMP_USE_DYNAMIC_LOCK
  5453. __kmp_init_dynamic_user_locks();
  5454. #else
  5455. __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
  5456. #endif
  5457. }
  5458. #if KMP_AFFINITY_SUPPORTED
  5459. if (!TCR_4(__kmp_init_middle)) {
  5460. #if KMP_USE_HWLOC
  5461. // Force using hwloc when either tiles or numa nodes requested within
  5462. // KMP_HW_SUBSET or granularity setting and no other topology method
  5463. // is requested
  5464. if (__kmp_hw_subset &&
  5465. __kmp_affinity_top_method == affinity_top_method_default)
  5466. if (__kmp_hw_subset->specified(KMP_HW_NUMA) ||
  5467. __kmp_hw_subset->specified(KMP_HW_TILE) ||
  5468. __kmp_affinity_gran == KMP_HW_TILE ||
  5469. __kmp_affinity_gran == KMP_HW_NUMA)
  5470. __kmp_affinity_top_method = affinity_top_method_hwloc;
  5471. // Force using hwloc when tiles or numa nodes requested for OMP_PLACES
  5472. if (__kmp_affinity_gran == KMP_HW_NUMA ||
  5473. __kmp_affinity_gran == KMP_HW_TILE)
  5474. __kmp_affinity_top_method = affinity_top_method_hwloc;
  5475. #endif
  5476. // Determine if the machine/OS is actually capable of supporting
  5477. // affinity.
  5478. const char *var = "KMP_AFFINITY";
  5479. KMPAffinity::pick_api();
  5480. #if KMP_USE_HWLOC
  5481. // If Hwloc topology discovery was requested but affinity was also disabled,
  5482. // then tell user that Hwloc request is being ignored and use default
  5483. // topology discovery method.
  5484. if (__kmp_affinity_top_method == affinity_top_method_hwloc &&
  5485. __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) {
  5486. KMP_WARNING(AffIgnoringHwloc, var);
  5487. __kmp_affinity_top_method = affinity_top_method_all;
  5488. }
  5489. #endif
  5490. if (__kmp_affinity_type == affinity_disabled) {
  5491. KMP_AFFINITY_DISABLE();
  5492. } else if (!KMP_AFFINITY_CAPABLE()) {
  5493. __kmp_affinity_dispatch->determine_capable(var);
  5494. if (!KMP_AFFINITY_CAPABLE()) {
  5495. if (__kmp_affinity_verbose ||
  5496. (__kmp_affinity_warnings &&
  5497. (__kmp_affinity_type != affinity_default) &&
  5498. (__kmp_affinity_type != affinity_none) &&
  5499. (__kmp_affinity_type != affinity_disabled))) {
  5500. KMP_WARNING(AffNotSupported, var);
  5501. }
  5502. __kmp_affinity_type = affinity_disabled;
  5503. __kmp_affinity_respect_mask = 0;
  5504. __kmp_affinity_gran = KMP_HW_THREAD;
  5505. }
  5506. }
  5507. if (__kmp_affinity_type == affinity_disabled) {
  5508. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  5509. } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) {
  5510. // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
  5511. __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
  5512. }
  5513. if (KMP_AFFINITY_CAPABLE()) {
  5514. #if KMP_GROUP_AFFINITY
  5515. // This checks to see if the initial affinity mask is equal
  5516. // to a single windows processor group. If it is, then we do
  5517. // not respect the initial affinity mask and instead, use the
  5518. // entire machine.
  5519. bool exactly_one_group = false;
  5520. if (__kmp_num_proc_groups > 1) {
  5521. int group;
  5522. bool within_one_group;
  5523. // Get the initial affinity mask and determine if it is
  5524. // contained within a single group.
  5525. kmp_affin_mask_t *init_mask;
  5526. KMP_CPU_ALLOC(init_mask);
  5527. __kmp_get_system_affinity(init_mask, TRUE);
  5528. group = __kmp_get_proc_group(init_mask);
  5529. within_one_group = (group >= 0);
  5530. // If the initial affinity is within a single group,
  5531. // then determine if it is equal to that single group.
  5532. if (within_one_group) {
  5533. DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group);
  5534. DWORD num_bits_in_mask = 0;
  5535. for (int bit = init_mask->begin(); bit != init_mask->end();
  5536. bit = init_mask->next(bit))
  5537. num_bits_in_mask++;
  5538. exactly_one_group = (num_bits_in_group == num_bits_in_mask);
  5539. }
  5540. KMP_CPU_FREE(init_mask);
  5541. }
  5542. // Handle the Win 64 group affinity stuff if there are multiple
  5543. // processor groups, or if the user requested it, and OMP 4.0
  5544. // affinity is not in effect.
  5545. if (__kmp_num_proc_groups > 1 &&
  5546. __kmp_affinity_type == affinity_default &&
  5547. __kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
  5548. // Do not respect the initial processor affinity mask if it is assigned
  5549. // exactly one Windows Processor Group since this is interpreted as the
  5550. // default OS assignment. Not respecting the mask allows the runtime to
  5551. // use all the logical processors in all groups.
  5552. if (__kmp_affinity_respect_mask == affinity_respect_mask_default &&
  5553. exactly_one_group) {
  5554. __kmp_affinity_respect_mask = FALSE;
  5555. }
  5556. // Use compact affinity with anticipation of pinning to at least the
  5557. // group granularity since threads can only be bound to one group.
  5558. if (__kmp_affinity_type == affinity_default) {
  5559. __kmp_affinity_type = affinity_compact;
  5560. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  5561. }
  5562. if (__kmp_affinity_top_method == affinity_top_method_default)
  5563. __kmp_affinity_top_method = affinity_top_method_all;
  5564. if (__kmp_affinity_gran == KMP_HW_UNKNOWN)
  5565. __kmp_affinity_gran = KMP_HW_PROC_GROUP;
  5566. } else
  5567. #endif /* KMP_GROUP_AFFINITY */
  5568. {
  5569. if (__kmp_affinity_respect_mask == affinity_respect_mask_default) {
  5570. #if KMP_GROUP_AFFINITY
  5571. if (__kmp_num_proc_groups > 1 && exactly_one_group) {
  5572. __kmp_affinity_respect_mask = FALSE;
  5573. } else
  5574. #endif /* KMP_GROUP_AFFINITY */
  5575. {
  5576. __kmp_affinity_respect_mask = TRUE;
  5577. }
  5578. }
  5579. if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&
  5580. (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {
  5581. if (__kmp_affinity_type == affinity_default) {
  5582. __kmp_affinity_type = affinity_compact;
  5583. __kmp_affinity_dups = FALSE;
  5584. }
  5585. } else if (__kmp_affinity_type == affinity_default) {
  5586. #if KMP_MIC_SUPPORTED
  5587. if (__kmp_mic_type != non_mic) {
  5588. __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
  5589. } else
  5590. #endif
  5591. {
  5592. __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
  5593. }
  5594. #if KMP_MIC_SUPPORTED
  5595. if (__kmp_mic_type != non_mic) {
  5596. __kmp_affinity_type = affinity_scatter;
  5597. } else
  5598. #endif
  5599. {
  5600. __kmp_affinity_type = affinity_none;
  5601. }
  5602. }
  5603. if ((__kmp_affinity_gran == KMP_HW_UNKNOWN) &&
  5604. (__kmp_affinity_gran_levels < 0)) {
  5605. #if KMP_MIC_SUPPORTED
  5606. if (__kmp_mic_type != non_mic) {
  5607. __kmp_affinity_gran = KMP_HW_THREAD;
  5608. } else
  5609. #endif
  5610. {
  5611. __kmp_affinity_gran = KMP_HW_CORE;
  5612. }
  5613. }
  5614. if (__kmp_affinity_top_method == affinity_top_method_default) {
  5615. __kmp_affinity_top_method = affinity_top_method_all;
  5616. }
  5617. }
  5618. }
  5619. K_DIAG(1, ("__kmp_affinity_type == %d\n", __kmp_affinity_type));
  5620. K_DIAG(1, ("__kmp_affinity_compact == %d\n", __kmp_affinity_compact));
  5621. K_DIAG(1, ("__kmp_affinity_offset == %d\n", __kmp_affinity_offset));
  5622. K_DIAG(1, ("__kmp_affinity_verbose == %d\n", __kmp_affinity_verbose));
  5623. K_DIAG(1, ("__kmp_affinity_warnings == %d\n", __kmp_affinity_warnings));
  5624. K_DIAG(1, ("__kmp_affinity_respect_mask == %d\n",
  5625. __kmp_affinity_respect_mask));
  5626. K_DIAG(1, ("__kmp_affinity_gran == %d\n", __kmp_affinity_gran));
  5627. KMP_DEBUG_ASSERT(__kmp_affinity_type != affinity_default);
  5628. KMP_DEBUG_ASSERT(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default);
  5629. K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
  5630. __kmp_nested_proc_bind.bind_types[0]));
  5631. }
  5632. #endif /* KMP_AFFINITY_SUPPORTED */
  5633. if (__kmp_version) {
  5634. __kmp_print_version_1();
  5635. }
  5636. // Post-initialization step: some env. vars need their value's further
  5637. // processing
  5638. if (string != NULL) { // kmp_set_defaults() was called
  5639. __kmp_aux_env_initialize(&block);
  5640. }
  5641. __kmp_env_blk_free(&block);
  5642. KMP_MB();
  5643. } // __kmp_env_initialize
  5644. void __kmp_env_print() {
  5645. kmp_env_blk_t block;
  5646. int i;
  5647. kmp_str_buf_t buffer;
  5648. __kmp_stg_init();
  5649. __kmp_str_buf_init(&buffer);
  5650. __kmp_env_blk_init(&block, NULL);
  5651. __kmp_env_blk_sort(&block);
  5652. // Print real environment values.
  5653. __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings));
  5654. for (i = 0; i < block.count; ++i) {
  5655. char const *name = block.vars[i].name;
  5656. char const *value = block.vars[i].value;
  5657. if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) ||
  5658. strncmp(name, "OMP_", 4) == 0
  5659. #ifdef KMP_GOMP_COMPAT
  5660. || strncmp(name, "GOMP_", 5) == 0
  5661. #endif // KMP_GOMP_COMPAT
  5662. ) {
  5663. __kmp_str_buf_print(&buffer, " %s=%s\n", name, value);
  5664. }
  5665. }
  5666. __kmp_str_buf_print(&buffer, "\n");
  5667. // Print internal (effective) settings.
  5668. __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings));
  5669. for (int i = 0; i < __kmp_stg_count; ++i) {
  5670. if (__kmp_stg_table[i].print != NULL) {
  5671. __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
  5672. __kmp_stg_table[i].data);
  5673. }
  5674. }
  5675. __kmp_printf("%s", buffer.str);
  5676. __kmp_env_blk_free(&block);
  5677. __kmp_str_buf_free(&buffer);
  5678. __kmp_printf("\n");
  5679. } // __kmp_env_print
  5680. void __kmp_env_print_2() {
  5681. __kmp_display_env_impl(__kmp_display_env, __kmp_display_env_verbose);
  5682. } // __kmp_env_print_2
  5683. void __kmp_display_env_impl(int display_env, int display_env_verbose) {
  5684. kmp_env_blk_t block;
  5685. kmp_str_buf_t buffer;
  5686. __kmp_env_format = 1;
  5687. __kmp_stg_init();
  5688. __kmp_str_buf_init(&buffer);
  5689. __kmp_env_blk_init(&block, NULL);
  5690. __kmp_env_blk_sort(&block);
  5691. __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin));
  5692. __kmp_str_buf_print(&buffer, " _OPENMP='%d'\n", __kmp_openmp_version);
  5693. for (int i = 0; i < __kmp_stg_count; ++i) {
  5694. if (__kmp_stg_table[i].print != NULL &&
  5695. ((display_env && strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) ||
  5696. display_env_verbose)) {
  5697. __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
  5698. __kmp_stg_table[i].data);
  5699. }
  5700. }
  5701. __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd));
  5702. __kmp_str_buf_print(&buffer, "\n");
  5703. __kmp_printf("%s", buffer.str);
  5704. __kmp_env_blk_free(&block);
  5705. __kmp_str_buf_free(&buffer);
  5706. __kmp_printf("\n");
  5707. }
  5708. #if OMPD_SUPPORT
  5709. // Dump environment variables for OMPD
  5710. void __kmp_env_dump() {
  5711. kmp_env_blk_t block;
  5712. kmp_str_buf_t buffer, env, notdefined;
  5713. __kmp_stg_init();
  5714. __kmp_str_buf_init(&buffer);
  5715. __kmp_str_buf_init(&env);
  5716. __kmp_str_buf_init(&notdefined);
  5717. __kmp_env_blk_init(&block, NULL);
  5718. __kmp_env_blk_sort(&block);
  5719. __kmp_str_buf_print(&notdefined, ": %s", KMP_I18N_STR(NotDefined));
  5720. for (int i = 0; i < __kmp_stg_count; ++i) {
  5721. if (__kmp_stg_table[i].print == NULL)
  5722. continue;
  5723. __kmp_str_buf_clear(&env);
  5724. __kmp_stg_table[i].print(&env, __kmp_stg_table[i].name,
  5725. __kmp_stg_table[i].data);
  5726. if (env.used < 4) // valid definition must have indents (3) and a new line
  5727. continue;
  5728. if (strstr(env.str, notdefined.str))
  5729. // normalize the string
  5730. __kmp_str_buf_print(&buffer, "%s=undefined\n", __kmp_stg_table[i].name);
  5731. else
  5732. __kmp_str_buf_cat(&buffer, env.str + 3, env.used - 3);
  5733. }
  5734. ompd_env_block = (char *)__kmp_allocate(buffer.used + 1);
  5735. KMP_MEMCPY(ompd_env_block, buffer.str, buffer.used + 1);
  5736. ompd_env_block_size = (ompd_size_t)KMP_STRLEN(ompd_env_block);
  5737. __kmp_env_blk_free(&block);
  5738. __kmp_str_buf_free(&buffer);
  5739. __kmp_str_buf_free(&env);
  5740. __kmp_str_buf_free(&notdefined);
  5741. }
  5742. #endif // OMPD_SUPPORT
  5743. // end of file