1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
- <library id="context" name="Context" dirname="context" last-revision="$Date: 2019/10/02 06:15:27 $"
- xmlns:xi="http://www.w3.org/2001/XInclude">
- <libraryinfo>
- <authorgroup>
- <author>
- <firstname>Oliver</firstname> <surname>Kowalke</surname>
- </author>
- </authorgroup>
- <copyright>
- <year>2014</year> <holder>Oliver Kowalke</holder>
- </copyright>
- <legalnotice id="context.legal">
- <para>
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at <ulink url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
- </para>
- </legalnotice>
- <librarypurpose>
- C++ Library for swiching different user ctx
- </librarypurpose>
- <librarycategory name="category:text"></librarycategory>
- </libraryinfo>
- <title>Context</title>
- <section id="context.overview">
- <title><link linkend="context.overview">Overview</link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> is a foundational library that
- provides a sort of cooperative multitasking on a single thread. By providing
- an abstraction of the current execution state in the current thread, including
- the stack (with local variables) and stack pointer, all registers and CPU flags,
- and the instruction pointer, a execution context represents a specific point
- in the application's execution path. This is useful for building higher-level
- abstractions, like <emphasis>coroutines</emphasis>, <emphasis>cooperative threads
- (userland threads)</emphasis> or an equivalent to <ulink url="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx">C#
- keyword <emphasis>yield</emphasis></ulink> in C++.
- </para>
- <para>
- <link linkend="cc"><emphasis>callcc()</emphasis></link>/<link linkend="cc"><emphasis>continuation</emphasis></link>
- provides the means to suspend the current execution path and to transfer execution
- control, thereby permitting another context to run on the current thread. This
- state full transfer mechanism enables a context to suspend execution from within
- nested functions and, later, to resume from where it was suspended. While the
- execution path represented by a <link linkend="cc"><emphasis>continuation</emphasis></link>
- only runs on a single thread, it can be migrated to another thread at any given
- time.
- </para>
- <para>
- A <ulink url="http://en.wikipedia.org/wiki/Context_switch">context switch</ulink>
- between threads requires system calls (involving the OS kernel), which can
- cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring control
- vias <link linkend="cc"><emphasis>callcc()</emphasis></link>/<link linkend="cc"><emphasis>continuation</emphasis></link>
- requires only few CPU cycles because it does not involve system calls as it
- is done within a single thread.
- </para>
- <para>
- All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>.
- </para>
- <note>
- <para>
- This library requires C++11!
- </para>
- </note>
- <important>
- <para>
- Windows using fcontext_t: turn off global program optimization (/GL) and
- change /EHsc (compiler assumes that functions declared as extern "C"
- never throw a C++ exception) to /EHs (tells compiler assumes that functions
- declared as extern "C" may throw an exception).
- </para>
- </important>
- </section>
- <section id="context.requirements">
- <title><link linkend="context.requirements">Requirements</link></title>
- <para>
- If <emphasis role="bold">Boost.Context</emphasis> uses fcontext_t (the default)
- as its implementation, it must be built for the particular compiler(s) and
- CPU architecture(s) being targeted. Using <link linkend="implementation"><emphasis>fcontext_t</emphasis></link>,
- <emphasis role="bold">Boost.Context</emphasis> includes assembly code and,
- therefore, requires GNU as and GNU preprocessor for supported POSIX systems,
- MASM for Windows/x86 systems and ARMasm for Windows/arm systems.
- </para>
- <note>
- <para>
- MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.
- </para>
- </note>
- <important>
- <para>
- Please note that <code><phrase role="identifier">address</phrase><phrase
- role="special">-</phrase><phrase role="identifier">model</phrase><phrase
- role="special">=</phrase><phrase role="number">64</phrase></code> must be
- given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit
- code will be generated.
- </para>
- </important>
- <important>
- <para>
- For cross-compiling the lib you must specify certain additional properties
- at bjam command line: <code><phrase role="identifier">target</phrase><phrase
- role="special">-</phrase><phrase role="identifier">os</phrase></code>, <code><phrase
- role="identifier">abi</phrase></code>, <code><phrase role="identifier">binary</phrase><phrase
- role="special">-</phrase><phrase role="identifier">format</phrase></code>,
- <code><phrase role="identifier">architecture</phrase></code> and <code><phrase
- role="identifier">address</phrase><phrase role="special">-</phrase><phrase
- role="identifier">model</phrase></code>.
- </para>
- </important>
- <important>
- <para>
- Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must
- be specified at bjam command line.
- </para>
- </important>
- <important>
- <para>
- Windows using fcontext_t: turn off global program optimization (/GL) and
- change /EHsc (compiler assumes that functions declared as extern "C"
- never throw a C++ exception) to /EHs (tells compiler assumes that functions
- declared as extern "C" may throw an exception).
- </para>
- </important>
- <para>
- Because this library uses C++11 extensively, it requires a compatible compiler.
- Known minimum working versions are as follows: Microsoft Visual Studio 2015
- (msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other
- compilers may work, if they support the following language features: auto declarations,
- constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept,
- nullptr, rvalue references, template aliases. thread local, variadic templates.
- </para>
- </section>
- <section id="context.ff">
- <title><anchor id="ff"/><link linkend="context.ff">Context switching with fibers</link></title>
- <note>
- <para>
- <emphasis>fiber</emphasis> is the reference implementation of C++ proposal
- <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0876r0.pdf">P0876R0:
- fibers without scheduler</ulink>.
- </para>
- </note>
- <para>
- A <emphasis>fiber</emphasis> represents the state of the control flow of a
- program at a given point in time. Fibers can be suspended and resumed later
- in order to change the control flow of a program.
- </para>
- <para>
- Modern micro-processors are registers machines; the content of processor registers
- represent a fiber of the executed program at a given point in time. Operating
- systems simulate parallel execution of programs on a single processor by switching
- between programs (context switch) by preserving and restoring the fiber, e.g.
- the content of all registers.
- </para>
- <bridgehead renderas="sect3" id="context.ff.h0">
- <phrase id="context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"/><link
- linkend="context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"><link
- linkend="ff"><emphasis>fiber</emphasis></link></link>
- </bridgehead>
- <para>
- <link linkend="ff"><emphasis>fiber</emphasis></link> captures the current fiber
- (the rest of the computation; code after <link linkend="ff"><emphasis>fiber</emphasis></link>)
- and triggers a context switch. The context switch is achieved by preserving
- certain registers (including instruction and stack pointer), defined by the
- calling convention of the ABI, of the current fiber and restoring those registers
- of the resumed fiber. The control flow of the resumed fiber continues. The
- current fiber is suspended and passed as argument to the resumed fiber.
- </para>
- <para>
- <link linkend="ff"><emphasis>fiber</emphasis></link> expects a <emphasis>context-function</emphasis>
- with signature <code><phrase role="char">'fiber(fiber && f)'</phrase></code>.
- The parameter <code><phrase role="identifier">f</phrase></code> represents
- the current fiber from which this fiber was resumed (e.g. that has called
- <link linkend="ff"><emphasis>fiber</emphasis></link>).
- </para>
- <para>
- On return the <emphasis>context-function</emphasis> of the current fiber has
- to specify an <link linkend="ff"><emphasis>fiber</emphasis></link> to which
- the execution control is transferred after termination of the current fiber.
- </para>
- <para>
- If an instance with valid state goes out of scope and the <emphasis>context-function</emphasis>
- has not yet returned, the stack is traversed in order to access the control
- structure (address stored at the first stack frame) and fiber's stack is deallocated
- via the <emphasis>StackAllocator</emphasis>.
- </para>
- <note>
- <para>
- <link linkend="segmented"><emphasis>Segmented stacks</emphasis></link> are
- supported by <link linkend="ff"><emphasis>fiber</emphasis></link> using
- <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>.
- </para>
- </note>
- <para>
- <link linkend="ff"><emphasis>fiber</emphasis></link> represents a <emphasis>fiber</emphasis>;
- it contains the content of preserved registers and manages the associated stack
- (allocation/deallocation). <link linkend="ff"><emphasis>fiber</emphasis></link>
- is a one-shot fiber - it can be used only once, after calling <emphasis>continuation::resume()</emphasis>
- or <emphasis>continuation::resume_with()</emphasis> it is invalidated.
- </para>
- <para>
- <link linkend="ff"><emphasis>fiber</emphasis></link> is only move-constructible
- and move-assignable.
- </para>
- <para>
- As a first-class object <link linkend="ff"><emphasis>fiber</emphasis></link>
- can be applied to and returned from a function, assigned to a variable or stored
- in a container.
- </para>
- <para>
- A fiber is continued by calling <code><phrase role="identifier">resume</phrase><phrase
- role="special">()</phrase></code>/<code><phrase role="identifier">resume_with</phrase><phrase
- role="special">()</phrase></code>.
- </para>
- <bridgehead renderas="sect3" id="context.ff.h1">
- <phrase id="context.ff.usage"/><link linkend="context.ff.usage">Usage</link>
- </bridgehead>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">source</phrase><phrase role="special">{[&</phrase><phrase role="identifier">a</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">for</phrase><phrase role="special">(;;){</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
- <phrase role="special">}};</phrase>
- <phrase role="keyword">for</phrase> <phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">j</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">a</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
- </programlisting>
- <para>
- This simple example demonstrates the basic usage of <link linkend="ff"><emphasis>fiber</emphasis></link>
- as a <emphasis>generator</emphasis>. The fiber <code><phrase role="identifier">sink</phrase></code>
- represents the <emphasis>main</emphasis>-fiber (function <code><phrase role="identifier">main</phrase><phrase
- role="special">()</phrase></code>). <code><phrase role="identifier">sink</phrase></code>
- is captured (current-fiber) by invoking <link linkend="ff"><emphasis>fiber</emphasis></link>
- and passed as parameter to the lambda.
- </para>
- <para>
- Because the state is invalidated (one-shot fiber) by each call of <emphasis>continuation::resume()</emphasis>,
- the new state of the <link linkend="ff"><emphasis>fiber</emphasis></link>,
- returned by <emphasis>continuation::resume()</emphasis>, needs to be assigned
- to <code><phrase role="identifier">sink</phrase></code> after each call. In
- order to express the invalidation of the resumed fiber, the member functions
- <code><phrase role="identifier">resume</phrase><phrase role="special">()</phrase></code>
- and <code><phrase role="identifier">resume_with</phrase><phrase role="special">()</phrase></code>
- are rvalue-ref qualified. Both functions bind only to rvalues. Thus an lvalue
- fiber must be casted to an rvalue via <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">()</phrase></code>.
- </para>
- <para>
- The lambda that calculates the Fibonacci numbers is executed inside the fiber
- represented by <code><phrase role="identifier">source</phrase></code>. Calculated
- Fibonacci numbers are transferred between the two fibers via variable <code><phrase
- role="identifier">a</phrase></code> (lambda capture reference).
- </para>
- <para>
- The locale variables <code><phrase role="identifier">b</phrase></code> and
- <code> <phrase role="identifier">next</phrase></code> remain their values during
- each context switch. This is possible due <code><phrase role="identifier">source</phrase></code>
- has its own stack and the stack is exchanged by each context switch.
- </para>
- <bridgehead renderas="sect3" id="context.ff.h2">
- <phrase id="context.ff.parameter_passing"/><link linkend="context.ff.parameter_passing">Parameter
- passing</link>
- </bridgehead>
- <para>
- Data can be transferred between two fibers via global pointers, calling wrappers
- (like <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">bind</phrase></code>) or lambda captures.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">{[&</phrase><phrase role="identifier">i</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside f1,i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">i</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}};</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">inside</phrase> <phrase role="identifier">c1</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
- <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">2</phrase>
- </programlisting>
- <para>
- <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>
- enters the lambda in fiber represented by <code><phrase role="identifier">f1</phrase></code>
- with lambda capture reference <code><phrase role="identifier">i</phrase><phrase
- role="special">=</phrase><phrase role="number">1</phrase></code>. The expression
- <code><phrase role="identifier">f2</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>
- resumes the fiber <code><phrase role="identifier">f2</phrase></code>. On return
- of <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>,
- the variable <code><phrase role="identifier">i</phrase></code> has the value
- of <code><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase
- role="number">1</phrase></code>.
- </para>
- <bridgehead renderas="sect3" id="context.ff.h3">
- <phrase id="context.ff.exception_handling"/><link linkend="context.ff.exception_handling">Exception
- handling</link>
- </bridgehead>
- <para>
- If the function executed inside a <emphasis>context-function</emphasis> emits
- ans exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">terminate</phrase><phrase
- role="special">()</phrase></code>. <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">exception_ptr</phrase></code>
- can be used to transfer exceptions between different fibers.
- </para>
- <important>
- <para>
- Do not jump from inside a catch block and then re-throw the exception in
- another fiber.
- </para>
- </important>
- <anchor id="ff_ontop"/>
- <bridgehead renderas="sect3" id="context.ff.h4">
- <phrase id="context.ff.executing_function_on_top_of_a_fiber"/><link linkend="context.ff.executing_function_on_top_of_a_fiber">Executing
- function on top of a fiber</link>
- </bridgehead>
- <para>
- Sometimes it is useful to execute a new function on top of a resumed fiber.
- For this purpose <emphasis>continuation::resume_with()</emphasis> has to be
- used. The function passed as argument must accept a rvalue reference to <link
- linkend="ff"><emphasis>fiber</emphasis></link> and return <code><phrase role="keyword">void</phrase></code>.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">{[&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">f2</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">f2</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase>
- <phrase role="special">}};</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">=-</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned third time"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">0</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
- <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase>
- </programlisting>
- <para>
- The expression <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume_with</phrase><phrase role="special">(...)</phrase></code>
- executes a lambda on top of fiber <code><phrase role="identifier">f1</phrase></code>,
- e.g. an additional stack frame is allocated on top of the stack. This lambda
- assigns <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
- to <code><phrase role="identifier">data</phrase></code> and returns to the
- second invocation of <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>.
- </para>
- <para>
- Another option is to execute a function on top of the fiber that throws an
- exception.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="special">:</phrase> <phrase role="keyword">public</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">what</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">{</phrase> <phrase role="identifier">what</phrase> <phrase role="special">},</phrase>
- <phrase role="identifier">f</phrase><phrase role="special">{</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f_</phrase><phrase role="special">)</phrase> <phrase role="special">}</phrase> <phrase role="special">{</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">};</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">{[](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">-></phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"entered"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">my_exception</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ex</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cerr</phrase> <phrase role="special"><<</phrase> <phrase role="string">"my_exception: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">what</phrase><phrase role="special">()</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="special">{};</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">-></phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">),</phrase><phrase role="string">"abc"</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">return</phrase> <phrase role="special">{};</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">entered</phrase>
- <phrase role="identifier">my_exception</phrase><phrase role="special">:</phrase> <phrase role="identifier">abc</phrase>
- </programlisting>
- <para>
- In this exception <code><phrase role="identifier">my_exception</phrase></code>
- is throw from a function invoked on-top of fiber <code><phrase role="identifier">f</phrase></code>
- and catched inside the <code><phrase role="keyword">for</phrase></code>-loop.
- </para>
- <bridgehead renderas="sect3" id="context.ff.h5">
- <phrase id="context.ff.stack_unwinding"/><link linkend="context.ff.stack_unwinding">Stack
- unwinding</link>
- </bridgehead>
- <para>
- On construction of <link linkend="ff"><emphasis>fiber</emphasis></link> a stack
- is allocated. If the <emphasis>context-function</emphasis> returns the stack
- will be destructed. If the <emphasis>context-function</emphasis> has not yet
- returned and the destructor of an valid <link linkend="ff"><emphasis>fiber</emphasis></link>
- instance (e.g. <emphasis>fiber::operator bool()</emphasis> returns <code><phrase
- role="keyword">true</phrase></code>) is called, the stack will be destructed
- too.
- </para>
- <important>
- <para>
- Code executed by <emphasis>context-function</emphasis> must not prevent the
- propagation ofs the <emphasis>detail::forced_unwind</emphasis> exception.
- Absorbing that exception will cause stack unwinding to fail. Thus, any code
- that catches all exceptions must re-throw any pending <emphasis>detail::forced_unwind</emphasis>
- exception.
- </para>
- </important>
- <anchor id="ff_prealloc"/>
- <bridgehead renderas="sect3" id="context.ff.h6">
- <phrase id="context.ff.allocating_control_structures_on_top_of_stack"/><link
- linkend="context.ff.allocating_control_structures_on_top_of_stack">Allocating
- control structures on top of stack</link>
- </bridgehead>
- <para>
- Allocating control structures on top of the stack requires to allocated the
- <emphasis>stack_context</emphasis> and create the control structure with placement
- new before <link linkend="ff"><emphasis>fiber</emphasis></link> is created.
- </para>
- <note>
- <para>
- The user is responsible for destructing the control structure at the top
- of the stack.
- </para>
- </note>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
- <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase><phrase role="number">4048</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// allocate stack space</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase><phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">());</phrase>
- <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">=</phrase><phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">=</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase><phrase role="special">-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// placement new creates control structure on reserved space</phrase>
- <phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase><phrase role="special">=</phrase><phrase role="keyword">new</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
- <phrase role="special">...</phrase>
- <phrase role="comment">// destructing the control structure</phrase>
- <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
- <phrase role="special">...</phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
- <phrase role="comment">// captured fiber</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
- <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="comment">// create captured fiber</phrase>
- <phrase role="identifier">f</phrase><phrase role="special">{</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">),</phrase><phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">entry_func</phrase><phrase role="special">}</phrase> <phrase role="special">{</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">...</phrase>
- <phrase role="special">};</phrase>
- </programlisting>
- <bridgehead renderas="sect3" id="context.ff.h7">
- <phrase id="context.ff.inverting_the_control_flow"/><link linkend="context.ff.inverting_the_control_flow">Inverting
- the control flow</link>
- </bridgehead>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="comment">/*
- * grammar:
- * P ---> E '\0'
- * E ---> T {('+'|'-') T}
- * T ---> S {('*'|'/') S}
- * S ---> digit | '(' E ')'
- */</phrase>
- <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">pull</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">char_traits</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">>::</phrase><phrase role="identifier">to_char_type</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">());</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">scan</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">do</phrase><phrase role="special">{</phrase>
- <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">pull</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">isspace</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">));</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">Parser</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb_</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="identifier">next</phrase><phrase role="special">(),</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="identifier">is_</phrase><phrase role="special">),</phrase> <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">cb_</phrase><phrase role="special">)</phrase>
- <phrase role="special">{}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">E</phrase><phrase role="special">(){</phrase>
- <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'+'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'-'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">T</phrase><phrase role="special">(){</phrase>
- <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'*'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'/'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">S</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">isdigit</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">)){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'('</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">')'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase><phrase role="keyword">else</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">else</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">};</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// user-code pulls parsed data from parser</phrase>
- <phrase role="comment">// invert control flow</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// execute parser in new fiber</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">source</phrase><phrase role="special">{[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
- <phrase role="comment">// create parser with callback function</phrase>
- <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">c_</phrase><phrase role="special">){</phrase>
- <phrase role="comment">// resume main fiber</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c_</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">});</phrase>
- <phrase role="comment">// start recursive parsing</phrase>
- <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
- <phrase role="comment">// signal termination</phrase>
- <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// resume main fiber</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
- <phrase role="special">}};</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(!</phrase><phrase role="identifier">done</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">Move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- </programlisting>
- <para>
- In this example a recursive descent parser uses a callback to emit a newly
- passed symbol. Using <link linkend="ff"><emphasis>fiber</emphasis></link> the
- control flow can be inverted, e.g. the user-code pulls parsed symbols from
- the parser - instead to get pushed from the parser (via callback).
- </para>
- <para>
- The data (character) is transferred between the two fibers.
- </para>
- <section id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber">
- <title><anchor id="implementation"/><link linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations:
- fcontext_t, ucontext_t and WinFiber</link></title>
- <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h0">
- <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"/><link
- linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</link>
- </bridgehead>
- <para>
- The implementation uses <emphasis>fcontext_t</emphasis> per default. fcontext_t
- is based on assembler and not available for all platforms. It provides a
- much better performance than <emphasis>ucontext_t</emphasis> (the context
- switch takes two magnitudes of order less CPU cycles; see section <link linkend="performance"><emphasis>performance</emphasis></link>)
- and <emphasis>WinFiber</emphasis>.
- </para>
- <note>
- <para>
- Because the TIB (thread information block on Windows) is not fully described
- in the MSDN, it might be possible that not all required TIB-parts are swapped.
- Using WinFiber implementation migh be an alternative.
- </para>
- </note>
- <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h1">
- <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"/><link
- linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</link>
- </bridgehead>
- <para>
- As an alternative, <ulink url="https://en.wikipedia.org/wiki/Setcontext"><emphasis>ucontext_t</emphasis></ulink>
- can be used by compiling with <code><phrase role="identifier">BOOST_USE_UCONTEXT</phrase></code>
- and b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
- role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
- <emphasis>ucontext_t</emphasis> might be available on a broader range of
- POSIX-platforms but has some <link linkend="ucontext"><emphasis>disadvantages</emphasis></link>
- (for instance deprecated since POSIX.1-2003, not C99 conform).
- </para>
- <note>
- <para>
- <link linkend="ff"><emphasis>fiber</emphasis></link> supports <link linkend="segmented"><emphasis>Segmented
- stacks</emphasis></link> only with <emphasis>ucontext_t</emphasis> as its
- implementation.
- </para>
- </note>
- <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h2">
- <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"/><link
- linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</link>
- </bridgehead>
- <para>
- With <code><phrase role="identifier">BOOST_USE_WINFIB</phrase></code> and
- b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
- role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">winfib</phrase></code>
- Win32-Fibers are used as implementation for <link linkend="ff"><emphasis>fiber</emphasis></link>.
- </para>
- <note>
- <para>
- The first call of <link linkend="ff"><emphasis>fiber</emphasis></link>
- converts the thread into a Windows fiber by invoking <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
- role="special">()</phrase></code>. If desired, <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
- role="special">()</phrase></code> has to be called by the user explicitly
- in order to release resources allocated by <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
- role="special">()</phrase></code> (e.g. after using boost.context).
- </para>
- </note>
- </section>
- <section id="context.ff.class__fiber_">
- <title><link linkend="context.ff.class__fiber_">Class <code><phrase role="identifier">fiber</phrase></code></link></title>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">class</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">)</phrase> <phrase role="special">&&;</phrase>
- <phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
- <phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="special">};</phrase>
- </programlisting>
- <para>
- <bridgehead renderas="sect4" id="ff_constructor1_bridgehead">
- <phrase id="ff_constructor1"/>
- <link linkend="ff_constructor1">Constructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Creates a invalid fiber.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_constructor2_bridgehead">
- <phrase id="ff_constructor2"/>
- <link linkend="ff_constructor2">Constructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Creates a new fiber and prepares the context to execute <code><phrase
- role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
- is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
- The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
- is used to create a user defined data <link linkend="ff_prealloc">(for
- instance additional control structures)</link> on top of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_destructor destructor_bridgehead">
- <phrase id="ff_destructor destructor"/>
- <link linkend="ff_destructor
- destructor">Destructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> is a valid fiber, e.g. <emphasis>fiber::operator
- bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_move constructor_bridgehead">
- <phrase id="ff_move constructor"/>
- <link linkend="ff_move constructor">Move
- constructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves underlying capture fiber to <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_move assignment_bridgehead">
- <phrase id="ff_move assignment"/>
- <link linkend="ff_move assignment">Move assignment
- operator</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves the state of <code><phrase role="identifier">other</phrase></code>
- to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- using move semantics.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_call_bridgehead">
- <phrase id="ff_operator_call"/>
- <link linkend="ff_operator_call">Member function
- <code>operator()</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">)</phrase> <phrase role="special">&&;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Captures current fiber and resumes <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>. The function <code><phrase role="identifier">resume_with</phrase></code>,
- is used to execute function <code><phrase role="identifier">fn</phrase></code>
- in the execution context of <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> (e.g. the stack frame of <code><phrase
- role="identifier">fn</phrase></code> is allocated on stack of <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The fiber representing the fiber that has been suspended.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- Because <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- gets invalidated, <code><phrase role="identifier">resume</phrase><phrase
- role="special">()</phrase></code> and <code><phrase role="identifier">resume_with</phrase><phrase
- role="special">()</phrase></code> are rvalue-ref qualified and bind
- only to rvalues.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- Function <code><phrase role="identifier">fn</phrase></code> needs to
- return <code><phrase role="identifier">fiber</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- The returned fiber indicates if the suspended fiber has terminated
- (return from context-function) via <code><phrase role="keyword">bool</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_bool_bridgehead">
- <phrase id="ff_operator_bool"/>
- <link linkend="ff_operator_bool">Member function
- <code>operator bool</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- points to a captured fiber.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_not_bridgehead">
- <phrase id="ff_operator_not"/>
- <link linkend="ff_operator_not">Member function <code>operator!</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- does not point to a captured fiber.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_equal_bridgehead">
- <phrase id="ff_operator_equal"/>
- <link linkend="ff_operator_equal">Member function
- <code>operator==</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- and <code><phrase role="identifier">other</phrase></code> represent
- the same fiber, <code><phrase role="keyword">false</phrase></code>
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_notequal_bridgehead">
- <phrase id="ff_operator_notequal"/>
- <link linkend="ff_operator_notequal">Member
- function <code>operator!=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code>! (other == * this)</code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_less_bridgehead">
- <phrase id="ff_operator_less"/>
- <link linkend="ff_operator_less">Member function
- <code>operator<</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase> <phrase
- role="special">!=</phrase> <phrase role="identifier">other</phrase></code>
- is true and the implementation-defined total order of <code><phrase
- role="identifier">fiber</phrase></code> values places <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- before <code><phrase role="identifier">other</phrase></code>, false
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_greater_bridgehead">
- <phrase id="ff_operator_greater"/>
- <link linkend="ff_operator_greater">Member
- function <code>operator></code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_lesseq_bridgehead">
- <phrase id="ff_operator_lesseq"/>
- <link linkend="ff_operator_lesseq">Member function
- <code>operator<=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
- role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
- role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff_operator_greatereq_bridgehead">
- <phrase id="ff_operator_greatereq"/>
- <link linkend="ff_operator_greatereq">Member
- function <code>operator>=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
- <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
- <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ff__bridgehead">
- <phrase id="ff_"/>
- <link linkend="ff_">Non-member function <code>operator<<()</code></link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Writes the representation of <code><phrase role="identifier">other</phrase></code>
- to stream <code><phrase role="identifier">os</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">os</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- </section>
- <section id="context.cc">
- <title><anchor id="cc"/><link linkend="context.cc">Context switching with call/cc</link></title>
- <note>
- <para>
- <emphasis>call/cc</emphasis> is the reference implementation of C++ proposal
- <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0534r3.pdf">P0534R3:
- call/cc (call-with-current-continuation): A low-level API for stackful context
- switching</ulink>.
- </para>
- </note>
- <para>
- <emphasis>call/cc</emphasis> (call with current continuation) is a universal
- control operator (well-known from the programming language Scheme) that captures
- the current continuation as a first-class object and pass it as an argument
- to another continuation.
- </para>
- <para>
- A continuation (abstract concept of functional programming languages) represents
- the state of the control flow of a program at a given point in time. Continuations
- can be suspended and resumed later in order to change the control flow of a
- program.
- </para>
- <para>
- Modern micro-processors are registers machines; the content of processor registers
- represent a continuation of the executed program at a given point in time.
- Operating systems simulate parallel execution of programs on a single processor
- by switching between programs (context switch) by preserving and restoring
- the continuation, e.g. the content of all registers.
- </para>
- <bridgehead renderas="sect3" id="context.cc.h0">
- <phrase id="context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"/><link
- linkend="context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"><link
- linkend="cc"><emphasis>callcc()</emphasis></link></link>
- </bridgehead>
- <para>
- <link linkend="cc"><emphasis>callcc()</emphasis></link> is the C++ equivalent
- to Scheme's <emphasis>call/cc</emphasis> operator. It captures the current
- continuation (the rest of the computation; code after <link linkend="cc"><emphasis>callcc()</emphasis></link>)
- and triggers a context switch. The context switch is achieved by preserving
- certain registers (including instruction and stack pointer), defined by the
- calling convention of the ABI, of the current continuation and restoring those
- registers of the resumed continuation. The control flow of the resumed continuation
- continues. The current continuation is suspended and passed as argument to
- the resumed continuation.
- </para>
- <para>
- <link linkend="cc"><emphasis>callcc()</emphasis></link> expects a <emphasis>context-function</emphasis>
- with signature <code><phrase role="char">'continuation(continuation &&
- c)'</phrase></code>. The parameter <code><phrase role="identifier">c</phrase></code>
- represents the current continuation from which this continuation was resumed
- (e.g. that has called <link linkend="cc"><emphasis>callcc()</emphasis></link>).
- </para>
- <para>
- On return the <emphasis>context-function</emphasis> of the current continuation
- has to specify an <link linkend="cc"><emphasis>continuation</emphasis></link>
- to which the execution control is transferred after termination of the current
- continuation.
- </para>
- <para>
- If an instance with valid state goes out of scope and the <emphasis>context-function</emphasis>
- has not yet returned, the stack is traversed in order to access the control
- structure (address stored at the first stack frame) and continuation's stack
- is deallocated via the <emphasis>StackAllocator</emphasis>.
- </para>
- <note>
- <para>
- <link linkend="segmented"><emphasis>Segmented stacks</emphasis></link> are
- supported by <link linkend="cc"><emphasis>callcc()</emphasis></link> using
- <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>.
- </para>
- </note>
- <bridgehead renderas="sect3" id="context.cc.h1">
- <phrase id="context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"/><link
- linkend="context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"><link
- linkend="cc"><emphasis>continuation</emphasis></link></link>
- </bridgehead>
- <para>
- <link linkend="cc"><emphasis>continuation</emphasis></link> represents a continuation;
- it contains the content of preserved registers and manages the associated stack
- (allocation/deallocation). <link linkend="cc"><emphasis>continuation</emphasis></link>
- is a one-shot continuation - it can be used only once, after calling <emphasis>continuation::resume()</emphasis>
- or <emphasis>continuation::resume_with()</emphasis> it is invalidated.
- </para>
- <para>
- <link linkend="cc"><emphasis>continuation</emphasis></link> is only move-constructible
- and move-assignable.
- </para>
- <para>
- As a first-class object <link linkend="cc"><emphasis>continuation</emphasis></link>
- can be applied to and returned from a function, assigned to a variable or stored
- in a container.
- </para>
- <para>
- A continuation is continued by calling <code><phrase role="identifier">resume</phrase><phrase
- role="special">()</phrase></code>/<code><phrase role="identifier">resume_with</phrase><phrase
- role="special">()</phrase></code>.
- </para>
- <bridgehead renderas="sect3" id="context.cc.h2">
- <phrase id="context.cc.usage"/><link linkend="context.cc.usage">Usage</link>
- </bridgehead>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">a</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">for</phrase><phrase role="special">(;;){</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="keyword">for</phrase> <phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">j</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">a</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
- </programlisting>
- <para>
- This simple example demonstrates the basic usage of <emphasis>call/cc</emphasis>
- as a <emphasis>generator</emphasis>. The continuation <code><phrase role="identifier">sink</phrase></code>
- represents the <emphasis>main</emphasis>-continuation (function <code><phrase
- role="identifier">main</phrase><phrase role="special">()</phrase></code>).
- <code><phrase role="identifier">sink</phrase></code> is captured (current-continuation)
- by invoking <link linkend="cc"><emphasis>callcc()</emphasis></link> and passed
- as parameter to the lambda.
- </para>
- <para>
- Because the state is invalidated (one-shot continuation) by each call of <emphasis>continuation::resume()</emphasis>,
- the new state of the <link linkend="cc"><emphasis>continuation</emphasis></link>,
- returned by <emphasis>continuation::resume()</emphasis>, needs to be assigned
- to <code><phrase role="identifier">sink</phrase></code> after each call.
- </para>
- <para>
- The lambda that calculates the Fibonacci numbers is executed inside the continuation
- represented by <code><phrase role="identifier">source</phrase></code>. Calculated
- Fibonacci numbers are transferred between the two continuations via variable
- <code><phrase role="identifier">a</phrase></code> (lambda capture reference).
- </para>
- <para>
- The locale variables <code><phrase role="identifier">b</phrase></code> and
- <code> <phrase role="identifier">next</phrase></code> remain their values during
- each context switch. This is possible due <code><phrase role="identifier">source</phrase></code>
- has its own stack and the stack is exchanged by each context switch.
- </para>
- <bridgehead renderas="sect3" id="context.cc.h3">
- <phrase id="context.cc.parameter_passing"/><link linkend="context.cc.parameter_passing">Parameter
- passing</link>
- </bridgehead>
- <para>
- Data can be transferred between two continuations via global pointers, calling
- wrappers (like <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">bind</phrase></code>) or lambda captures.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c1</phrase><phrase role="special">=</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([&</phrase><phrase role="identifier">i</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c2</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside c1,i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">i</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">c2</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">inside</phrase> <phrase role="identifier">c1</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
- <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">2</phrase>
- </programlisting>
- <para>
- <code><phrase role="identifier">callcc</phrase><phrase role="special">(<</phrase><phrase
- role="identifier">lambda</phrase><phrase role="special">>)</phrase></code>
- enters the lambda in continuation represented by <code><phrase role="identifier">c1</phrase></code>
- with lambda capture reference <code><phrase role="identifier">i</phrase><phrase
- role="special">=</phrase><phrase role="number">1</phrase></code>. The expression
- <code><phrase role="identifier">c2</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>
- resumes the continuation <code><phrase role="identifier">c2</phrase></code>.
- On return of <code><phrase role="identifier">callcc</phrase><phrase role="special">(<</phrase><phrase
- role="identifier">lambda</phrase><phrase role="special">>)</phrase></code>,
- the variable <code><phrase role="identifier">i</phrase></code> has the value
- of <code><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase
- role="number">1</phrase></code>.
- </para>
- <bridgehead renderas="sect3" id="context.cc.h4">
- <phrase id="context.cc.exception_handling"/><link linkend="context.cc.exception_handling">Exception
- handling</link>
- </bridgehead>
- <para>
- If the function executed inside a <emphasis>context-function</emphasis> emits
- an exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">terminate</phrase><phrase
- role="special">()</phrase></code>. <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">exception_ptr</phrase></code>
- can be used to transfer exceptions between different continuations.
- </para>
- <important>
- <para>
- Do not jump from inside a catch block and then re-throw the exception in
- another continuation.
- </para>
- </important>
- <anchor id="cc_ontop"/>
- <bridgehead renderas="sect3" id="context.cc.h5">
- <phrase id="context.cc.executing_function_on_top_of_a_continuation"/><link
- linkend="context.cc.executing_function_on_top_of_a_continuation">Executing
- function on top of a continuation</link>
- </bridgehead>
- <para>
- Sometimes it is useful to execute a new function on top of a resumed continuation.
- For this purpose <emphasis>continuation::resume_with()</emphasis> has to be
- used. The function passed as argument must accept a rvalue reference to <link
- linkend="cc"><emphasis>continuation</emphasis></link> and return <code><phrase
- role="keyword">void</phrase></code>.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">=-</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned third time"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">0</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
- <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
- <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase>
- </programlisting>
- <para>
- The expression <code><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume_with</phrase><phrase role="special">(...)</phrase></code>
- executes a lambda on top of continuation <code><phrase role="identifier">c</phrase></code>,
- e.g. an additional stack frame is allocated on top of the stack. This lambda
- assigns <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
- to <code><phrase role="identifier">data</phrase></code> and returns to the
- second invocation of <code><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase
- role="identifier">resume</phrase><phrase role="special">()</phrase></code>.
- </para>
- <para>
- Another option is to execute a function on top of the continuation that throws
- an exception.
- </para>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="special">:</phrase> <phrase role="keyword">public</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">what</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">{</phrase> <phrase role="identifier">what</phrase> <phrase role="special">},</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">{</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c_</phrase><phrase role="special">)</phrase> <phrase role="special">}</phrase> <phrase role="special">{</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">};</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"entered"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">my_exception</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ex</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cerr</phrase> <phrase role="special"><<</phrase> <phrase role="string">"my_exception: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">what</phrase><phrase role="special">()</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">c</phrase> <phrase role="special">=</phrase> <phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase>
- <phrase role="special">[](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">){</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">),</phrase><phrase role="string">"abc"</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">entered</phrase>
- <phrase role="identifier">my_exception</phrase><phrase role="special">:</phrase> <phrase role="identifier">abc</phrase>
- </programlisting>
- <para>
- In this exception <code><phrase role="identifier">my_exception</phrase></code>
- is throw from a function invoked on-top of continuation <code><phrase role="identifier">c</phrase></code>
- and catched inside the <code><phrase role="keyword">for</phrase></code>-loop.
- </para>
- <bridgehead renderas="sect3" id="context.cc.h6">
- <phrase id="context.cc.stack_unwinding"/><link linkend="context.cc.stack_unwinding">Stack
- unwinding</link>
- </bridgehead>
- <para>
- On construction of <link linkend="cc"><emphasis>continuation</emphasis></link>
- a stack is allocated. If the <emphasis>context-function</emphasis> returns
- the stack will be destructed. If the <emphasis>context-function</emphasis>
- has not yet returned and the destructor of an valid <link linkend="cc"><emphasis>continuation</emphasis></link>
- instance (e.g. <emphasis>continuation::operator bool()</emphasis> returns
- <code><phrase role="keyword">true</phrase></code>) is called, the stack will
- be destructed too.
- </para>
- <important>
- <para>
- Code executed by <emphasis>context-function</emphasis> must not prevent the
- propagation ofs the <emphasis>detail::forced_unwind</emphasis> exception.
- Absorbing that exception will cause stack unwinding to fail. Thus, any code
- that catches all exceptions must re-throw any pending <emphasis>detail::forced_unwind</emphasis>
- exception.
- </para>
- </important>
- <anchor id="cc_prealloc"/>
- <bridgehead renderas="sect3" id="context.cc.h7">
- <phrase id="context.cc.allocating_control_structures_on_top_of_stack"/><link
- linkend="context.cc.allocating_control_structures_on_top_of_stack">Allocating
- control structures on top of stack</link>
- </bridgehead>
- <para>
- Allocating control structures on top of the stack requires to allocated the
- <emphasis>stack_context</emphasis> and create the control structure with placement
- new before <link linkend="cc"><emphasis>continuation</emphasis></link> is created.
- </para>
- <note>
- <para>
- The user is responsible for destructing the control structure at the top
- of the stack.
- </para>
- </note>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
- <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase><phrase role="number">4048</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// allocate stack space</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase><phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">());</phrase>
- <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">=</phrase><phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">=</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase><phrase role="special">-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// placement new creates control structure on reserved space</phrase>
- <phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase><phrase role="special">=</phrase><phrase role="keyword">new</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
- <phrase role="special">...</phrase>
- <phrase role="comment">// destructing the control structure</phrase>
- <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
- <phrase role="special">...</phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
- <phrase role="comment">// captured continuation</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
- <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="comment">// create captured continuation</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">{}</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">),</phrase><phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">entry_func</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">...</phrase>
- <phrase role="special">};</phrase>
- </programlisting>
- <bridgehead renderas="sect3" id="context.cc.h8">
- <phrase id="context.cc.inverting_the_control_flow"/><link linkend="context.cc.inverting_the_control_flow">Inverting
- the control flow</link>
- </bridgehead>
- <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
- <phrase role="comment">/*
- * grammar:
- * P ---> E '\0'
- * E ---> T {('+'|'-') T}
- * T ---> S {('*'|'/') S}
- * S ---> digit | '(' E ')'
- */</phrase>
- <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">pull</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">char_traits</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">>::</phrase><phrase role="identifier">to_char_type</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">());</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">scan</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">do</phrase><phrase role="special">{</phrase>
- <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">pull</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">isspace</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">));</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">Parser</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb_</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="identifier">next</phrase><phrase role="special">(),</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="identifier">is_</phrase><phrase role="special">),</phrase> <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">cb_</phrase><phrase role="special">)</phrase>
- <phrase role="special">{}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">E</phrase><phrase role="special">(){</phrase>
- <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'+'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'-'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">T</phrase><phrase role="special">(){</phrase>
- <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'*'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'/'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">S</phrase><phrase role="special">(){</phrase>
- <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">isdigit</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">)){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'('</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">')'</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase><phrase role="keyword">else</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">else</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">};</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
- <phrase role="comment">// execute parser in new continuation</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">source</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// user-code pulls parsed data from parser</phrase>
- <phrase role="comment">// invert control flow</phrase>
- <phrase role="keyword">char</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
- <phrase role="comment">// create parser with callback function</phrase>
- <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">c_</phrase><phrase role="special">){</phrase>
- <phrase role="comment">// resume main continuation</phrase>
- <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c_</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">});</phrase>
- <phrase role="comment">// start recursive parsing</phrase>
- <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
- <phrase role="comment">// signal termination</phrase>
- <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// resume main continuation</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(!</phrase><phrase role="identifier">done</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- </programlisting>
- <para>
- In this example a recursive descent parser uses a callback to emit a newly
- passed symbol. Using <emphasis>call/cc</emphasis> the control flow can be inverted,
- e.g. the user-code pulls parsed symbols from the parser - instead to get pushed
- from the parser (via callback).
- </para>
- <para>
- The data (character) is transferred between the two continuations.
- </para>
- <section id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber">
- <title><anchor id="implementation0"/><link linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations:
- fcontext_t, ucontext_t and WinFiber</link></title>
- <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h0">
- <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"/><link
- linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</link>
- </bridgehead>
- <para>
- The implementation uses <emphasis>fcontext_t</emphasis> per default. fcontext_t
- is based on assembler and not available for all platforms. It provides a
- much better performance than <emphasis>ucontext_t</emphasis> (the context
- switch takes two magnitudes of order less CPU cycles; see section <link linkend="performance"><emphasis>performance</emphasis></link>)
- and <emphasis>WinFiber</emphasis>.
- </para>
- <note>
- <para>
- Because the TIB (thread information block on Windows) is not fully described
- in the MSDN, it might be possible that not all required TIB-parts are swapped.
- Using WinFiber implementation migh be an alternative.
- </para>
- </note>
- <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h1">
- <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"/><link
- linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</link>
- </bridgehead>
- <para>
- As an alternative, <ulink url="https://en.wikipedia.org/wiki/Setcontext"><emphasis>ucontext_t</emphasis></ulink>
- can be used by compiling with <code><phrase role="identifier">BOOST_USE_UCONTEXT</phrase></code>
- and b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
- role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
- <emphasis>ucontext_t</emphasis> might be available on a broader range of
- POSIX-platforms but has some <link linkend="ucontext"><emphasis>disadvantages</emphasis></link>
- (for instance deprecated since POSIX.1-2003, not C99 conform).
- </para>
- <note>
- <para>
- <link linkend="cc"><emphasis>callcc()</emphasis></link> supports <link
- linkend="segmented"><emphasis>Segmented stacks</emphasis></link> only with
- <emphasis>ucontext_t</emphasis> as its implementation.
- </para>
- </note>
- <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h2">
- <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"/><link
- linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</link>
- </bridgehead>
- <para>
- With <code><phrase role="identifier">BOOST_USE_WINFIB</phrase></code> and
- b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
- role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">winfib</phrase></code>
- Win32-Fibers are used as implementation for <link linkend="cc"><emphasis>callcc()</emphasis></link>.
- </para>
- <note>
- <para>
- The first call of <link linkend="cc"><emphasis>callcc()</emphasis></link>
- converts the thread into a Windows fiber by invoking <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
- role="special">()</phrase></code>. If desired, <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
- role="special">()</phrase></code> has to be called by the user explicitly
- in order to release resources allocated by <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
- role="special">()</phrase></code> (e.g. after using boost.context).
- </para>
- </note>
- </section>
- <section id="context.cc.class__continuation_">
- <title><link linkend="context.cc.class__continuation_">Class <code><phrase
- role="identifier">continuation</phrase></code></link></title>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">continuation</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">class</phrase> <phrase role="identifier">continuation</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">continuation</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">default</phrase><phrase role="special">;</phrase>
- <phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase>
- <phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
- <phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="special">};</phrase>
- </programlisting>
- <para>
- <bridgehead renderas="sect4" id="cc_constructor_bridgehead">
- <phrase id="cc_constructor"/>
- <link linkend="cc_constructor">Constructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">continuation</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Creates a invalid continuation.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_destructor destructor_bridgehead">
- <phrase id="cc_destructor destructor"/>
- <link linkend="cc_destructor
- destructor">Destructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> is a valid continuation, e.g.
- <emphasis>continuation::operator bool()</emphasis> returns <code><phrase
- role="keyword">true</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_move constructor_bridgehead">
- <phrase id="cc_move constructor"/>
- <link linkend="cc_move constructor">Move
- constructor</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves underlying capture continuation to <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_move assignment_bridgehead">
- <phrase id="cc_move assignment"/>
- <link linkend="cc_move assignment">Move assignment
- operator</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves the state of <code><phrase role="identifier">other</phrase></code>
- to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- using move semantics.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_call_bridgehead">
- <phrase id="cc_operator_call"/>
- <link linkend="cc_operator_call">Member function
- <code>operator()</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Captures current continuation and resumes <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>. The function <code><phrase role="identifier">resume_with</phrase></code>,
- is used to execute function <code><phrase role="identifier">fn</phrase></code>
- in the execution context of <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> (e.g. the stack frame of <code><phrase
- role="identifier">fn</phrase></code> is allocated on stack of <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The continuation representing the continuation that has been suspended.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- Function <code><phrase role="identifier">fn</phrase></code> needs to
- return <code><phrase role="identifier">continuation</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- The returned continuation indicates if the suspended continuation has
- terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_bool_bridgehead">
- <phrase id="cc_operator_bool"/>
- <link linkend="cc_operator_bool">Member function
- <code>operator bool</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- points to a captured continuation.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_not_bridgehead">
- <phrase id="cc_operator_not"/>
- <link linkend="cc_operator_not">Member function <code>operator!</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- does not point to a captured continuation.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_equal_bridgehead">
- <phrase id="cc_operator_equal"/>
- <link linkend="cc_operator_equal">Member function
- <code>operator==</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- and <code><phrase role="identifier">other</phrase></code> represent
- the same continuation, <code><phrase role="keyword">false</phrase></code>
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_notequal_bridgehead">
- <phrase id="cc_operator_notequal"/>
- <link linkend="cc_operator_notequal">Member
- function <code>operator!=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code>! (other == * this)</code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_less_bridgehead">
- <phrase id="cc_operator_less"/>
- <link linkend="cc_operator_less">Member function
- <code>operator<</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase> <phrase
- role="special">!=</phrase> <phrase role="identifier">other</phrase></code>
- is true and the implementation-defined total order of <code><phrase
- role="identifier">continuation</phrase></code> values places <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>
- before <code><phrase role="identifier">other</phrase></code>, false
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_greater_bridgehead">
- <phrase id="cc_operator_greater"/>
- <link linkend="cc_operator_greater">Member
- function <code>operator></code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_lesseq_bridgehead">
- <phrase id="cc_operator_lesseq"/>
- <link linkend="cc_operator_lesseq">Member function
- <code>operator<=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
- role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
- role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc_operator_greatereq_bridgehead">
- <phrase id="cc_operator_greatereq"/>
- <link linkend="cc_operator_greatereq">Member
- function <code>operator>=</code>()</link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
- <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
- <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="cc__bridgehead">
- <phrase id="cc_"/>
- <link linkend="cc_">Non-member function <code>operator<<()</code></link>
- </bridgehead>
- </para>
- <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Writes the representation of <code><phrase role="identifier">other</phrase></code>
- to stream <code><phrase role="identifier">os</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">os</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.cc.class__continuation_.h0">
- <phrase id="context.cc.class__continuation_.call_with_current_continuation"/><link
- linkend="context.cc.class__continuation_.call_with_current_continuation">Call
- with current continuation</link>
- </bridgehead>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">continuation</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
- <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Captures current continuation and creates a new continuation prepared
- to execute <code><phrase role="identifier">fn</phrase></code>. <code><phrase
- role="identifier">fixedsize_stack</phrase></code> is used as default
- stack allocator (stack size == fixedsize_stack::traits::default_size()).
- The function with argument type <code><phrase role="identifier">preallocated</phrase></code>,
- is used to create a user defined data <link linkend="cc_prealloc">(for
- instance additional control structures)</link> on top of the stack.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The continuation representing the contexcontinuation that has been
- suspended.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- The returned continuation indicates if the suspended continuation has
- terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- </section>
- <section id="context.stack">
- <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
- <para>
- The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
- which is required to model a <emphasis>stack-allocator concept</emphasis>.
- </para>
- <bridgehead renderas="sect3" id="context.stack.h0">
- <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
- linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
- concept</emphasis></link>
- </bridgehead>
- <para>
- A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
- concept</emphasis> requirements shown in the following table, in which <code><phrase
- role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
- type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
- role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
- is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">size_t</phrase></code>:
- </para>
- <informaltable frame="all">
- <tgroup cols="3">
- <thead>
- <row>
- <entry>
- <para>
- expression
- </para>
- </entry>
- <entry>
- <para>
- return type
- </para>
- </entry>
- <entry>
- <para>
- notes
- </para>
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
- role="identifier">size</phrase><phrase role="special">)</phrase></code>
- </para>
- </entry>
- <entry>
- </entry>
- <entry>
- <para>
- creates a stack allocator
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
- role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- <code><phrase role="identifier">stack_context</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- creates a stack
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
- role="identifier">deallocate</phrase><phrase role="special">(</phrase>
- <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- <code><phrase role="keyword">void</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
- role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code>
- </para>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <important>
- <para>
- The implementation of <code><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code> might include logic to protect against
- exceeding the context's available stack size rather than leaving it as undefined
- behaviour.
- </para>
- </important>
- <important>
- <para>
- Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
- with a <code><phrase role="identifier">stack_context</phrase></code> not
- set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
- results in undefined behaviour.
- </para>
- </important>
- <note>
- <para>
- Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code> stores an address from the top of the stack
- (growing downwards) or the bottom of the stack (growing upwards).
- </para>
- </note>
- <section id="context.stack.protected_fixedsize">
- <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
- which models the <emphasis>stack-allocator concept</emphasis>. It appends
- a guard page at the end of each stack to protect against exceeding the stack.
- If the guard page is accessed (read or write operation) a segmentation fault/access
- violation is generated by the operating system.
- </para>
- <important>
- <para>
- Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That
- is, launching a new coroutine with a new stack is expensive; the allocated
- stack is just as efficient to use as any other stack.
- </para>
- </important>
- <note>
- <para>
- The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
- is <emphasis role="bold">not</emphasis> mapped to physical memory, only
- virtual addresses are used.
- </para>
- </note>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">protected_fixedsize</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">basic_protected_fixesize</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">protected_fixedsize</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h0">
- <phrase id="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
- and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
- role="special">()</phrase> <phrase role="special">&&</phrase>
- <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
- role="identifier">size</phrase><phrase role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
- Bytes and stores a pointer to the stack and its actual size in <code><phrase
- role="identifier">sctx</phrase></code>. Depending on the architecture
- (the stack grows downwards/upwards) the stored address is the highest/lowest
- address of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h1">
- <phrase id="context.stack.protected_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
- linkend="context.stack.protected_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
- role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
- role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
- <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">)</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
- role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
- <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">.</phrase><phrase role="identifier">size</phrase><phrase
- role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Deallocates the stack space.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack.pooled_fixedsize">
- <title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>pooled_fixedsize_stack</emphasis>
- which models the <emphasis>stack-allocator concept</emphasis>. In contrast
- to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
- page at the end of each stack. The memory is managed internally by <ulink
- url="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html"><code><phrase
- role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
- role="identifier">pool</phrase><phrase role="special"><></phrase></code></ulink>.
- </para>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">pooled_fixedsize_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">stack_size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">(),</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase> <phrase role="special">=</phrase> <phrase role="number">32</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">pooled_fixedsize_stack</phrase><phrase role="special">;</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h0">
- <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"/><link
- linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"><code><phrase
- role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase
- role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
- <phrase role="identifier">stack_size</phrase><phrase role="special">,</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase><phrase
- role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase><phrase
- role="special">)</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
- role="special">()</phrase> <phrase role="special">&&</phrase>
- <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
- role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>
- and <code><phrase role="number">0</phrase> <phrase role="special"><</phrase>
- <phrase role="identifier">nest_size</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
- Bytes and stores a pointer to the stack and its actual size in <code><phrase
- role="identifier">sctx</phrase></code>. Depending on the architecture
- (the stack grows downwards/upwards) the stored address is the highest/lowest
- address of the stack. Argument <code><phrase role="identifier">next_size</phrase></code>
- determines the number of stacks to request from the system the first
- time that <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- needs to allocate system memory. The third argument <code><phrase role="identifier">max_size</phrase></code>
- controls how many memory might be allocated for stacks - a value of
- zero means no uper limit.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h1">
- <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
- role="special">()</phrase> <phrase role="special">&&</phrase>
- <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
- role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
- Bytes and stores a pointer to the stack and its actual size in <code><phrase
- role="identifier">sctx</phrase></code>. Depending on the architecture
- (the stack grows downwards/upwards) the stored address is the highest/lowest
- address of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h2">
- <phrase id="context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
- linkend="context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
- role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
- role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
- <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">)</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">sp</phrase></code> is valid, <code><phrase role="special">!</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
- <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">.</phrase><phrase role="identifier">size</phrase><phrase
- role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Deallocates the stack space.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack.fixedsize">
- <title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>fixedsize_stack</emphasis>
- which models the <emphasis>stack-allocator concept</emphasis>. In contrast
- to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
- page at the end of each stack. The memory is simply managed by <code><phrase
- role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">malloc</phrase><phrase
- role="special">()</phrase></code> and <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">free</phrase><phrase
- role="special">()</phrase></code>.
- </para>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">fixedsize_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">basic_fixesize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">fixedsize_stack</phrase><phrase role="special">;</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.fixedsize.h0">
- <phrase id="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
- and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
- role="special">()</phrase> <phrase role="special">&&</phrase>
- <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
- role="identifier">size</phrase><phrase role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
- Bytes and stores a pointer to the stack and its actual size in <code><phrase
- role="identifier">sctx</phrase></code>. Depending on the architecture
- (the stack grows downwards/upwards) the stored address is the highest/lowest
- address of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.fixedsize.h1">
- <phrase id="context.stack.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
- linkend="context.stack.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
- role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
- role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
- <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">)</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
- role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
- <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">.</phrase><phrase role="identifier">size</phrase><phrase
- role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Deallocates the stack space.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack.segmented">
- <title><anchor id="segmented"/><link linkend="context.stack.segmented">Class
- <emphasis>segmented_stack</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> supports usage of a <link
- linkend="segmented"><emphasis>segmented_stack</emphasis></link>, e. g. the
- size of the stack grows on demand. The coroutine is created with a minimal
- stack size and will be increased as required. Class <link linkend="segmented"><emphasis>segmented_stack</emphasis></link>
- models the <emphasis>stack-allocator concept</emphasis>. In contrast to
- <emphasis>protected_fixedsize_stack</emphasis> and <emphasis>fixedsize_stack</emphasis>
- it creates a stack which grows on demand.
- </para>
- <note>
- <para>
- Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
- from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis>
- from version <emphasis role="bold">3.4</emphasis> onwards. In order to
- use a <emphasis>segmented_stack</emphasis> <emphasis role="bold">Boost.Context</emphasis>
- must be built with property <code><phrase role="identifier">segmented</phrase><phrase
- role="special">-</phrase><phrase role="identifier">stacks</phrase></code>,
- e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> and
- applying <code><phrase role="identifier">BOOST_USE_SEGMENTED_STACKS</phrase></code>
- at b2/bjam command line.
- </para>
- </note>
- <note>
- <para>
- Segmented stacks can only be used with <link linkend="cc"><emphasis>callcc()</emphasis></link>
- (using <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>)
- </para>
- </note>
- <para>
- .
- </para>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">segmented_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_segmented_stack</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">basic_segmented_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_segmented_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">segmented_stack</phrase><phrase role="special">;</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.segmented.h0">
- <phrase id="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
- and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
- role="special">()</phrase> <phrase role="special">&&</phrase>
- <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
- role="identifier">size</phrase><phrase role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
- Bytes and stores a pointer to the stack and its actual size in <code><phrase
- role="identifier">sctx</phrase></code>. Depending on the architecture
- (the stack grows downwards/upwards) the stored address is the highest/lowest
- address of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.segmented.h1">
- <phrase id="context.stack.segmented._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
- linkend="context.stack.segmented._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
- role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
- role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
- <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">)</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
- role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
- role="special">:</phrase><phrase role="identifier">size</phrase><phrase
- role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
- role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
- role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
- <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
- <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
- role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
- role="identifier">size</phrase><phrase role="special">()</phrase>
- <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
- role="special">.</phrase><phrase role="identifier">size</phrase><phrase
- role="special">)</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Deallocates the stack space.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <note>
- <para>
- If the library is compiled for segmented stacks, <emphasis>segmented_stack</emphasis>
- is the only available stack allocator.
- </para>
- </note>
- </section>
- <section id="context.stack.stack_traits">
- <title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title>
- <para>
- <emphasis>stack_traits</emphasis> models a <emphasis>stack-traits</emphasis>
- providing a way to access certain properites defined by the enironment. Stack
- allocators use <emphasis>stack-traits</emphasis> to allocate stacks.
- </para>
- <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">stack_traits</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="keyword">struct</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">page_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.stack_traits.h0">
- <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
- role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns <code><phrase role="keyword">true</phrase></code> if the environment
- defines no limit for the size of a stack.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.stack_traits.h1">
- <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
- role="identifier">page_size</phrase><phrase role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns the page size in bytes.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.stack_traits.h2">
- <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_size__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_size__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
- role="identifier">default_size</phrase><phrase role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns a default stack size, which may be platform specific. If the
- stack is unbounded then the present implementation returns the maximum
- of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
- and <code><phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.stack_traits.h3">
- <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_size__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_size__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
- role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns the minimum size in bytes of stack defined by the environment
- (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.stack_traits.h4">
- <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_size__phrase__phrase_role__special______phrase___code_"/><link
- linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_size__phrase__phrase_role__special______phrase___code_"><code><phrase
- role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
- role="identifier">maximum_size</phrase><phrase role="special">()</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Preconditions:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code>
- returns <code><phrase role="keyword">false</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns the maximum size in bytes of stack defined by the environment.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack.stack_context">
- <title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>stack_context</emphasis>
- which will contain the stack pointer and the size of the stack. In case of
- a <link linkend="segmented"><emphasis>segmented_stack</emphasis></link>,
- <emphasis>stack_context</emphasis> contains some extra control structures.
- </para>
- <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// might contain additional control structures</phrase>
- <phrase role="comment">// for segmented stacks</phrase>
- <phrase role="special">}</phrase>
- </programlisting>
- <bridgehead renderas="sect4" id="context.stack.stack_context.h0">
- <phrase id="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
- linkend="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase
- role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Value:</term>
- <listitem>
- <para>
- Pointer to the beginning of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <bridgehead renderas="sect4" id="context.stack.stack_context.h1">
- <phrase id="context.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"/><link
- linkend="context.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"><code><phrase
- role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
- <phrase role="identifier">size</phrase></code></link>
- </bridgehead>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Value:</term>
- <listitem>
- <para>
- Actual size of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack.valgrind">
- <title><link linkend="context.stack.valgrind">Support for valgrind</link></title>
- <para>
- Running programs that switch stacks under valgrind causes problems. Property
- (b2 command-line) <code><phrase role="identifier">valgrind</phrase><phrase
- role="special">=</phrase><phrase role="identifier">on</phrase></code> let
- valgrind treat the memory regions as stack space which suppresses the errors.
- Users must define <code><phrase role="identifier">BOOST_USE_VALGRIND</phrase></code>
- before including any Boost.Context headers when linking against Boost binaries
- compiled with <code><phrase role="identifier">valgrind</phrase><phrase role="special">=</phrase><phrase
- role="identifier">on</phrase></code>.
- </para>
- </section>
- <section id="context.stack.sanitizers">
- <title><link linkend="context.stack.sanitizers">Support for sanitizers</link></title>
- <para>
- Sanitizers (GCC/Clang) are confused by the stack switches. The library is
- required to be compiled with property (b2 command-line) <code><phrase role="identifier">context</phrase><phrase
- role="special">-</phrase><phrase role="identifier">impl</phrase><phrase role="special">=</phrase><phrase
- role="identifier">ucontext</phrase></code> and compilers santizer options.
- Users must define <code><phrase role="identifier">BOOST_USE_ASAN</phrase></code>
- before including any Boost.Context headers when linking against Boost binaries.
- </para>
- </section>
- </section>
- <section id="context.struct__preallocated_">
- <title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title>
- <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="special">};</phrase>
- </programlisting>
- <bridgehead renderas="sect3" id="context.struct__preallocated_.h0">
- <phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link>
- </bridgehead>
- <programlisting><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- </programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Creates an object of preallocated.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.performance">
- <title><anchor id="performance"/><link linkend="context.performance">Performance</link></title>
- <para>
- Performance measurements were taken using <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
- role="special">::</phrase><phrase role="identifier">highresolution_clock</phrase></code>,
- with overhead corrections. The code was compiled with gcc-6.3.1, using build
- options: variant = release, optimization = speed. Tests were executed on dual
- Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM, running Linux (x86_64).
- </para>
- <table frame="all" id="context.performance.performance_of_context_switch">
- <title>Performance of context switch</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>
- <para>
- callcc()/continuation (fcontext_t)
- </para>
- </entry>
- <entry>
- <para>
- callcc()/continuation (ucontext_t)
- </para>
- </entry>
- <entry>
- <para>
- callcc()/continuation (Windows-Fiber)
- </para>
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <para>
- 9 ns / 19 CPU cycles
- </para>
- </entry>
- <entry>
- <para>
- 547 ns / 1130 CPU cycles
- </para>
- </entry>
- <entry>
- <para>
- 49 ns / 98 CPU cycles
- </para>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section id="context.architectures">
- <title><link linkend="context.architectures">Architectures</link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis>, using <link linkend="implementation"><emphasis>fcontext_t</emphasis></link>,
- supports following architectures:
- </para>
- <table frame="all" id="context.architectures.supported_architectures___abi_binary_format__">
- <title>Supported architectures (<ABI|binary format>)</title>
- <tgroup cols="5">
- <thead>
- <row>
- <entry>
- <para>
- Architecture
- </para>
- </entry>
- <entry>
- <para>
- LINUX (UNIX)
- </para>
- </entry>
- <entry>
- <para>
- Windows
- </para>
- </entry>
- <entry>
- <para>
- MacOS X
- </para>
- </entry>
- <entry>
- <para>
- iOS
- </para>
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <para>
- arm (aarch32)
- </para>
- </entry>
- <entry>
- <para>
- AAPCS|ELF
- </para>
- </entry>
- <entry>
- <para>
- AAPCS|PE
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- AAPCS|MACH-O
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- arm (aarch64)
- </para>
- </entry>
- <entry>
- <para>
- AAPCS|ELF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- AAPCS|MACH-O
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- i386
- </para>
- </entry>
- <entry>
- <para>
- SYSV|ELF
- </para>
- </entry>
- <entry>
- <para>
- MS|PE
- </para>
- </entry>
- <entry>
- <para>
- SYSV|MACH-O
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- mips1
- </para>
- </entry>
- <entry>
- <para>
- O32|ELF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- ppc32
- </para>
- </entry>
- <entry>
- <para>
- SYSV|ELF,XCOFF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- SYSV|MACH-O
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- ppc64
- </para>
- </entry>
- <entry>
- <para>
- SYSV|ELF,XCOFF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- SYSV|MACH-O
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- riscv64
- </para>
- </entry>
- <entry>
- <para>
- SYSV|ELF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- SYSV
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- s390x
- </para>
- </entry>
- <entry>
- <para>
- SYSV|ELF
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- sparc
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- x86_64
- </para>
- </entry>
- <entry>
- <para>
- SYSV,X32|ELF
- </para>
- </entry>
- <entry>
- <para>
- MS|PE
- </para>
- </entry>
- <entry>
- <para>
- SYSV|MACH-O
- </para>
- </entry>
- <entry>
- <para>
- -
- </para>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <note>
- <para>
- If the architecture is not supported but the platform provides <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>,
- <emphasis role="bold">Boost.Context</emphasis> should be compiled with <code><phrase
- role="identifier">BOOST_USE_UCONTEXT</phrase></code> and b2 property <code><phrase
- role="identifier">context</phrase><phrase role="special">-</phrase><phrase
- role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
- </para>
- </note>
- <section id="context.architectures.crosscompiling">
- <title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title>
- <para>
- Cross compiling the library requires to specify the build properties <architecture>,
- <address-model>, <binary-format> and <abi> at b2 command
- line.
- </para>
- </section>
- </section>
- <section id="context.rationale">
- <title><link linkend="context.rationale">Rationale</link></title>
- <bridgehead renderas="sect3" id="context.rationale.h0">
- <phrase id="context.rationale.no_inline_assembler"/><link linkend="context.rationale.no_inline_assembler">No
- inline-assembler</link>
- </bridgehead>
- <para>
- Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
- inline assembler. <footnote id="context.rationale.f0">
- <para>
- <ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article
- 'Inline Assembler'</ulink>
- </para>
- </footnote>. Inlined assembler generates code bloating which is not welcome
- on embedded systems.
- </para>
- <bridgehead renderas="sect3" id="context.rationale.h1">
- <phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link>
- </bridgehead>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the low level API fcontext_t
- which is implemented in assembler to provide context swapping operations. fcontext_t
- is the part to port to new platforms.
- </para>
- <note>
- <para>
- Context switches do not preserve the signal mask on UNIX systems.
- </para>
- </note>
- <para>
- <emphasis>fcontext_t</emphasis> is an opaque pointer.
- </para>
- <section id="context.rationale.other_apis_">
- <title><link linkend="context.rationale.other_apis_">Other APIs </link></title>
- <bridgehead renderas="sect4" id="context.rationale.other_apis_.h0">
- <phrase id="context.rationale.other_apis_.setjmp___longjmp__"/><link linkend="context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</link>
- </bridgehead>
- <para>
- C99 defines <code><phrase role="identifier">setjmp</phrase><phrase role="special">()</phrase></code>/<code><phrase
- role="identifier">longjmp</phrase><phrase role="special">()</phrase></code>
- to provide non-local jumps but it does not require that <emphasis>longjmp()</emphasis>
- preserves the current stack frame. Therefore, jumping into a function which
- was exited via a call to <emphasis>longjmp()</emphasis> is undefined <footnote
- id="context.rationale.other_apis_.f0">
- <para>
- ISO/IEC 9899:1999, 2005, 7.13.2.1:2
- </para>
- </footnote>.
- </para>
- <anchor id="ucontext"/>
- <bridgehead renderas="sect4" id="context.rationale.other_apis_.h1">
- <phrase id="context.rationale.other_apis_.ucontext_t"/><link linkend="context.rationale.other_apis_.ucontext_t">ucontext_t</link>
- </bridgehead>
- <para>
- Since POSIX.1-2004 <code><phrase role="identifier">ucontext_t</phrase></code>
- is deprecated and was removed in POSIX.1-2008! The function signature of
- <code><phrase role="identifier">makecontext</phrase><phrase role="special">()</phrase></code>
- is:
- </para>
- <programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">makecontext</phrase><phrase role="special">(</phrase><phrase role="identifier">ucontext_t</phrase> <phrase role="special">*</phrase><phrase role="identifier">ucp</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">(*</phrase><phrase role="identifier">func</phrase><phrase role="special">)(),</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">argc</phrase><phrase role="special">,</phrase> <phrase role="special">...);</phrase>
- </programlisting>
- <para>
- The third argument of <code><phrase role="identifier">makecontext</phrase><phrase
- role="special">()</phrase></code> specifies the number of integer arguments
- that follow which will require function pointer cast if <code><phrase role="identifier">func</phrase></code>
- will accept those arguments which is undefined in C99 <footnote id="context.rationale.other_apis_.f1">
- <para>
- ISO/IEC 9899:1999, 2005, J.2
- </para>
- </footnote>.
- </para>
- <para>
- The arguments in the var-arg list are required to be integers, passing pointers
- in var-arg list is not guaranteed to work, especially it will fail for architectures
- where pointers are larger than integers.
- </para>
- <para>
- <code><phrase role="identifier">ucontext_t</phrase></code> preserves signal
- mask between context switches which involves system calls consuming a lot
- of CPU cycles (ucontext_t is slower; a context switch takes <link linkend="performance"><emphasis>two
- magnitutes of order more CPU cycles</emphasis></link> more than <emphasis>fcontext_t</emphasis>).
- </para>
- <bridgehead renderas="sect4" id="context.rationale.other_apis_.h2">
- <phrase id="context.rationale.other_apis_.windows_fibers"/><link linkend="context.rationale.other_apis_.windows_fibers">Windows
- fibers</link>
- </bridgehead>
- <para>
- A drawback of Windows Fiber API is that <code><phrase role="identifier">CreateFiber</phrase><phrase
- role="special">()</phrase></code> does not accept a pointer to user allocated
- stack space preventing the reuse of stacks for other context instances. Because
- the Windows Fiber API requires to call <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
- role="special">()</phrase></code> if <code><phrase role="identifier">SwitchFiber</phrase><phrase
- role="special">()</phrase></code> is called for a thread which has not been
- converted to a fiber. For the same reason <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
- role="special">()</phrase></code> must be called after return from <code><phrase
- role="identifier">SwitchFiber</phrase><phrase role="special">()</phrase></code>
- if the thread was forced to be converted to a fiber before (which is inefficient).
- </para>
- <programlisting><phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">is_a_fiber</phrase><phrase role="special">()</phrase> <phrase role="special">)</phrase>
- <phrase role="special">{</phrase>
- <phrase role="identifier">ConvertThreadToFiber</phrase><phrase role="special">(</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">SwitchToFiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">ConvertFiberToThread</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- </programlisting>
- <para>
- If the condition <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase
- role="special">>=</phrase> <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code>
- is met function <code><phrase role="identifier">IsThreadAFiber</phrase><phrase
- role="special">()</phrase></code> is provided in order to detect if the current
- thread was already converted. Unfortunately Windows XP + SP 2/3 defines
- <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase role="special">>=</phrase>
- <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> without providing
- <code><phrase role="identifier">IsThreadAFiber</phrase><phrase role="special">()</phrase></code>.
- </para>
- </section>
- <section id="context.rationale.x86_and_floating_point_env">
- <title><link linkend="context.rationale.x86_and_floating_point_env">x86 and
- floating-point env</link></title>
- <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h0">
- <phrase id="context.rationale.x86_and_floating_point_env.i386"/><link linkend="context.rationale.x86_and_floating_point_env.i386">i386</link>
- </bridgehead>
- <para>
- "The FpCsr and the MxCsr register must be saved and restored before
- any call or return by any procedure that needs to modify them ..."
- <footnote id="context.rationale.x86_and_floating_point_env.f0">
- <para>
- 'Calling Conventions', Agner Fog
- </para>
- </footnote>.
- </para>
- <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h1">
- <phrase id="context.rationale.x86_and_floating_point_env.x86_64"/><link linkend="context.rationale.x86_and_floating_point_env.x86_64">x86_64</link>
- </bridgehead>
- <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h2">
- <phrase id="context.rationale.x86_and_floating_point_env.windows"/><link
- linkend="context.rationale.x86_and_floating_point_env.windows">Windows</link>
- </bridgehead>
- <para>
- MxCsr - "A callee that modifies any of the non-volatile fields within
- MxCsr must restore them before returning to its caller. Furthermore, a caller
- that has modified any of these fields must restore them to their standard
- values before invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f1">
- <para>
- <ulink url="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx">MSDN
- article 'MxCsr'</ulink>
- </para>
- </footnote>.
- </para>
- <para>
- FpCsr - "A callee that modifies any of the fields within FpCsr must
- restore them before returning to its caller. Furthermore, a caller that has
- modified any of these fields must restore them to their standard values before
- invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f2">
- <para>
- <ulink url="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx">MSDN
- article 'FpCsr'</ulink>
- </para>
- </footnote>.
- </para>
- <para>
- "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved
- across context switches. There is no explicit calling convention for these
- registers." <footnote id="context.rationale.x86_and_floating_point_env.f3">
- <para>
- <ulink url="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx">MSDN
- article 'Legacy Floating-Point Support'</ulink>
- </para>
- </footnote>.
- </para>
- <para>
- "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
- <footnote id="context.rationale.x86_and_floating_point_env.f4">
- <para>
- 'Calling Conventions', Agner Fog
- </para>
- </footnote>.
- </para>
- <para>
- "XMM6-XMM15 must be preserved" <footnote id="context.rationale.x86_and_floating_point_env.f5">
- <para>
- <ulink url="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx">MSDN
- article 'Register Usage'</ulink>
- </para>
- </footnote>
- </para>
- <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h3">
- <phrase id="context.rationale.x86_and_floating_point_env.sysv"/><link linkend="context.rationale.x86_and_floating_point_env.sysv">SysV</link>
- </bridgehead>
- <para>
- "The control bits of the MxCsr register are callee-saved (preserved
- across calls), while the status bits are caller-saved (not preserved). The
- x87 status word register is caller-saved, whereas the x87 control word (FpCsr)
- is callee-saved." <footnote id="context.rationale.x86_and_floating_point_env.f6">
- <para>
- SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4,
- 3.2.1
- </para>
- </footnote>.
- </para>
- </section>
- </section>
- <section id="context.reference">
- <title><link linkend="context.reference">Reference</link></title>
- <bridgehead renderas="sect3" id="context.reference.h0">
- <phrase id="context.reference.arm"/><link linkend="context.reference.arm">ARM</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- AAPCS ABI: Procedure Call Standard for the ARM Architecture
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
- </simpara>
- </listitem>
- </itemizedlist>
- <bridgehead renderas="sect3" id="context.reference.h1">
- <phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
- </simpara>
- </listitem>
- </itemizedlist>
- <bridgehead renderas="sect3" id="context.reference.h2">
- <phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
- </simpara>
- </listitem>
- </itemizedlist>
- <bridgehead renderas="sect3" id="context.reference.h3">
- <phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- SYSV ABI: PowerPC User Instruction Set Architecture, Book I
- </simpara>
- </listitem>
- </itemizedlist>
- <bridgehead renderas="sect3" id="context.reference.h4">
- <phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
- Processor Supplement
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling
- Conventions</ulink>
- </simpara>
- </listitem>
- </itemizedlist>
- <bridgehead renderas="sect3" id="context.reference.h5">
- <phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link>
- </bridgehead>
- <itemizedlist>
- <listitem>
- <simpara>
- SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
- Supplement
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64
- Software Conventions</ulink>
- </simpara>
- </listitem>
- </itemizedlist>
- </section>
- <section id="context.acknowledgements">
- <title><link linkend="context.acknowledgements">Acknowledgments</link></title>
- <para>
- I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins,
- Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull,
- Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin
- Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente
- J. Botet Escriba, Wayne Piekarski.
- </para>
- </section>
- </library>
|