1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841 |
- @node Memory, Character Handling, Error Reporting, Top
- @chapter Virtual Memory Allocation And Paging
- @c %MENU% Allocating virtual memory and controlling paging
- @cindex memory allocation
- @cindex storage allocation
- This chapter describes how processes manage and use memory in a system
- that uses @theglibc{}.
- @Theglibc{} has several functions for dynamically allocating
- virtual memory in various ways. They vary in generality and in
- efficiency. The library also provides functions for controlling paging
- and allocation of real memory.
- @menu
- * Memory Concepts:: An introduction to concepts and terminology.
- * Memory Allocation:: Allocating storage for your program data
- * Resizing the Data Segment:: @code{brk}, @code{sbrk}
- * Memory Protection:: Controlling access to memory regions.
- * Locking Pages:: Preventing page faults
- @end menu
- Memory mapped I/O is not discussed in this chapter. @xref{Memory-mapped I/O}.
- @node Memory Concepts
- @section Process Memory Concepts
- One of the most basic resources a process has available to it is memory.
- There are a lot of different ways systems organize memory, but in a
- typical one, each process has one linear virtual address space, with
- addresses running from zero to some huge maximum. It need not be
- contiguous; i.e., not all of these addresses actually can be used to
- store data.
- The virtual memory is divided into pages (4 kilobytes is typical).
- Backing each page of virtual memory is a page of real memory (called a
- @dfn{frame}) or some secondary storage, usually disk space. The disk
- space might be swap space or just some ordinary disk file. Actually, a
- page of all zeroes sometimes has nothing at all backing it -- there's
- just a flag saying it is all zeroes.
- @cindex page frame
- @cindex frame, real memory
- @cindex swap space
- @cindex page, virtual memory
- The same frame of real memory or backing store can back multiple virtual
- pages belonging to multiple processes. This is normally the case, for
- example, with virtual memory occupied by @glibcadj{} code. The same
- real memory frame containing the @code{printf} function backs a virtual
- memory page in each of the existing processes that has a @code{printf}
- call in its program.
- In order for a program to access any part of a virtual page, the page
- must at that moment be backed by (``connected to'') a real frame. But
- because there is usually a lot more virtual memory than real memory, the
- pages must move back and forth between real memory and backing store
- regularly, coming into real memory when a process needs to access them
- and then retreating to backing store when not needed anymore. This
- movement is called @dfn{paging}.
- When a program attempts to access a page which is not at that moment
- backed by real memory, this is known as a @dfn{page fault}. When a page
- fault occurs, the kernel suspends the process, places the page into a
- real page frame (this is called ``paging in'' or ``faulting in''), then
- resumes the process so that from the process' point of view, the page
- was in real memory all along. In fact, to the process, all pages always
- seem to be in real memory. Except for one thing: the elapsed execution
- time of an instruction that would normally be a few nanoseconds is
- suddenly much, much, longer (because the kernel normally has to do I/O
- to complete the page-in). For programs sensitive to that, the functions
- described in @ref{Locking Pages} can control it.
- @cindex page fault
- @cindex paging
- Within each virtual address space, a process has to keep track of what
- is at which addresses, and that process is called memory allocation.
- Allocation usually brings to mind meting out scarce resources, but in
- the case of virtual memory, that's not a major goal, because there is
- generally much more of it than anyone needs. Memory allocation within a
- process is mainly just a matter of making sure that the same byte of
- memory isn't used to store two different things.
- Processes allocate memory in two major ways: by exec and
- programmatically. Actually, forking is a third way, but it's not very
- interesting. @xref{Creating a Process}.
- Exec is the operation of creating a virtual address space for a process,
- loading its basic program into it, and executing the program. It is
- done by the ``exec'' family of functions (e.g. @code{execl}). The
- operation takes a program file (an executable), it allocates space to
- load all the data in the executable, loads it, and transfers control to
- it. That data is most notably the instructions of the program (the
- @dfn{text}), but also literals and constants in the program and even
- some variables: C variables with the static storage class (@pxref{Memory
- Allocation and C}).
- @cindex executable
- @cindex literals
- @cindex constants
- Once that program begins to execute, it uses programmatic allocation to
- gain additional memory. In a C program with @theglibc{}, there
- are two kinds of programmatic allocation: automatic and dynamic.
- @xref{Memory Allocation and C}.
- Memory-mapped I/O is another form of dynamic virtual memory allocation.
- Mapping memory to a file means declaring that the contents of certain
- range of a process' addresses shall be identical to the contents of a
- specified regular file. The system makes the virtual memory initially
- contain the contents of the file, and if you modify the memory, the
- system writes the same modification to the file. Note that due to the
- magic of virtual memory and page faults, there is no reason for the
- system to do I/O to read the file, or allocate real memory for its
- contents, until the program accesses the virtual memory.
- @xref{Memory-mapped I/O}.
- @cindex memory mapped I/O
- @cindex memory mapped file
- @cindex files, accessing
- Just as it programmatically allocates memory, the program can
- programmatically deallocate (@dfn{free}) it. You can't free the memory
- that was allocated by exec. When the program exits or execs, you might
- say that all its memory gets freed, but since in both cases the address
- space ceases to exist, the point is really moot. @xref{Program
- Termination}.
- @cindex execing a program
- @cindex freeing memory
- @cindex exiting a program
- A process' virtual address space is divided into segments. A segment is
- a contiguous range of virtual addresses. Three important segments are:
- @itemize @bullet
- @item
- The @dfn{text segment} contains a program's instructions and literals and
- static constants. It is allocated by exec and stays the same size for
- the life of the virtual address space.
- @item
- The @dfn{data segment} is working storage for the program. It can be
- preallocated and preloaded by exec and the process can extend or shrink
- it by calling functions as described in @xref{Resizing the Data
- Segment}. Its lower end is fixed.
- @item
- The @dfn{stack segment} contains a program stack. It grows as the stack
- grows, but doesn't shrink when the stack shrinks.
- @end itemize
- @node Memory Allocation
- @section Allocating Storage For Program Data
- This section covers how ordinary programs manage storage for their data,
- including the famous @code{malloc} function and some fancier facilities
- special to @theglibc{} and GNU Compiler.
- @menu
- * Memory Allocation and C:: How to get different kinds of allocation in C.
- * The GNU Allocator:: An overview of the GNU @code{malloc}
- implementation.
- * Unconstrained Allocation:: The @code{malloc} facility allows fully general
- dynamic allocation.
- * Allocation Debugging:: Finding memory leaks and not freed memory.
- * Replacing malloc:: Using your own @code{malloc}-style allocator.
- * Obstacks:: Obstacks are less general than malloc
- but more efficient and convenient.
- * Variable Size Automatic:: Allocation of variable-sized blocks
- of automatic storage that are freed when the
- calling function returns.
- @end menu
- @node Memory Allocation and C
- @subsection Memory Allocation in C Programs
- The C language supports two kinds of memory allocation through the
- variables in C programs:
- @itemize @bullet
- @item
- @dfn{Static allocation} is what happens when you declare a static or
- global variable. Each static or global variable defines one block of
- space, of a fixed size. The space is allocated once, when your program
- is started (part of the exec operation), and is never freed.
- @cindex static memory allocation
- @cindex static storage class
- @item
- @dfn{Automatic allocation} happens when you declare an automatic
- variable, such as a function argument or a local variable. The space
- for an automatic variable is allocated when the compound statement
- containing the declaration is entered, and is freed when that
- compound statement is exited.
- @cindex automatic memory allocation
- @cindex automatic storage class
- In GNU C, the size of the automatic storage can be an expression
- that varies. In other C implementations, it must be a constant.
- @end itemize
- A third important kind of memory allocation, @dfn{dynamic allocation},
- is not supported by C variables but is available via @glibcadj{}
- functions.
- @cindex dynamic memory allocation
- @subsubsection Dynamic Memory Allocation
- @cindex dynamic memory allocation
- @dfn{Dynamic memory allocation} is a technique in which programs
- determine as they are running where to store some information. You need
- dynamic allocation when the amount of memory you need, or how long you
- continue to need it, depends on factors that are not known before the
- program runs.
- For example, you may need a block to store a line read from an input
- file; since there is no limit to how long a line can be, you must
- allocate the memory dynamically and make it dynamically larger as you
- read more of the line.
- Or, you may need a block for each record or each definition in the input
- data; since you can't know in advance how many there will be, you must
- allocate a new block for each record or definition as you read it.
- When you use dynamic allocation, the allocation of a block of memory is
- an action that the program requests explicitly. You call a function or
- macro when you want to allocate space, and specify the size with an
- argument. If you want to free the space, you do so by calling another
- function or macro. You can do these things whenever you want, as often
- as you want.
- Dynamic allocation is not supported by C variables; there is no storage
- class ``dynamic'', and there can never be a C variable whose value is
- stored in dynamically allocated space. The only way to get dynamically
- allocated memory is via a system call (which is generally via a @glibcadj{}
- function call), and the only way to refer to dynamically
- allocated space is through a pointer. Because it is less convenient,
- and because the actual process of dynamic allocation requires more
- computation time, programmers generally use dynamic allocation only when
- neither static nor automatic allocation will serve.
- For example, if you want to allocate dynamically some space to hold a
- @code{struct foobar}, you cannot declare a variable of type @code{struct
- foobar} whose contents are the dynamically allocated space. But you can
- declare a variable of pointer type @code{struct foobar *} and assign it the
- address of the space. Then you can use the operators @samp{*} and
- @samp{->} on this pointer variable to refer to the contents of the space:
- @smallexample
- @{
- struct foobar *ptr
- = (struct foobar *) malloc (sizeof (struct foobar));
- ptr->name = x;
- ptr->next = current_foobar;
- current_foobar = ptr;
- @}
- @end smallexample
- @node The GNU Allocator
- @subsection The GNU Allocator
- @cindex gnu allocator
- The @code{malloc} implementation in @theglibc{} is derived from ptmalloc
- (pthreads malloc), which in turn is derived from dlmalloc (Doug Lea malloc).
- This malloc may allocate memory in two different ways depending on their size
- and certain parameters that may be controlled by users. The most common way is
- to allocate portions of memory (called chunks) from a large contiguous area of
- memory and manage these areas to optimize their use and reduce wastage in the
- form of unusable chunks. Traditionally the system heap was set up to be the one
- large memory area but the @glibcadj{} @code{malloc} implementation maintains
- multiple such areas to optimize their use in multi-threaded applications. Each
- such area is internally referred to as an @dfn{arena}.
- As opposed to other versions, the @code{malloc} in @theglibc{} does not round
- up chunk sizes to powers of two, neither for large nor for small sizes.
- Neighboring chunks can be coalesced on a @code{free} no matter what their size
- is. This makes the implementation suitable for all kinds of allocation
- patterns without generally incurring high memory waste through fragmentation.
- The presence of multiple arenas allows multiple threads to allocate
- memory simultaneously in separate arenas, thus improving performance.
- The other way of memory allocation is for very large blocks, i.e. much larger
- than a page. These requests are allocated with @code{mmap} (anonymous or via
- @file{/dev/zero}; @pxref{Memory-mapped I/O})). This has the great advantage
- that these chunks are returned to the system immediately when they are freed.
- Therefore, it cannot happen that a large chunk becomes ``locked'' in between
- smaller ones and even after calling @code{free} wastes memory. The size
- threshold for @code{mmap} to be used is dynamic and gets adjusted according to
- allocation patterns of the program. @code{mallopt} can be used to statically
- adjust the threshold using @code{M_MMAP_THRESHOLD} and the use of @code{mmap}
- can be disabled completely with @code{M_MMAP_MAX};
- @pxref{Malloc Tunable Parameters}.
- A more detailed technical description of the GNU Allocator is maintained in
- the @glibcadj{} wiki. See
- @uref{https://sourceware.org/glibc/wiki/MallocInternals}.
- It is possible to use your own custom @code{malloc} instead of the
- built-in allocator provided by @theglibc{}. @xref{Replacing malloc}.
- @node Unconstrained Allocation
- @subsection Unconstrained Allocation
- @cindex unconstrained memory allocation
- @cindex @code{malloc} function
- @cindex heap, dynamic allocation from
- The most general dynamic allocation facility is @code{malloc}. It
- allows you to allocate blocks of memory of any size at any time, make
- them bigger or smaller at any time, and free the blocks individually at
- any time (or never).
- @menu
- * Basic Allocation:: Simple use of @code{malloc}.
- * Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}.
- * Freeing after Malloc:: Use @code{free} to free a block you
- got with @code{malloc}.
- * Changing Block Size:: Use @code{realloc} to make a block
- bigger or smaller.
- * Allocating Cleared Space:: Use @code{calloc} to allocate a
- block and clear it.
- * Aligned Memory Blocks:: Allocating specially aligned memory.
- * Malloc Tunable Parameters:: Use @code{mallopt} to adjust allocation
- parameters.
- * Heap Consistency Checking:: Automatic checking for errors.
- * Hooks for Malloc:: You can use these hooks for debugging
- programs that use @code{malloc}.
- * Statistics of Malloc:: Getting information about how much
- memory your program is using.
- * Summary of Malloc:: Summary of @code{malloc} and related functions.
- @end menu
- @node Basic Allocation
- @subsubsection Basic Memory Allocation
- @cindex allocation of memory with @code{malloc}
- To allocate a block of memory, call @code{malloc}. The prototype for
- this function is in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun {void *} malloc (size_t @var{size})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Malloc hooks and __morecore pointers, as well as such parameters as
- @c max_n_mmaps and max_mmapped_mem, are accessed without guards, so they
- @c could pose a thread safety issue; in order to not declare malloc
- @c MT-unsafe, it's modifying the hooks and parameters while multiple
- @c threads are active that is regarded as unsafe. An arena's next field
- @c is initialized and never changed again, except for main_arena's,
- @c that's protected by list_lock; next_free is only modified while
- @c list_lock is held too. All other data members of an arena, as well
- @c as the metadata of the memory areas assigned to it, are only modified
- @c while holding the arena's mutex (fastbin pointers use catomic ops
- @c because they may be modified by free without taking the arena's
- @c lock). Some reassurance was needed for fastbins, for it wasn't clear
- @c how they were initialized. It turns out they are always
- @c zero-initialized: main_arena's, for being static data, and other
- @c arena's, for being just-mmapped memory.
- @c Leaking file descriptors and memory in case of cancellation is
- @c unavoidable without disabling cancellation, but the lock situation is
- @c a bit more complicated: we don't have fallback arenas for malloc to
- @c be safe to call from within signal handlers. Error-checking mutexes
- @c or trylock could enable us to try and use alternate arenas, even with
- @c -DPER_THREAD (enabled by default), but supporting interruption
- @c (cancellation or signal handling) while holding the arena list mutex
- @c would require more work; maybe blocking signals and disabling async
- @c cancellation while manipulating the arena lists?
- @c __libc_malloc @asulock @aculock @acsfd @acsmem
- @c force_reg ok
- @c *malloc_hook unguarded
- @c arena_lock @asulock @aculock @acsfd @acsmem
- @c mutex_lock @asulock @aculock
- @c arena_get2 @asulock @aculock @acsfd @acsmem
- @c get_free_list @asulock @aculock
- @c mutex_lock (list_lock) dup @asulock @aculock
- @c mutex_unlock (list_lock) dup @aculock
- @c mutex_lock (arena lock) dup @asulock @aculock [returns locked]
- @c __get_nprocs ext ok @acsfd
- @c NARENAS_FROM_NCORES ok
- @c catomic_compare_and_exchange_bool_acq ok
- @c _int_new_arena ok @asulock @aculock @acsmem
- @c new_heap ok @acsmem
- @c mmap ok @acsmem
- @c munmap ok @acsmem
- @c mprotect ok
- @c chunk2mem ok
- @c set_head ok
- @c tsd_setspecific dup ok
- @c mutex_init ok
- @c mutex_lock (just-created mutex) ok, returns locked
- @c mutex_lock (list_lock) dup @asulock @aculock
- @c atomic_write_barrier ok
- @c mutex_unlock (list_lock) @aculock
- @c catomic_decrement ok
- @c reused_arena @asulock @aculock
- @c reads&writes next_to_use and iterates over arena next without guards
- @c those are harmless as long as we don't drop arenas from the
- @c NEXT list, and we never do; when a thread terminates,
- @c __malloc_arena_thread_freeres prepends the arena to the free_list
- @c NEXT_FREE list, but NEXT is never modified, so it's safe!
- @c mutex_trylock (arena lock) @asulock @aculock
- @c mutex_lock (arena lock) dup @asulock @aculock
- @c tsd_setspecific dup ok
- @c _int_malloc @acsfd @acsmem
- @c checked_request2size ok
- @c REQUEST_OUT_OF_RANGE ok
- @c request2size ok
- @c get_max_fast ok
- @c fastbin_index ok
- @c fastbin ok
- @c catomic_compare_and_exhange_val_acq ok
- @c malloc_printerr dup @mtsenv
- @c if we get to it, we're toast already, undefined behavior must have
- @c been invoked before
- @c libc_message @mtsenv [no leaks with cancellation disabled]
- @c FATAL_PREPARE ok
- @c pthread_setcancelstate disable ok
- @c libc_secure_getenv @mtsenv
- @c getenv @mtsenv
- @c open_not_cancel_2 dup @acsfd
- @c strchrnul ok
- @c WRITEV_FOR_FATAL ok
- @c writev ok
- @c mmap ok @acsmem
- @c munmap ok @acsmem
- @c BEFORE_ABORT @acsfd
- @c backtrace ok
- @c write_not_cancel dup ok
- @c backtrace_symbols_fd @aculock
- @c open_not_cancel_2 dup @acsfd
- @c read_not_cancel dup ok
- @c close_not_cancel_no_status dup @acsfd
- @c abort ok
- @c itoa_word ok
- @c abort ok
- @c check_remalloced_chunk ok/disabled
- @c chunk2mem dup ok
- @c alloc_perturb ok
- @c in_smallbin_range ok
- @c smallbin_index ok
- @c bin_at ok
- @c last ok
- @c malloc_consolidate ok
- @c get_max_fast dup ok
- @c clear_fastchunks ok
- @c unsorted_chunks dup ok
- @c fastbin dup ok
- @c atomic_exchange_acq ok
- @c check_inuse_chunk dup ok/disabled
- @c chunk_at_offset dup ok
- @c chunksize dup ok
- @c inuse_bit_at_offset dup ok
- @c unlink dup ok
- @c clear_inuse_bit_at_offset dup ok
- @c in_smallbin_range dup ok
- @c set_head dup ok
- @c malloc_init_state ok
- @c bin_at dup ok
- @c set_noncontiguous dup ok
- @c set_max_fast dup ok
- @c initial_top ok
- @c unsorted_chunks dup ok
- @c check_malloc_state ok/disabled
- @c set_inuse_bit_at_offset ok
- @c check_malloced_chunk ok/disabled
- @c largebin_index ok
- @c have_fastchunks ok
- @c unsorted_chunks ok
- @c bin_at ok
- @c chunksize ok
- @c chunk_at_offset ok
- @c set_head ok
- @c set_foot ok
- @c mark_bin ok
- @c idx2bit ok
- @c first ok
- @c unlink ok
- @c malloc_printerr dup ok
- @c in_smallbin_range dup ok
- @c idx2block ok
- @c idx2bit dup ok
- @c next_bin ok
- @c sysmalloc @acsfd @acsmem
- @c MMAP @acsmem
- @c set_head dup ok
- @c check_chunk ok/disabled
- @c chunk2mem dup ok
- @c chunksize dup ok
- @c chunk_at_offset dup ok
- @c heap_for_ptr ok
- @c grow_heap ok
- @c mprotect ok
- @c set_head dup ok
- @c new_heap @acsmem
- @c MMAP dup @acsmem
- @c munmap @acsmem
- @c top ok
- @c set_foot dup ok
- @c contiguous ok
- @c MORECORE ok
- @c *__morecore ok unguarded
- @c __default_morecore
- @c sbrk ok
- @c force_reg dup ok
- @c *__after_morecore_hook unguarded
- @c set_noncontiguous ok
- @c malloc_printerr dup ok
- @c _int_free (have_lock) @acsfd @acsmem [@asulock @aculock]
- @c chunksize dup ok
- @c mutex_unlock dup @aculock/!have_lock
- @c malloc_printerr dup ok
- @c check_inuse_chunk ok/disabled
- @c chunk_at_offset dup ok
- @c mutex_lock dup @asulock @aculock/@have_lock
- @c chunk2mem dup ok
- @c free_perturb ok
- @c set_fastchunks ok
- @c catomic_and ok
- @c fastbin_index dup ok
- @c fastbin dup ok
- @c catomic_compare_and_exchange_val_rel ok
- @c chunk_is_mmapped ok
- @c contiguous dup ok
- @c prev_inuse ok
- @c unlink dup ok
- @c inuse_bit_at_offset dup ok
- @c clear_inuse_bit_at_offset ok
- @c unsorted_chunks dup ok
- @c in_smallbin_range dup ok
- @c set_head dup ok
- @c set_foot dup ok
- @c check_free_chunk ok/disabled
- @c check_chunk dup ok/disabled
- @c have_fastchunks dup ok
- @c malloc_consolidate dup ok
- @c systrim ok
- @c MORECORE dup ok
- @c *__after_morecore_hook dup unguarded
- @c set_head dup ok
- @c check_malloc_state ok/disabled
- @c top dup ok
- @c heap_for_ptr dup ok
- @c heap_trim @acsfd @acsmem
- @c top dup ok
- @c chunk_at_offset dup ok
- @c prev_chunk ok
- @c chunksize dup ok
- @c prev_inuse dup ok
- @c delete_heap @acsmem
- @c munmap dup @acsmem
- @c unlink dup ok
- @c set_head dup ok
- @c shrink_heap @acsfd
- @c check_may_shrink_heap @acsfd
- @c open_not_cancel_2 @acsfd
- @c read_not_cancel ok
- @c close_not_cancel_no_status @acsfd
- @c MMAP dup ok
- @c madvise ok
- @c munmap_chunk @acsmem
- @c chunksize dup ok
- @c chunk_is_mmapped dup ok
- @c chunk2mem dup ok
- @c malloc_printerr dup ok
- @c munmap dup @acsmem
- @c check_malloc_state ok/disabled
- @c arena_get_retry @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- @c mutex_lock dup @asulock @aculock
- @c arena_get2 dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock @aculock
- @c mem2chunk ok
- @c chunk_is_mmapped ok
- @c arena_for_chunk ok
- @c chunk_non_main_arena ok
- @c heap_for_ptr ok
- This function returns a pointer to a newly allocated block @var{size}
- bytes long, or a null pointer if the block could not be allocated.
- @end deftypefun
- The contents of the block are undefined; you must initialize it yourself
- (or use @code{calloc} instead; @pxref{Allocating Cleared Space}).
- Normally you would cast the value as a pointer to the kind of object
- that you want to store in the block. Here we show an example of doing
- so, and of initializing the space with zeros using the library function
- @code{memset} (@pxref{Copying Strings and Arrays}):
- @smallexample
- struct foo *ptr;
- @dots{}
- ptr = (struct foo *) malloc (sizeof (struct foo));
- if (ptr == 0) abort ();
- memset (ptr, 0, sizeof (struct foo));
- @end smallexample
- You can store the result of @code{malloc} into any pointer variable
- without a cast, because @w{ISO C} automatically converts the type
- @code{void *} to another type of pointer when necessary. But the cast
- is necessary in contexts other than assignment operators or if you might
- want your code to run in traditional C.
- Remember that when allocating space for a string, the argument to
- @code{malloc} must be one plus the length of the string. This is
- because a string is terminated with a null character that doesn't count
- in the ``length'' of the string but does need space. For example:
- @smallexample
- char *ptr;
- @dots{}
- ptr = (char *) malloc (length + 1);
- @end smallexample
- @noindent
- @xref{Representation of Strings}, for more information about this.
- @node Malloc Examples
- @subsubsection Examples of @code{malloc}
- If no more space is available, @code{malloc} returns a null pointer.
- You should check the value of @emph{every} call to @code{malloc}. It is
- useful to write a subroutine that calls @code{malloc} and reports an
- error if the value is a null pointer, returning only if the value is
- nonzero. This function is conventionally called @code{xmalloc}. Here
- it is:
- @smallexample
- void *
- xmalloc (size_t size)
- @{
- void *value = malloc (size);
- if (value == 0)
- fatal ("virtual memory exhausted");
- return value;
- @}
- @end smallexample
- Here is a real example of using @code{malloc} (by way of @code{xmalloc}).
- The function @code{savestring} will copy a sequence of characters into
- a newly allocated null-terminated string:
- @smallexample
- @group
- char *
- savestring (const char *ptr, size_t len)
- @{
- char *value = (char *) xmalloc (len + 1);
- value[len] = '\0';
- return (char *) memcpy (value, ptr, len);
- @}
- @end group
- @end smallexample
- The block that @code{malloc} gives you is guaranteed to be aligned so
- that it can hold any type of data. On @gnusystems{}, the address is
- always a multiple of eight on 32-bit systems, and a multiple of 16 on
- 64-bit systems. Only rarely is any higher boundary (such as a page
- boundary) necessary; for those cases, use @code{aligned_alloc} or
- @code{posix_memalign} (@pxref{Aligned Memory Blocks}).
- Note that the memory located after the end of the block is likely to be
- in use for something else; perhaps a block already allocated by another
- call to @code{malloc}. If you attempt to treat the block as longer than
- you asked for it to be, you are liable to destroy the data that
- @code{malloc} uses to keep track of its blocks, or you may destroy the
- contents of another block. If you have already allocated a block and
- discover you want it to be bigger, use @code{realloc} (@pxref{Changing
- Block Size}).
- @node Freeing after Malloc
- @subsubsection Freeing Memory Allocated with @code{malloc}
- @cindex freeing memory allocated with @code{malloc}
- @cindex heap, freeing memory from
- When you no longer need a block that you got with @code{malloc}, use the
- function @code{free} to make the block available to be allocated again.
- The prototype for this function is in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun void free (void *@var{ptr})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c __libc_free @asulock @aculock @acsfd @acsmem
- @c releasing memory into fastbins modifies the arena without taking
- @c its mutex, but catomic operations ensure safety. If two (or more)
- @c threads are running malloc and have their own arenas locked when
- @c each gets a signal whose handler free()s large (non-fastbin-able)
- @c blocks from each other's arena, we deadlock; this is a more general
- @c case of @asulock.
- @c *__free_hook unguarded
- @c mem2chunk ok
- @c chunk_is_mmapped ok, chunk bits not modified after allocation
- @c chunksize ok
- @c munmap_chunk dup @acsmem
- @c arena_for_chunk dup ok
- @c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
- The @code{free} function deallocates the block of memory pointed at
- by @var{ptr}.
- @end deftypefun
- Freeing a block alters the contents of the block. @strong{Do not expect to
- find any data (such as a pointer to the next block in a chain of blocks) in
- the block after freeing it.} Copy whatever you need out of the block before
- freeing it! Here is an example of the proper way to free all the blocks in
- a chain, and the strings that they point to:
- @smallexample
- struct chain
- @{
- struct chain *next;
- char *name;
- @}
- void
- free_chain (struct chain *chain)
- @{
- while (chain != 0)
- @{
- struct chain *next = chain->next;
- free (chain->name);
- free (chain);
- chain = next;
- @}
- @}
- @end smallexample
- Occasionally, @code{free} can actually return memory to the operating
- system and make the process smaller. Usually, all it can do is allow a
- later call to @code{malloc} to reuse the space. In the meantime, the
- space remains in your program as part of a free-list used internally by
- @code{malloc}.
- There is no point in freeing blocks at the end of a program, because all
- of the program's space is given back to the system when the process
- terminates.
- @node Changing Block Size
- @subsubsection Changing the Size of a Block
- @cindex changing the size of a block (@code{malloc})
- Often you do not know for certain how big a block you will ultimately need
- at the time you must begin to use the block. For example, the block might
- be a buffer that you use to hold a line being read from a file; no matter
- how long you make the buffer initially, you may encounter a line that is
- longer.
- You can make the block longer by calling @code{realloc} or
- @code{reallocarray}. These functions are declared in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c It may call the implementations of malloc and free, so all of their
- @c issues arise, plus the realloc hook, also accessed without guards.
- @c __libc_realloc @asulock @aculock @acsfd @acsmem
- @c *__realloc_hook unguarded
- @c __libc_free dup @asulock @aculock @acsfd @acsmem
- @c __libc_malloc dup @asulock @aculock @acsfd @acsmem
- @c mem2chunk dup ok
- @c chunksize dup ok
- @c malloc_printerr dup ok
- @c checked_request2size dup ok
- @c chunk_is_mmapped dup ok
- @c mremap_chunk
- @c chunksize dup ok
- @c __mremap ok
- @c set_head dup ok
- @c MALLOC_COPY ok
- @c memcpy ok
- @c munmap_chunk dup @acsmem
- @c arena_for_chunk dup ok
- @c mutex_lock (arena mutex) dup @asulock @aculock
- @c _int_realloc @acsfd @acsmem
- @c malloc_printerr dup ok
- @c check_inuse_chunk dup ok/disabled
- @c chunk_at_offset dup ok
- @c chunksize dup ok
- @c set_head_size dup ok
- @c chunk_at_offset dup ok
- @c set_head dup ok
- @c chunk2mem dup ok
- @c inuse dup ok
- @c unlink dup ok
- @c _int_malloc dup @acsfd @acsmem
- @c mem2chunk dup ok
- @c MALLOC_COPY dup ok
- @c _int_free (have_lock) dup @acsfd @acsmem
- @c set_inuse_bit_at_offset dup ok
- @c set_head dup ok
- @c mutex_unlock (arena mutex) dup @aculock
- @c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
- The @code{realloc} function changes the size of the block whose address is
- @var{ptr} to be @var{newsize}.
- Since the space after the end of the block may be in use, @code{realloc}
- may find it necessary to copy the block to a new address where more free
- space is available. The value of @code{realloc} is the new address of the
- block. If the block needs to be moved, @code{realloc} copies the old
- contents.
- If you pass a null pointer for @var{ptr}, @code{realloc} behaves just
- like @samp{malloc (@var{newsize})}. This can be convenient, but beware
- that older implementations (before @w{ISO C}) may not support this
- behavior, and will probably crash when @code{realloc} is passed a null
- pointer.
- @end deftypefun
- @deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
- @standards{BSD, malloc.h}
- @standards{BSD, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- The @code{reallocarray} function changes the size of the block whose address
- is @var{ptr} to be long enough to contain a vector of @var{nmemb} elements,
- each of size @var{size}. It is equivalent to @samp{realloc (@var{ptr},
- @var{nmemb} * @var{size})}, except that @code{reallocarray} fails safely if
- the multiplication overflows, by setting @code{errno} to @code{ENOMEM},
- returning a null pointer, and leaving the original block unchanged.
- @code{reallocarray} should be used instead of @code{realloc} when the new size
- of the allocated block is the result of a multiplication that might overflow.
- @strong{Portability Note:} This function is not part of any standard. It was
- first introduced in OpenBSD 5.6.
- @end deftypefun
- Like @code{malloc}, @code{realloc} and @code{reallocarray} may return a null
- pointer if no memory space is available to make the block bigger. When this
- happens, the original block is untouched; it has not been modified or
- relocated.
- In most cases it makes no difference what happens to the original block
- when @code{realloc} fails, because the application program cannot continue
- when it is out of memory, and the only thing to do is to give a fatal error
- message. Often it is convenient to write and use a subroutine,
- conventionally called @code{xrealloc}, that takes care of the error message
- as @code{xmalloc} does for @code{malloc}:
- @smallexample
- void *
- xrealloc (void *ptr, size_t size)
- @{
- void *value = realloc (ptr, size);
- if (value == 0)
- fatal ("Virtual memory exhausted");
- return value;
- @}
- @end smallexample
- You can also use @code{realloc} or @code{reallocarray} to make a block
- smaller. The reason you would do this is to avoid tying up a lot of memory
- space when only a little is needed.
- @comment The following is no longer true with the new malloc.
- @comment But it seems wise to keep the warning for other implementations.
- In several allocation implementations, making a block smaller sometimes
- necessitates copying it, so it can fail if no other space is available.
- If the new size you specify is the same as the old size, @code{realloc} and
- @code{reallocarray} are guaranteed to change nothing and return the same
- address that you gave.
- @node Allocating Cleared Space
- @subsubsection Allocating Cleared Space
- The function @code{calloc} allocates memory and clears it to zero. It
- is declared in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Same caveats as malloc.
- @c __libc_calloc @asulock @aculock @acsfd @acsmem
- @c *__malloc_hook dup unguarded
- @c memset dup ok
- @c arena_get @asulock @aculock @acsfd @acsmem
- @c arena_lock dup @asulock @aculock @acsfd @acsmem
- @c top dup ok
- @c chunksize dup ok
- @c heap_for_ptr dup ok
- @c _int_malloc dup @acsfd @acsmem
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- @c mem2chunk dup ok
- @c chunk_is_mmapped dup ok
- @c MALLOC_ZERO ok
- @c memset dup ok
- This function allocates a block long enough to contain a vector of
- @var{count} elements, each of size @var{eltsize}. Its contents are
- cleared to zero before @code{calloc} returns.
- @end deftypefun
- You could define @code{calloc} as follows:
- @smallexample
- void *
- calloc (size_t count, size_t eltsize)
- @{
- size_t size = count * eltsize;
- void *value = malloc (size);
- if (value != 0)
- memset (value, 0, size);
- return value;
- @}
- @end smallexample
- But in general, it is not guaranteed that @code{calloc} calls
- @code{malloc} internally. Therefore, if an application provides its own
- @code{malloc}/@code{realloc}/@code{free} outside the C library, it
- should always define @code{calloc}, too.
- @node Aligned Memory Blocks
- @subsubsection Allocating Aligned Memory Blocks
- @cindex page boundary
- @cindex alignment (with @code{malloc})
- @pindex stdlib.h
- The address of a block returned by @code{malloc} or @code{realloc} in
- @gnusystems{} is always a multiple of eight (or sixteen on 64-bit
- systems). If you need a block whose address is a multiple of a higher
- power of two than that, use @code{aligned_alloc} or @code{posix_memalign}.
- @code{aligned_alloc} and @code{posix_memalign} are declared in
- @file{stdlib.h}.
- @deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size})
- @standards{???, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Alias to memalign.
- The @code{aligned_alloc} function allocates a block of @var{size} bytes whose
- address is a multiple of @var{alignment}. The @var{alignment} must be a
- power of two and @var{size} must be a multiple of @var{alignment}.
- The @code{aligned_alloc} function returns a null pointer on error and sets
- @code{errno} to one of the following values:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{alignment} is not a power of two.
- This function was introduced in @w{ISO C11} and hence may have better
- portability to modern non-POSIX systems than @code{posix_memalign}.
- @end table
- @end deftypefun
- @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
- @standards{BSD, malloc.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Same issues as malloc. The padding bytes are safely freed in
- @c _int_memalign, with the arena still locked.
- @c __libc_memalign @asulock @aculock @acsfd @acsmem
- @c *__memalign_hook dup unguarded
- @c __libc_malloc dup @asulock @aculock @acsfd @acsmem
- @c arena_get dup @asulock @aculock @acsfd @acsmem
- @c _int_memalign @acsfd @acsmem
- @c _int_malloc dup @acsfd @acsmem
- @c checked_request2size dup ok
- @c mem2chunk dup ok
- @c chunksize dup ok
- @c chunk_is_mmapped dup ok
- @c set_head dup ok
- @c chunk2mem dup ok
- @c set_inuse_bit_at_offset dup ok
- @c set_head_size dup ok
- @c _int_free (have_lock) dup @acsfd @acsmem
- @c chunk_at_offset dup ok
- @c check_inuse_chunk dup ok
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- The @code{memalign} function allocates a block of @var{size} bytes whose
- address is a multiple of @var{boundary}. The @var{boundary} must be a
- power of two! The function @code{memalign} works by allocating a
- somewhat larger block, and then returning an address within the block
- that is on the specified boundary.
- The @code{memalign} function returns a null pointer on error and sets
- @code{errno} to one of the following values:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{boundary} is not a power of two.
- @end table
- The @code{memalign} function is obsolete and @code{aligned_alloc} or
- @code{posix_memalign} should be used instead.
- @end deftypefun
- @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
- @standards{POSIX, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Calls memalign unless the requirements are not met (powerof2 macro is
- @c safe given an automatic variable as an argument) or there's a
- @c memalign hook (accessed unguarded, but safely).
- The @code{posix_memalign} function is similar to the @code{memalign}
- function in that it returns a buffer of @var{size} bytes aligned to a
- multiple of @var{alignment}. But it adds one requirement to the
- parameter @var{alignment}: the value must be a power of two multiple of
- @code{sizeof (void *)}.
- If the function succeeds in allocation memory a pointer to the allocated
- memory is returned in @code{*@var{memptr}} and the return value is zero.
- Otherwise the function returns an error value indicating the problem.
- The possible error values returned are:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{alignment} is not a power of two multiple of @code{sizeof (void *)}.
- @end table
- This function was introduced in POSIX 1003.1d. Although this function is
- superseded by @code{aligned_alloc}, it is more portable to older POSIX
- systems that do not support @w{ISO C11}.
- @end deftypefun
- @deftypefun {void *} valloc (size_t @var{size})
- @standards{BSD, malloc.h}
- @standards{BSD, stdlib.h}
- @safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
- @c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
- @c ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
- @c _dl_addr @asucorrupt? @aculock
- @c __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt? @aculock
- @c _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
- @c the ok above assumes no partial updates on dl_ns and _ns_loaded
- @c that could confuse a _dl_addr call in a signal handler
- @c _dl_addr_inside_object ok
- @c determine_info ok
- @c __rtld_lock_unlock_recursive (dl_load_lock) @aculock
- @c *_environ @mtsenv
- @c next_env_entry ok
- @c strcspn dup ok
- @c __libc_mallopt dup @mtasuconst:mallopt [setting mp_]
- @c __malloc_check_init @mtasuconst:malloc_hooks [setting hooks]
- @c *__malloc_initialize_hook unguarded, ok
- @c *__memalign_hook dup ok, unguarded
- @c arena_get dup @asulock @aculock @acsfd @acsmem
- @c _int_valloc @acsfd @acsmem
- @c malloc_consolidate dup ok
- @c _int_memalign dup @acsfd @acsmem
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c _int_memalign dup @acsfd @acsmem
- @c mutex_unlock dup @aculock
- Using @code{valloc} is like using @code{memalign} and passing the page size
- as the value of the first argument. It is implemented like this:
- @smallexample
- void *
- valloc (size_t size)
- @{
- return memalign (getpagesize (), size);
- @}
- @end smallexample
- @ref{Query Memory Parameters} for more information about the memory
- subsystem.
- The @code{valloc} function is obsolete and @code{aligned_alloc} or
- @code{posix_memalign} should be used instead.
- @end deftypefun
- @node Malloc Tunable Parameters
- @subsubsection Malloc Tunable Parameters
- You can adjust some parameters for dynamic memory allocation with the
- @code{mallopt} function. This function is the general SVID/XPG
- interface, defined in @file{malloc.h}.
- @pindex malloc.h
- @deftypefun int mallopt (int @var{param}, int @var{value})
- @safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
- @c __libc_mallopt @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
- @c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
- @c mutex_lock (main_arena->mutex) @asulock @aculock
- @c malloc_consolidate dup ok
- @c set_max_fast ok
- @c mutex_unlock dup @aculock
- When calling @code{mallopt}, the @var{param} argument specifies the
- parameter to be set, and @var{value} the new value to be set. Possible
- choices for @var{param}, as defined in @file{malloc.h}, are:
- @vtable @code
- @item M_MMAP_MAX
- The maximum number of chunks to allocate with @code{mmap}. Setting this
- to zero disables all use of @code{mmap}.
- The default value of this parameter is @code{65536}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_MMAP_MAX_} to the desired value.
- @item M_MMAP_THRESHOLD
- All chunks larger than this value are allocated outside the normal
- heap, using the @code{mmap} system call. This way it is guaranteed
- that the memory for these chunks can be returned to the system on
- @code{free}. Note that requests smaller than this threshold might still
- be allocated via @code{mmap}.
- If this parameter is not set, the default value is set as 128 KiB and the
- threshold is adjusted dynamically to suit the allocation patterns of the
- program. If the parameter is set, the dynamic adjustment is disabled and the
- value is set statically to the input value.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_MMAP_THRESHOLD_} to the desired value.
- @comment TODO: @item M_MXFAST
- @item M_PERTURB
- If non-zero, memory blocks are filled with values depending on some
- low order bits of this parameter when they are allocated (except when
- allocated by @code{calloc}) and freed. This can be used to debug the
- use of uninitialized or freed heap memory. Note that this option does not
- guarantee that the freed block will have any specific values. It only
- guarantees that the content the block had before it was freed will be
- overwritten.
- The default value of this parameter is @code{0}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_MMAP_PERTURB_} to the desired value.
- @item M_TOP_PAD
- This parameter determines the amount of extra memory to obtain from the system
- when an arena needs to be extended. It also specifies the number of bytes to
- retain when shrinking an arena. This provides the necessary hysteresis in heap
- size such that excessive amounts of system calls can be avoided.
- The default value of this parameter is @code{0}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_TOP_PAD_} to the desired value.
- @item M_TRIM_THRESHOLD
- This is the minimum size (in bytes) of the top-most, releasable chunk
- that will trigger a system call in order to return memory to the system.
- If this parameter is not set, the default value is set as 128 KiB and the
- threshold is adjusted dynamically to suit the allocation patterns of the
- program. If the parameter is set, the dynamic adjustment is disabled and the
- value is set statically to the provided input.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_TRIM_THRESHOLD_} to the desired value.
- @item M_ARENA_TEST
- This parameter specifies the number of arenas that can be created before the
- test on the limit to the number of arenas is conducted. The value is ignored if
- @code{M_ARENA_MAX} is set.
- The default value of this parameter is 2 on 32-bit systems and 8 on 64-bit
- systems.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_ARENA_TEST} to the desired value.
- @item M_ARENA_MAX
- This parameter sets the number of arenas to use regardless of the number of
- cores in the system.
- The default value of this tunable is @code{0}, meaning that the limit on the
- number of arenas is determined by the number of CPU cores online. For 32-bit
- systems the limit is twice the number of cores online and on 64-bit systems, it
- is eight times the number of cores online. Note that the default value is not
- derived from the default value of M_ARENA_TEST and is computed independently.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_ARENA_MAX} to the desired value.
- @end vtable
- @end deftypefun
- @node Heap Consistency Checking
- @subsubsection Heap Consistency Checking
- @cindex heap consistency checking
- @cindex consistency checking, of heap
- You can ask @code{malloc} to check the consistency of dynamic memory by
- using the @code{mcheck} function. This function is a GNU extension,
- declared in @file{mcheck.h}.
- @pindex mcheck.h
- @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
- @c The hooks must be set up before malloc is first used, which sort of
- @c implies @mtuinit/@asuinit but since the function is a no-op if malloc
- @c was already used, that doesn't pose any safety issues. The actual
- @c problem is with the hooks, designed for single-threaded
- @c fully-synchronous operation: they manage an unguarded linked list of
- @c allocated blocks, and get temporarily overwritten before calling the
- @c allocation functions recursively while holding the old hooks. There
- @c are no guards for thread safety, and inconsistent hooks may be found
- @c within signal handlers or left behind in case of cancellation.
- Calling @code{mcheck} tells @code{malloc} to perform occasional
- consistency checks. These will catch things such as writing
- past the end of a block that was allocated with @code{malloc}.
- The @var{abortfn} argument is the function to call when an inconsistency
- is found. If you supply a null pointer, then @code{mcheck} uses a
- default function which prints a message and calls @code{abort}
- (@pxref{Aborting a Program}). The function you supply is called with
- one argument, which says what sort of inconsistency was detected; its
- type is described below.
- It is too late to begin allocation checking once you have allocated
- anything with @code{malloc}. So @code{mcheck} does nothing in that
- case. The function returns @code{-1} if you call it too late, and
- @code{0} otherwise (when it is successful).
- The easiest way to arrange to call @code{mcheck} early enough is to use
- the option @samp{-lmcheck} when you link your program; then you don't
- need to modify your program source at all. Alternatively you might use
- a debugger to insert a call to @code{mcheck} whenever the program is
- started, for example these gdb commands will automatically call @code{mcheck}
- whenever the program starts:
- @smallexample
- (gdb) break main
- Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10
- (gdb) command 1
- Type commands for when breakpoint 1 is hit, one per line.
- End with a line saying just "end".
- >call mcheck(0)
- >continue
- >end
- (gdb) @dots{}
- @end smallexample
- This will however only work if no initialization function of any object
- involved calls any of the @code{malloc} functions since @code{mcheck}
- must be called before the first such function.
- @end deftypefun
- @deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
- @safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
- @c The linked list of headers may be modified concurrently by other
- @c threads, and it may find a partial update if called from a signal
- @c handler. It's mostly read only, so cancelling it might be safe, but
- @c it will modify global state that, if cancellation hits at just the
- @c right spot, may be left behind inconsistent. This path is only taken
- @c if checkhdr finds an inconsistency. If the inconsistency could only
- @c occur because of earlier undefined behavior, that wouldn't be an
- @c additional safety issue problem, but because of the other concurrency
- @c issues in the mcheck hooks, the apparent inconsistency could be the
- @c result of mcheck's own internal data race. So, AC-Unsafe it is.
- The @code{mprobe} function lets you explicitly check for inconsistencies
- in a particular allocated block. You must have already called
- @code{mcheck} at the beginning of the program, to do its occasional
- checks; calling @code{mprobe} requests an additional consistency check
- to be done at the time of the call.
- The argument @var{pointer} must be a pointer returned by @code{malloc}
- or @code{realloc}. @code{mprobe} returns a value that says what
- inconsistency, if any, was found. The values are described below.
- @end deftypefun
- @deftp {Data Type} {enum mcheck_status}
- This enumerated type describes what kind of inconsistency was detected
- in an allocated block, if any. Here are the possible values:
- @table @code
- @item MCHECK_DISABLED
- @code{mcheck} was not called before the first allocation.
- No consistency checking can be done.
- @item MCHECK_OK
- No inconsistency detected.
- @item MCHECK_HEAD
- The data immediately before the block was modified.
- This commonly happens when an array index or pointer
- is decremented too far.
- @item MCHECK_TAIL
- The data immediately after the block was modified.
- This commonly happens when an array index or pointer
- is incremented too far.
- @item MCHECK_FREE
- The block was already freed.
- @end table
- @end deftp
- Another possibility to check for and guard against bugs in the use of
- @code{malloc}, @code{realloc} and @code{free} is to set the environment
- variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set to a
- non-zero value, a special (less efficient) implementation is used which
- is designed to be tolerant against simple errors, such as double calls
- of @code{free} with the same argument, or overruns of a single byte
- (off-by-one bugs). Not all such errors can be protected against,
- however, and memory leaks can result.
- Any detected heap corruption results in immediate termination of the
- process.
- There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
- it could possibly be exploited since diverging from the normal programs
- behavior it now writes something to the standard error descriptor.
- Therefore the use of @code{MALLOC_CHECK_} is disabled by default for
- SUID and SGID binaries. It can be enabled again by the system
- administrator by adding a file @file{/etc/suid-debug} (the content is
- not important it could be empty).
- So, what's the difference between using @code{MALLOC_CHECK_} and linking
- with @samp{-lmcheck}? @code{MALLOC_CHECK_} is orthogonal with respect to
- @samp{-lmcheck}. @samp{-lmcheck} has been added for backward
- compatibility. Both @code{MALLOC_CHECK_} and @samp{-lmcheck} should
- uncover the same bugs - but using @code{MALLOC_CHECK_} you don't need to
- recompile your application.
- @node Hooks for Malloc
- @subsubsection Memory Allocation Hooks
- @cindex allocation hooks, for @code{malloc}
- @Theglibc{} lets you modify the behavior of @code{malloc},
- @code{realloc}, and @code{free} by specifying appropriate hook
- functions. You can use these hooks to help you debug programs that use
- dynamic memory allocation, for example.
- The hook variables are declared in @file{malloc.h}.
- @pindex malloc.h
- @defvar __malloc_hook
- @standards{GNU, malloc.h}
- The value of this variable is a pointer to the function that
- @code{malloc} uses whenever it is called. You should define this
- function to look like @code{malloc}; that is, like:
- @smallexample
- void *@var{function} (size_t @var{size}, const void *@var{caller})
- @end smallexample
- The value of @var{caller} is the return address found on the stack when
- the @code{malloc} function was called. This value allows you to trace
- the memory consumption of the program.
- @end defvar
- @defvar __realloc_hook
- @standards{GNU, malloc.h}
- The value of this variable is a pointer to function that @code{realloc}
- uses whenever it is called. You should define this function to look
- like @code{realloc}; that is, like:
- @smallexample
- void *@var{function} (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
- @end smallexample
- The value of @var{caller} is the return address found on the stack when
- the @code{realloc} function was called. This value allows you to trace the
- memory consumption of the program.
- @end defvar
- @defvar __free_hook
- @standards{GNU, malloc.h}
- The value of this variable is a pointer to function that @code{free}
- uses whenever it is called. You should define this function to look
- like @code{free}; that is, like:
- @smallexample
- void @var{function} (void *@var{ptr}, const void *@var{caller})
- @end smallexample
- The value of @var{caller} is the return address found on the stack when
- the @code{free} function was called. This value allows you to trace the
- memory consumption of the program.
- @end defvar
- @defvar __memalign_hook
- @standards{GNU, malloc.h}
- The value of this variable is a pointer to function that @code{aligned_alloc},
- @code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they
- are called. You should define this function to look like @code{aligned_alloc};
- that is, like:
- @smallexample
- void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller})
- @end smallexample
- The value of @var{caller} is the return address found on the stack when
- the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or
- @code{valloc} functions are called. This value allows you to trace the
- memory consumption of the program.
- @end defvar
- You must make sure that the function you install as a hook for one of
- these functions does not call that function recursively without restoring
- the old value of the hook first! Otherwise, your program will get stuck
- in an infinite recursion. Before calling the function recursively, one
- should make sure to restore all the hooks to their previous value. When
- coming back from the recursive call, all the hooks should be resaved
- since a hook might modify itself.
- An issue to look out for is the time at which the malloc hook functions
- can be safely installed. If the hook functions call the malloc-related
- functions recursively, it is necessary that malloc has already properly
- initialized itself at the time when @code{__malloc_hook} etc. is
- assigned to. On the other hand, if the hook functions provide a
- complete malloc implementation of their own, it is vital that the hooks
- are assigned to @emph{before} the very first @code{malloc} call has
- completed, because otherwise a chunk obtained from the ordinary,
- un-hooked malloc may later be handed to @code{__free_hook}, for example.
- Here is an example showing how to use @code{__malloc_hook} and
- @code{__free_hook} properly. It installs a function that prints out
- information every time @code{malloc} or @code{free} is called. We just
- assume here that @code{realloc} and @code{memalign} are not used in our
- program.
- @smallexample
- /* Prototypes for __malloc_hook, __free_hook */
- #include <malloc.h>
- /* Prototypes for our hooks. */
- static void my_init_hook (void);
- static void *my_malloc_hook (size_t, const void *);
- static void my_free_hook (void*, const void *);
- static void
- my_init (void)
- @{
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
- @}
- static void *
- my_malloc_hook (size_t size, const void *caller)
- @{
- void *result;
- /* Restore all old hooks */
- __malloc_hook = old_malloc_hook;
- __free_hook = old_free_hook;
- /* Call recursively */
- result = malloc (size);
- /* Save underlying hooks */
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- /* @r{@code{printf} might call @code{malloc}, so protect it too.} */
- printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
- /* Restore our own hooks */
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
- return result;
- @}
- static void
- my_free_hook (void *ptr, const void *caller)
- @{
- /* Restore all old hooks */
- __malloc_hook = old_malloc_hook;
- __free_hook = old_free_hook;
- /* Call recursively */
- free (ptr);
- /* Save underlying hooks */
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- /* @r{@code{printf} might call @code{free}, so protect it too.} */
- printf ("freed pointer %p\n", ptr);
- /* Restore our own hooks */
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
- @}
- main ()
- @{
- my_init ();
- @dots{}
- @}
- @end smallexample
- The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by
- installing such hooks.
- @c __morecore, __after_morecore_hook are undocumented
- @c It's not clear whether to document them.
- @node Statistics of Malloc
- @subsubsection Statistics for Memory Allocation with @code{malloc}
- @cindex allocation statistics
- You can get information about dynamic memory allocation by calling the
- @code{mallinfo} function. This function and its associated data type
- are declared in @file{malloc.h}; they are an extension of the standard
- SVID/XPG version.
- @pindex malloc.h
- @deftp {Data Type} {struct mallinfo}
- @standards{GNU, malloc.h}
- This structure type is used to return information about the dynamic
- memory allocator. It contains the following members:
- @table @code
- @item int arena
- This is the total size of memory allocated with @code{sbrk} by
- @code{malloc}, in bytes.
- @item int ordblks
- This is the number of chunks not in use. (The memory allocator
- internally gets chunks of memory from the operating system, and then
- carves them up to satisfy individual @code{malloc} requests;
- @pxref{The GNU Allocator}.)
- @item int smblks
- This field is unused.
- @item int hblks
- This is the total number of chunks allocated with @code{mmap}.
- @item int hblkhd
- This is the total size of memory allocated with @code{mmap}, in bytes.
- @item int usmblks
- This field is unused and always 0.
- @item int fsmblks
- This field is unused.
- @item int uordblks
- This is the total size of memory occupied by chunks handed out by
- @code{malloc}.
- @item int fordblks
- This is the total size of memory occupied by free (not in use) chunks.
- @item int keepcost
- This is the size of the top-most releasable chunk that normally
- borders the end of the heap (i.e., the high end of the virtual address
- space's data segment).
- @end table
- @end deftp
- @deftypefun {struct mallinfo} mallinfo (void)
- @standards{SVID, malloc.h}
- @safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
- @c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified with atomics
- @c but non-atomically elsewhere, may get us inconsistent results. We
- @c mark the statistics as unsafe, rather than the fast-path functions
- @c that collect the possibly inconsistent data.
- @c __libc_mallinfo @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
- @c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
- @c mutex_lock dup @asulock @aculock
- @c int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena]
- @c malloc_consolidate dup ok
- @c check_malloc_state dup ok/disabled
- @c chunksize dup ok
- @c fastbin dupo ok
- @c bin_at dup ok
- @c last dup ok
- @c mutex_unlock @aculock
- This function returns information about the current dynamic memory usage
- in a structure of type @code{struct mallinfo}.
- @end deftypefun
- @node Summary of Malloc
- @subsubsection Summary of @code{malloc}-Related Functions
- Here is a summary of the functions that work with @code{malloc}:
- @table @code
- @item void *malloc (size_t @var{size})
- Allocate a block of @var{size} bytes. @xref{Basic Allocation}.
- @item void free (void *@var{addr})
- Free a block previously allocated by @code{malloc}. @xref{Freeing after
- Malloc}.
- @item void *realloc (void *@var{addr}, size_t @var{size})
- Make a block previously allocated by @code{malloc} larger or smaller,
- possibly by copying it to a new location. @xref{Changing Block Size}.
- @item void *reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
- Change the size of a block previously allocated by @code{malloc} to
- @code{@var{nmemb} * @var{size}} bytes as with @code{realloc}. @xref{Changing
- Block Size}.
- @item void *calloc (size_t @var{count}, size_t @var{eltsize})
- Allocate a block of @var{count} * @var{eltsize} bytes using
- @code{malloc}, and set its contents to zero. @xref{Allocating Cleared
- Space}.
- @item void *valloc (size_t @var{size})
- Allocate a block of @var{size} bytes, starting on a page boundary.
- @xref{Aligned Memory Blocks}.
- @item void *aligned_alloc (size_t @var{size}, size_t @var{alignment})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
- @item int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
- @item void *memalign (size_t @var{size}, size_t @var{boundary})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{boundary}. @xref{Aligned Memory Blocks}.
- @item int mallopt (int @var{param}, int @var{value})
- Adjust a tunable parameter. @xref{Malloc Tunable Parameters}.
- @item int mcheck (void (*@var{abortfn}) (void))
- Tell @code{malloc} to perform occasional consistency checks on
- dynamically allocated memory, and to call @var{abortfn} when an
- inconsistency is found. @xref{Heap Consistency Checking}.
- @item void *(*__malloc_hook) (size_t @var{size}, const void *@var{caller})
- A pointer to a function that @code{malloc} uses whenever it is called.
- @item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
- A pointer to a function that @code{realloc} uses whenever it is called.
- @item void (*__free_hook) (void *@var{ptr}, const void *@var{caller})
- A pointer to a function that @code{free} uses whenever it is called.
- @item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller})
- A pointer to a function that @code{aligned_alloc}, @code{memalign},
- @code{posix_memalign} and @code{valloc} use whenever they are called.
- @item struct mallinfo mallinfo (void)
- Return information about the current dynamic memory usage.
- @xref{Statistics of Malloc}.
- @end table
- @node Allocation Debugging
- @subsection Allocation Debugging
- @cindex allocation debugging
- @cindex malloc debugger
- A complicated task when programming with languages which do not use
- garbage collected dynamic memory allocation is to find memory leaks.
- Long running programs must ensure that dynamically allocated objects are
- freed at the end of their lifetime. If this does not happen the system
- runs out of memory, sooner or later.
- The @code{malloc} implementation in @theglibc{} provides some
- simple means to detect such leaks and obtain some information to find
- the location. To do this the application must be started in a special
- mode which is enabled by an environment variable. There are no speed
- penalties for the program if the debugging mode is not enabled.
- @menu
- * Tracing malloc:: How to install the tracing functionality.
- * Using the Memory Debugger:: Example programs excerpts.
- * Tips for the Memory Debugger:: Some more or less clever ideas.
- * Interpreting the traces:: What do all these lines mean?
- @end menu
- @node Tracing malloc
- @subsubsection How to install the tracing functionality
- @deftypefun void mtrace (void)
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
- @c Like the mcheck hooks, these are not designed with thread safety in
- @c mind, because the hook pointers are temporarily modified without
- @c regard to other threads, signals or cancellation.
- @c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
- @c __libc_secure_getenv dup @mtsenv
- @c malloc dup @ascuheap @acsmem
- @c fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
- @c fcntl dup ok
- @c setvbuf dup @aculock
- @c fprintf dup (on newly-created stream) @aculock
- @c __cxa_atexit (once) dup @asulock @aculock @acsmem
- @c free dup @ascuheap @acsmem
- When the @code{mtrace} function is called it looks for an environment
- variable named @code{MALLOC_TRACE}. This variable is supposed to
- contain a valid file name. The user must have write access. If the
- file already exists it is truncated. If the environment variable is not
- set or it does not name a valid file which can be opened for writing
- nothing is done. The behavior of @code{malloc} etc. is not changed.
- For obvious reasons this also happens if the application is installed
- with the SUID or SGID bit set.
- If the named file is successfully opened, @code{mtrace} installs special
- handlers for the functions @code{malloc}, @code{realloc}, and
- @code{free} (@pxref{Hooks for Malloc}). From then on, all uses of these
- functions are traced and protocolled into the file. There is now of
- course a speed penalty for all calls to the traced functions so tracing
- should not be enabled during normal use.
- This function is a GNU extension and generally not available on other
- systems. The prototype can be found in @file{mcheck.h}.
- @end deftypefun
- @deftypefun void muntrace (void)
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
- @c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
- @c fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
- @c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
- The @code{muntrace} function can be called after @code{mtrace} was used
- to enable tracing the @code{malloc} calls. If no (successful) call of
- @code{mtrace} was made @code{muntrace} does nothing.
- Otherwise it deinstalls the handlers for @code{malloc}, @code{realloc},
- and @code{free} and then closes the protocol file. No calls are
- protocolled anymore and the program runs again at full speed.
- This function is a GNU extension and generally not available on other
- systems. The prototype can be found in @file{mcheck.h}.
- @end deftypefun
- @node Using the Memory Debugger
- @subsubsection Example program excerpts
- Even though the tracing functionality does not influence the runtime
- behavior of the program it is not a good idea to call @code{mtrace} in
- all programs. Just imagine that you debug a program using @code{mtrace}
- and all other programs used in the debugging session also trace their
- @code{malloc} calls. The output file would be the same for all programs
- and thus is unusable. Therefore one should call @code{mtrace} only if
- compiled for debugging. A program could therefore start like this:
- @example
- #include <mcheck.h>
- int
- main (int argc, char *argv[])
- @{
- #ifdef DEBUGGING
- mtrace ();
- #endif
- @dots{}
- @}
- @end example
- This is all that is needed if you want to trace the calls during the
- whole runtime of the program. Alternatively you can stop the tracing at
- any time with a call to @code{muntrace}. It is even possible to restart
- the tracing again with a new call to @code{mtrace}. But this can cause
- unreliable results since there may be calls of the functions which are
- not called. Please note that not only the application uses the traced
- functions, also libraries (including the C library itself) use these
- functions.
- This last point is also why it is not a good idea to call @code{muntrace}
- before the program terminates. The libraries are informed about the
- termination of the program only after the program returns from
- @code{main} or calls @code{exit} and so cannot free the memory they use
- before this time.
- So the best thing one can do is to call @code{mtrace} as the very first
- function in the program and never call @code{muntrace}. So the program
- traces almost all uses of the @code{malloc} functions (except those
- calls which are executed by constructors of the program or used
- libraries).
- @node Tips for the Memory Debugger
- @subsubsection Some more or less clever ideas
- You know the situation. The program is prepared for debugging and in
- all debugging sessions it runs well. But once it is started without
- debugging the error shows up. A typical example is a memory leak that
- becomes visible only when we turn off the debugging. If you foresee
- such situations you can still win. Simply use something equivalent to
- the following little program:
- @example
- #include <mcheck.h>
- #include <signal.h>
- static void
- enable (int sig)
- @{
- mtrace ();
- signal (SIGUSR1, enable);
- @}
- static void
- disable (int sig)
- @{
- muntrace ();
- signal (SIGUSR2, disable);
- @}
- int
- main (int argc, char *argv[])
- @{
- @dots{}
- signal (SIGUSR1, enable);
- signal (SIGUSR2, disable);
- @dots{}
- @}
- @end example
- I.e., the user can start the memory debugger any time s/he wants if the
- program was started with @code{MALLOC_TRACE} set in the environment.
- The output will of course not show the allocations which happened before
- the first signal but if there is a memory leak this will show up
- nevertheless.
- @node Interpreting the traces
- @subsubsection Interpreting the traces
- If you take a look at the output it will look similar to this:
- @example
- = Start
- @ [0x8048209] - 0x8064cc8
- @ [0x8048209] - 0x8064ce0
- @ [0x8048209] - 0x8064cf8
- @ [0x80481eb] + 0x8064c48 0x14
- @ [0x80481eb] + 0x8064c60 0x14
- @ [0x80481eb] + 0x8064c78 0x14
- @ [0x80481eb] + 0x8064c90 0x14
- = End
- @end example
- What this all means is not really important since the trace file is not
- meant to be read by a human. Therefore no attention is given to
- readability. Instead there is a program which comes with @theglibc{}
- which interprets the traces and outputs a summary in an
- user-friendly way. The program is called @code{mtrace} (it is in fact a
- Perl script) and it takes one or two arguments. In any case the name of
- the file with the trace output must be specified. If an optional
- argument precedes the name of the trace file this must be the name of
- the program which generated the trace.
- @example
- drepper$ mtrace tst-mtrace log
- No memory leaks.
- @end example
- In this case the program @code{tst-mtrace} was run and it produced a
- trace file @file{log}. The message printed by @code{mtrace} shows there
- are no problems with the code, all allocated memory was freed
- afterwards.
- If we call @code{mtrace} on the example trace given above we would get a
- different outout:
- @example
- drepper$ mtrace errlog
- - 0x08064cc8 Free 2 was never alloc'd 0x8048209
- - 0x08064ce0 Free 3 was never alloc'd 0x8048209
- - 0x08064cf8 Free 4 was never alloc'd 0x8048209
- Memory not freed:
- -----------------
- Address Size Caller
- 0x08064c48 0x14 at 0x80481eb
- 0x08064c60 0x14 at 0x80481eb
- 0x08064c78 0x14 at 0x80481eb
- 0x08064c90 0x14 at 0x80481eb
- @end example
- We have called @code{mtrace} with only one argument and so the script
- has no chance to find out what is meant with the addresses given in the
- trace. We can do better:
- @example
- drepper$ mtrace tst errlog
- - 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst.c:39
- - 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst.c:39
- - 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst.c:39
- Memory not freed:
- -----------------
- Address Size Caller
- 0x08064c48 0x14 at /home/drepper/tst.c:33
- 0x08064c60 0x14 at /home/drepper/tst.c:33
- 0x08064c78 0x14 at /home/drepper/tst.c:33
- 0x08064c90 0x14 at /home/drepper/tst.c:33
- @end example
- Suddenly the output makes much more sense and the user can see
- immediately where the function calls causing the trouble can be found.
- Interpreting this output is not complicated. There are at most two
- different situations being detected. First, @code{free} was called for
- pointers which were never returned by one of the allocation functions.
- This is usually a very bad problem and what this looks like is shown in
- the first three lines of the output. Situations like this are quite
- rare and if they appear they show up very drastically: the program
- normally crashes.
- The other situation which is much harder to detect are memory leaks. As
- you can see in the output the @code{mtrace} function collects all this
- information and so can say that the program calls an allocation function
- from line 33 in the source file @file{/home/drepper/tst-mtrace.c} four
- times without freeing this memory before the program terminates.
- Whether this is a real problem remains to be investigated.
- @node Replacing malloc
- @subsection Replacing @code{malloc}
- @cindex @code{malloc} replacement
- @cindex @code{LD_PRELOAD} and @code{malloc}
- @cindex alternative @code{malloc} implementations
- @cindex customizing @code{malloc}
- @cindex interposing @code{malloc}
- @cindex preempting @code{malloc}
- @cindex replacing @code{malloc}
- @Theglibc{} supports replacing the built-in @code{malloc} implementation
- with a different allocator with the same interface. For dynamically
- linked programs, this happens through ELF symbol interposition, either
- using shared object dependencies or @code{LD_PRELOAD}. For static
- linking, the @code{malloc} replacement library must be linked in before
- linking against @code{libc.a} (explicitly or implicitly).
- @strong{Note:} Failure to provide a complete set of replacement
- functions (that is, all the functions used by the application,
- @theglibc{}, and other linked-in libraries) can lead to static linking
- failures, and, at run time, to heap corruption and application crashes.
- The minimum set of functions which has to be provided by a custom
- @code{malloc} is given in the table below.
- @table @code
- @item malloc
- @item free
- @item calloc
- @item realloc
- @end table
- These @code{malloc}-related functions are required for @theglibc{} to
- work.@footnote{Versions of @theglibc{} before 2.25 required that a
- custom @code{malloc} defines @code{__libc_memalign} (with the same
- interface as the @code{memalign} function).}
- The @code{malloc} implementation in @theglibc{} provides additional
- functionality not used by the library itself, but which is often used by
- other system libraries and applications. A general-purpose replacement
- @code{malloc} implementation should provide definitions of these
- functions, too. Their names are listed in the following table.
- @table @code
- @item aligned_alloc
- @item malloc_usable_size
- @item memalign
- @item posix_memalign
- @item pvalloc
- @item valloc
- @end table
- In addition, very old applications may use the obsolete @code{cfree}
- function.
- Further @code{malloc}-related functions such as @code{mallopt} or
- @code{mallinfo} will not have any effect or return incorrect statistics
- when a replacement @code{malloc} is in use. However, failure to replace
- these functions typically does not result in crashes or other incorrect
- application behavior, but may result in static linking failures.
- @node Obstacks
- @subsection Obstacks
- @cindex obstacks
- An @dfn{obstack} is a pool of memory containing a stack of objects. You
- can create any number of separate obstacks, and then allocate objects in
- specified obstacks. Within each obstack, the last object allocated must
- always be the first one freed, but distinct obstacks are independent of
- each other.
- Aside from this one constraint of order of freeing, obstacks are totally
- general: an obstack can contain any number of objects of any size. They
- are implemented with macros, so allocation is usually very fast as long as
- the objects are usually small. And the only space overhead per object is
- the padding needed to start each object on a suitable boundary.
- @menu
- * Creating Obstacks:: How to declare an obstack in your program.
- * Preparing for Obstacks:: Preparations needed before you can
- use obstacks.
- * Allocation in an Obstack:: Allocating objects in an obstack.
- * Freeing Obstack Objects:: Freeing objects in an obstack.
- * Obstack Functions:: The obstack functions are both
- functions and macros.
- * Growing Objects:: Making an object bigger by stages.
- * Extra Fast Growing:: Extra-high-efficiency (though more
- complicated) growing objects.
- * Status of an Obstack:: Inquiries about the status of an obstack.
- * Obstacks Data Alignment:: Controlling alignment of objects in obstacks.
- * Obstack Chunks:: How obstacks obtain and release chunks;
- efficiency considerations.
- * Summary of Obstacks::
- @end menu
- @node Creating Obstacks
- @subsubsection Creating Obstacks
- The utilities for manipulating obstacks are declared in the header
- file @file{obstack.h}.
- @pindex obstack.h
- @deftp {Data Type} {struct obstack}
- @standards{GNU, obstack.h}
- An obstack is represented by a data structure of type @code{struct
- obstack}. This structure has a small fixed size; it records the status
- of the obstack and how to find the space in which objects are allocated.
- It does not contain any of the objects themselves. You should not try
- to access the contents of the structure directly; use only the functions
- described in this chapter.
- @end deftp
- You can declare variables of type @code{struct obstack} and use them as
- obstacks, or you can allocate obstacks dynamically like any other kind
- of object. Dynamic allocation of obstacks allows your program to have a
- variable number of different stacks. (You can even allocate an
- obstack structure in another obstack, but this is rarely useful.)
- All the functions that work with obstacks require you to specify which
- obstack to use. You do this with a pointer of type @code{struct obstack
- *}. In the following, we often say ``an obstack'' when strictly
- speaking the object at hand is such a pointer.
- The objects in the obstack are packed into large blocks called
- @dfn{chunks}. The @code{struct obstack} structure points to a chain of
- the chunks currently in use.
- The obstack library obtains a new chunk whenever you allocate an object
- that won't fit in the previous chunk. Since the obstack library manages
- chunks automatically, you don't need to pay much attention to them, but
- you do need to supply a function which the obstack library should use to
- get a chunk. Usually you supply a function which uses @code{malloc}
- directly or indirectly. You must also supply a function to free a chunk.
- These matters are described in the following section.
- @node Preparing for Obstacks
- @subsubsection Preparing for Using Obstacks
- Each source file in which you plan to use the obstack functions
- must include the header file @file{obstack.h}, like this:
- @smallexample
- #include <obstack.h>
- @end smallexample
- @findex obstack_chunk_alloc
- @findex obstack_chunk_free
- Also, if the source file uses the macro @code{obstack_init}, it must
- declare or define two functions or macros that will be called by the
- obstack library. One, @code{obstack_chunk_alloc}, is used to allocate
- the chunks of memory into which objects are packed. The other,
- @code{obstack_chunk_free}, is used to return chunks when the objects in
- them are freed. These macros should appear before any use of obstacks
- in the source file.
- Usually these are defined to use @code{malloc} via the intermediary
- @code{xmalloc} (@pxref{Unconstrained Allocation}). This is done with
- the following pair of macro definitions:
- @smallexample
- #define obstack_chunk_alloc xmalloc
- #define obstack_chunk_free free
- @end smallexample
- @noindent
- Though the memory you get using obstacks really comes from @code{malloc},
- using obstacks is faster because @code{malloc} is called less often, for
- larger blocks of memory. @xref{Obstack Chunks}, for full details.
- At run time, before the program can use a @code{struct obstack} object
- as an obstack, it must initialize the obstack by calling
- @code{obstack_init}.
- @deftypefun int obstack_init (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{@acsmem{}}}
- @c obstack_init @mtsrace:obstack-ptr @acsmem
- @c _obstack_begin @acsmem
- @c chunkfun = obstack_chunk_alloc (suggested malloc)
- @c freefun = obstack_chunk_free (suggested free)
- @c *chunkfun @acsmem
- @c obstack_chunk_alloc user-supplied
- @c *obstack_alloc_failed_handler user-supplied
- @c -> print_and_abort (default)
- @c
- @c print_and_abort
- @c _ dup @ascuintl
- @c fxprintf dup @asucorrupt @aculock @acucorrupt
- @c exit @acucorrupt?
- Initialize obstack @var{obstack-ptr} for allocation of objects. This
- function calls the obstack's @code{obstack_chunk_alloc} function. If
- allocation of memory fails, the function pointed to by
- @code{obstack_alloc_failed_handler} is called. The @code{obstack_init}
- function always returns 1 (Compatibility notice: Former versions of
- obstack returned 0 if allocation failed).
- @end deftypefun
- Here are two examples of how to allocate the space for an obstack and
- initialize it. First, an obstack that is a static variable:
- @smallexample
- static struct obstack myobstack;
- @dots{}
- obstack_init (&myobstack);
- @end smallexample
- @noindent
- Second, an obstack that is itself dynamically allocated:
- @smallexample
- struct obstack *myobstack_ptr
- = (struct obstack *) xmalloc (sizeof (struct obstack));
- obstack_init (myobstack_ptr);
- @end smallexample
- @defvar obstack_alloc_failed_handler
- @standards{GNU, obstack.h}
- The value of this variable is a pointer to a function that
- @code{obstack} uses when @code{obstack_chunk_alloc} fails to allocate
- memory. The default action is to print a message and abort.
- You should supply a function that either calls @code{exit}
- (@pxref{Program Termination}) or @code{longjmp} (@pxref{Non-Local
- Exits}) and doesn't return.
- @smallexample
- void my_obstack_alloc_failed (void)
- @dots{}
- obstack_alloc_failed_handler = &my_obstack_alloc_failed;
- @end smallexample
- @end defvar
- @node Allocation in an Obstack
- @subsubsection Allocation in an Obstack
- @cindex allocation (obstacks)
- The most direct way to allocate an object in an obstack is with
- @code{obstack_alloc}, which is invoked almost like @code{malloc}.
- @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_alloc @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_blank dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- This allocates an uninitialized block of @var{size} bytes in an obstack
- and returns its address. Here @var{obstack-ptr} specifies which obstack
- to allocate the block in; it is the address of the @code{struct obstack}
- object which represents the obstack. Each obstack function or macro
- requires you to specify an @var{obstack-ptr} as the first argument.
- This function calls the obstack's @code{obstack_chunk_alloc} function if
- it needs to allocate a new chunk of memory; it calls
- @code{obstack_alloc_failed_handler} if allocation of memory by
- @code{obstack_chunk_alloc} failed.
- @end deftypefun
- For example, here is a function that allocates a copy of a string @var{str}
- in a specific obstack, which is in the variable @code{string_obstack}:
- @smallexample
- struct obstack string_obstack;
- char *
- copystring (char *string)
- @{
- size_t len = strlen (string) + 1;
- char *s = (char *) obstack_alloc (&string_obstack, len);
- memcpy (s, string, len);
- return s;
- @}
- @end smallexample
- To allocate a block with specified contents, use the function
- @code{obstack_copy}, declared like this:
- @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_copy @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_grow dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- This allocates a block and initializes it by copying @var{size}
- bytes of data starting at @var{address}. It calls
- @code{obstack_alloc_failed_handler} if allocation of memory by
- @code{obstack_chunk_alloc} failed.
- @end deftypefun
- @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_copy0 @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_grow0 dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- Like @code{obstack_copy}, but appends an extra byte containing a null
- character. This extra byte is not counted in the argument @var{size}.
- @end deftypefun
- The @code{obstack_copy0} function is convenient for copying a sequence
- of characters into an obstack as a null-terminated string. Here is an
- example of its use:
- @smallexample
- char *
- obstack_savestring (char *addr, int size)
- @{
- return obstack_copy0 (&myobstack, addr, size);
- @}
- @end smallexample
- @noindent
- Contrast this with the previous example of @code{savestring} using
- @code{malloc} (@pxref{Basic Allocation}).
- @node Freeing Obstack Objects
- @subsubsection Freeing Objects in an Obstack
- @cindex freeing (obstacks)
- To free an object allocated in an obstack, use the function
- @code{obstack_free}. Since the obstack is a stack of objects, freeing
- one object automatically frees all other objects allocated more recently
- in the same obstack.
- @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
- @c obstack_free @mtsrace:obstack-ptr @acucorrupt
- @c (obstack_free) @mtsrace:obstack-ptr @acucorrupt
- @c *freefun dup user-supplied
- If @var{object} is a null pointer, everything allocated in the obstack
- is freed. Otherwise, @var{object} must be the address of an object
- allocated in the obstack. Then @var{object} is freed, along with
- everything allocated in @var{obstack-ptr} since @var{object}.
- @end deftypefun
- Note that if @var{object} is a null pointer, the result is an
- uninitialized obstack. To free all memory in an obstack but leave it
- valid for further allocation, call @code{obstack_free} with the address
- of the first object allocated on the obstack:
- @smallexample
- obstack_free (obstack_ptr, first_object_allocated_ptr);
- @end smallexample
- Recall that the objects in an obstack are grouped into chunks. When all
- the objects in a chunk become free, the obstack library automatically
- frees the chunk (@pxref{Preparing for Obstacks}). Then other
- obstacks, or non-obstack allocation, can reuse the space of the chunk.
- @node Obstack Functions
- @subsubsection Obstack Functions and Macros
- @cindex macros
- The interfaces for using obstacks may be defined either as functions or
- as macros, depending on the compiler. The obstack facility works with
- all C compilers, including both @w{ISO C} and traditional C, but there are
- precautions you must take if you plan to use compilers other than GNU C.
- If you are using an old-fashioned @w{non-ISO C} compiler, all the obstack
- ``functions'' are actually defined only as macros. You can call these
- macros like functions, but you cannot use them in any other way (for
- example, you cannot take their address).
- Calling the macros requires a special precaution: namely, the first
- operand (the obstack pointer) may not contain any side effects, because
- it may be computed more than once. For example, if you write this:
- @smallexample
- obstack_alloc (get_obstack (), 4);
- @end smallexample
- @noindent
- you will find that @code{get_obstack} may be called several times.
- If you use @code{*obstack_list_ptr++} as the obstack pointer argument,
- you will get very strange results since the incrementation may occur
- several times.
- In @w{ISO C}, each function has both a macro definition and a function
- definition. The function definition is used if you take the address of the
- function without calling it. An ordinary call uses the macro definition by
- default, but you can request the function definition instead by writing the
- function name in parentheses, as shown here:
- @smallexample
- char *x;
- void *(*funcp) ();
- /* @r{Use the macro}. */
- x = (char *) obstack_alloc (obptr, size);
- /* @r{Call the function}. */
- x = (char *) (obstack_alloc) (obptr, size);
- /* @r{Take the address of the function}. */
- funcp = obstack_alloc;
- @end smallexample
- @noindent
- This is the same situation that exists in @w{ISO C} for the standard library
- functions. @xref{Macro Definitions}.
- @strong{Warning:} When you do use the macros, you must observe the
- precaution of avoiding side effects in the first operand, even in @w{ISO C}.
- If you use the GNU C compiler, this precaution is not necessary, because
- various language extensions in GNU C permit defining the macros so as to
- compute each argument only once.
- @node Growing Objects
- @subsubsection Growing Objects
- @cindex growing objects (in obstacks)
- @cindex changing the size of a block (obstacks)
- Because memory in obstack chunks is used sequentially, it is possible to
- build up an object step by step, adding one or more bytes at a time to the
- end of the object. With this technique, you do not need to know how much
- data you will put in the object until you come to the end of it. We call
- this the technique of @dfn{growing objects}. The special functions
- for adding data to the growing object are described in this section.
- You don't need to do anything special when you start to grow an object.
- Using one of the functions to add data to the object automatically
- starts it. However, it is necessary to say explicitly when the object is
- finished. This is done with the function @code{obstack_finish}.
- The actual address of the object thus built up is not known until the
- object is finished. Until then, it always remains possible that you will
- add so much data that the object must be copied into a new chunk.
- While the obstack is in use for a growing object, you cannot use it for
- ordinary allocation of another object. If you try to do so, the space
- already added to the growing object will become part of the other object.
- @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_blank @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c *chunkfun dup @acsmem
- @c *obstack_alloc_failed_handler dup user-supplied
- @c *freefun
- @c obstack_blank_fast dup @mtsrace:obstack-ptr
- The most basic function for adding to a growing object is
- @code{obstack_blank}, which adds space without initializing it.
- @end deftypefun
- @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c memcpy ok
- To add a block of initialized space, use @code{obstack_grow}, which is
- the growing-object analogue of @code{obstack_copy}. It adds @var{size}
- bytes of data to the growing object, copying the contents from
- @var{data}.
- @end deftypefun
- @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_grow0 @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c (no sequence point between storing NUL and incrementing next_free)
- @c (multiple changes to next_free => @acucorrupt)
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c memcpy ok
- This is the growing-object analogue of @code{obstack_copy0}. It adds
- @var{size} bytes copied from @var{data}, followed by an additional null
- character.
- @end deftypefun
- @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_1grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_1grow_fast dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- To add one character at a time, use the function @code{obstack_1grow}.
- It adds a single byte containing @var{c} to the growing object.
- @end deftypefun
- @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_ptr_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_ptr_grow_fast dup @mtsrace:obstack-ptr
- Adding the value of a pointer one can use the function
- @code{obstack_ptr_grow}. It adds @code{sizeof (void *)} bytes
- containing the value of @var{data}.
- @end deftypefun
- @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_int_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_int_grow_fast dup @mtsrace:obstack-ptr
- A single value of type @code{int} can be added by using the
- @code{obstack_int_grow} function. It adds @code{sizeof (int)} bytes to
- the growing object and initializes them with the value of @var{data}.
- @end deftypefun
- @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
- @c obstack_finish @mtsrace:obstack-ptr @acucorrupt
- When you are finished growing the object, use the function
- @code{obstack_finish} to close it off and return its final address.
- Once you have finished the object, the obstack is available for ordinary
- allocation or for growing another object.
- This function can return a null pointer under the same conditions as
- @code{obstack_alloc} (@pxref{Allocation in an Obstack}).
- @end deftypefun
- When you build an object by growing it, you will probably need to know
- afterward how long it became. You need not keep track of this as you grow
- the object, because you can find out the length from the obstack just
- before finishing the object with the function @code{obstack_object_size},
- declared as follows:
- @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- This function returns the current size of the growing object, in bytes.
- Remember to call this function @emph{before} finishing the object.
- After it is finished, @code{obstack_object_size} will return zero.
- @end deftypefun
- If you have started growing an object and wish to cancel it, you should
- finish it and then free it, like this:
- @smallexample
- obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
- @end smallexample
- @noindent
- This has no effect if no object was growing.
- @cindex shrinking objects
- You can use @code{obstack_blank} with a negative size argument to make
- the current object smaller. Just don't try to shrink it beyond zero
- length---there's no telling what will happen if you do that.
- @node Extra Fast Growing
- @subsubsection Extra Fast Growing Objects
- @cindex efficiency and obstacks
- The usual functions for growing objects incur overhead for checking
- whether there is room for the new growth in the current chunk. If you
- are frequently constructing objects in small steps of growth, this
- overhead can be significant.
- You can reduce the overhead by using special ``fast growth''
- functions that grow the object without checking. In order to have a
- robust program, you must do the checking yourself. If you do this checking
- in the simplest way each time you are about to add data to the object, you
- have not saved anything, because that is what the ordinary growth
- functions do. But if you can arrange to check less often, or check
- more efficiently, then you make the program faster.
- The function @code{obstack_room} returns the amount of room available
- in the current chunk. It is declared as follows:
- @deftypefun int obstack_room (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- This returns the number of bytes that can be added safely to the current
- growing object (or to an object about to be started) in obstack
- @var{obstack-ptr} using the fast growth functions.
- @end deftypefun
- While you know there is room, you can use these fast growth functions
- for adding data to a growing object:
- @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_1grow_fast @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c (no sequence point between copying c and incrementing next_free)
- The function @code{obstack_1grow_fast} adds one byte containing the
- character @var{c} to the growing object in obstack @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_ptr_grow_fast @mtsrace:obstack-ptr
- The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)}
- bytes containing the value of @var{data} to the growing object in
- obstack @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_int_grow_fast @mtsrace:obstack-ptr
- The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes
- containing the value of @var{data} to the growing object in obstack
- @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_blank_fast @mtsrace:obstack-ptr
- The function @code{obstack_blank_fast} adds @var{size} bytes to the
- growing object in obstack @var{obstack-ptr} without initializing them.
- @end deftypefun
- When you check for space using @code{obstack_room} and there is not
- enough room for what you want to add, the fast growth functions
- are not safe. In this case, simply use the corresponding ordinary
- growth function instead. Very soon this will copy the object to a
- new chunk; then there will be lots of room available again.
- So, each time you use an ordinary growth function, check afterward for
- sufficient space using @code{obstack_room}. Once the object is copied
- to a new chunk, there will be plenty of space again, so the program will
- start using the fast growth functions again.
- Here is an example:
- @smallexample
- @group
- void
- add_string (struct obstack *obstack, const char *ptr, int len)
- @{
- while (len > 0)
- @{
- int room = obstack_room (obstack);
- if (room == 0)
- @{
- /* @r{Not enough room. Add one character slowly,}
- @r{which may copy to a new chunk and make room.} */
- obstack_1grow (obstack, *ptr++);
- len--;
- @}
- else
- @{
- if (room > len)
- room = len;
- /* @r{Add fast as much as we have room for.} */
- len -= room;
- while (room-- > 0)
- obstack_1grow_fast (obstack, *ptr++);
- @}
- @}
- @}
- @end group
- @end smallexample
- @node Status of an Obstack
- @subsubsection Status of an Obstack
- @cindex obstack status
- @cindex status of obstack
- Here are functions that provide information on the current status of
- allocation in an obstack. You can use them to learn about an object while
- still growing it.
- @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
- This function returns the tentative address of the beginning of the
- currently growing object in @var{obstack-ptr}. If you finish the object
- immediately, it will have that address. If you make it larger first, it
- may outgrow the current chunk---then its address will change!
- If no object is growing, this value says where the next object you
- allocate will start (once again assuming it fits in the current
- chunk).
- @end deftypefun
- @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
- This function returns the address of the first free byte in the current
- chunk of obstack @var{obstack-ptr}. This is the end of the currently
- growing object. If no object is growing, @code{obstack_next_free}
- returns the same value as @code{obstack_base}.
- @end deftypefun
- @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @c dup
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- This function returns the size in bytes of the currently growing object.
- This is equivalent to
- @smallexample
- obstack_next_free (@var{obstack-ptr}) - obstack_base (@var{obstack-ptr})
- @end smallexample
- @end deftypefun
- @node Obstacks Data Alignment
- @subsubsection Alignment of Data in Obstacks
- @cindex alignment (in obstacks)
- Each obstack has an @dfn{alignment boundary}; each object allocated in
- the obstack automatically starts on an address that is a multiple of the
- specified boundary. By default, this boundary is aligned so that
- the object can hold any type of data.
- To access an obstack's alignment boundary, use the macro
- @code{obstack_alignment_mask}, whose function prototype looks like
- this:
- @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- The value is a bit mask; a bit that is 1 indicates that the corresponding
- bit in the address of an object should be 0. The mask value should be one
- less than a power of 2; the effect is that all object addresses are
- multiples of that power of 2. The default value of the mask is a value
- that allows aligned objects to hold any type of data: for example, if
- its value is 3, any type of data can be stored at locations whose
- addresses are multiples of 4. A mask value of 0 means an object can start
- on any multiple of 1 (that is, no alignment is required).
- The expansion of the macro @code{obstack_alignment_mask} is an lvalue,
- so you can alter the mask by assignment. For example, this statement:
- @smallexample
- obstack_alignment_mask (obstack_ptr) = 0;
- @end smallexample
- @noindent
- has the effect of turning off alignment processing in the specified obstack.
- @end deftypefn
- Note that a change in alignment mask does not take effect until
- @emph{after} the next time an object is allocated or finished in the
- obstack. If you are not growing an object, you can make the new
- alignment mask take effect immediately by calling @code{obstack_finish}.
- This will finish a zero-length object and then do proper alignment for
- the next object.
- @node Obstack Chunks
- @subsubsection Obstack Chunks
- @cindex efficiency of chunks
- @cindex chunks
- Obstacks work by allocating space for themselves in large chunks, and
- then parceling out space in the chunks to satisfy your requests. Chunks
- are normally 4096 bytes long unless you specify a different chunk size.
- The chunk size includes 8 bytes of overhead that are not actually used
- for storing objects. Regardless of the specified size, longer chunks
- will be allocated when necessary for long objects.
- The obstack library allocates chunks by calling the function
- @code{obstack_chunk_alloc}, which you must define. When a chunk is no
- longer needed because you have freed all the objects in it, the obstack
- library frees the chunk by calling @code{obstack_chunk_free}, which you
- must also define.
- These two must be defined (as macros) or declared (as functions) in each
- source file that uses @code{obstack_init} (@pxref{Creating Obstacks}).
- Most often they are defined as macros like this:
- @smallexample
- #define obstack_chunk_alloc malloc
- #define obstack_chunk_free free
- @end smallexample
- Note that these are simple macros (no arguments). Macro definitions with
- arguments will not work! It is necessary that @code{obstack_chunk_alloc}
- or @code{obstack_chunk_free}, alone, expand into a function name if it is
- not itself a function name.
- If you allocate chunks with @code{malloc}, the chunk size should be a
- power of 2. The default chunk size, 4096, was chosen because it is long
- enough to satisfy many typical requests on the obstack yet short enough
- not to waste too much memory in the portion of the last chunk not yet used.
- @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This returns the chunk size of the given obstack.
- @end deftypefn
- Since this macro expands to an lvalue, you can specify a new chunk size by
- assigning it a new value. Doing so does not affect the chunks already
- allocated, but will change the size of chunks allocated for that particular
- obstack in the future. It is unlikely to be useful to make the chunk size
- smaller, but making it larger might improve efficiency if you are
- allocating many objects whose size is comparable to the chunk size. Here
- is how to do so cleanly:
- @smallexample
- if (obstack_chunk_size (obstack_ptr) < @var{new-chunk-size})
- obstack_chunk_size (obstack_ptr) = @var{new-chunk-size};
- @end smallexample
- @node Summary of Obstacks
- @subsubsection Summary of Obstack Functions
- Here is a summary of all the functions associated with obstacks. Each
- takes the address of an obstack (@code{struct obstack *}) as its first
- argument.
- @table @code
- @item void obstack_init (struct obstack *@var{obstack-ptr})
- Initialize use of an obstack. @xref{Creating Obstacks}.
- @item void *obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
- Allocate an object of @var{size} uninitialized bytes.
- @xref{Allocation in an Obstack}.
- @item void *obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Allocate an object of @var{size} bytes, with contents copied from
- @var{address}. @xref{Allocation in an Obstack}.
- @item void *obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Allocate an object of @var{size}+1 bytes, with @var{size} of them copied
- from @var{address}, followed by a null character at the end.
- @xref{Allocation in an Obstack}.
- @item void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
- Free @var{object} (and everything allocated in the specified obstack
- more recently than @var{object}). @xref{Freeing Obstack Objects}.
- @item void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
- Add @var{size} uninitialized bytes to a growing object.
- @xref{Growing Objects}.
- @item void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Add @var{size} bytes, copied from @var{address}, to a growing object.
- @xref{Growing Objects}.
- @item void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Add @var{size} bytes, copied from @var{address}, to a growing object,
- and then add another byte containing a null character. @xref{Growing
- Objects}.
- @item void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{data-char})
- Add one byte containing @var{data-char} to a growing object.
- @xref{Growing Objects}.
- @item void *obstack_finish (struct obstack *@var{obstack-ptr})
- Finalize the object that is growing and return its permanent address.
- @xref{Growing Objects}.
- @item int obstack_object_size (struct obstack *@var{obstack-ptr})
- Get the current size of the currently growing object. @xref{Growing
- Objects}.
- @item void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
- Add @var{size} uninitialized bytes to a growing object without checking
- that there is enough room. @xref{Extra Fast Growing}.
- @item void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{data-char})
- Add one byte containing @var{data-char} to a growing object without
- checking that there is enough room. @xref{Extra Fast Growing}.
- @item int obstack_room (struct obstack *@var{obstack-ptr})
- Get the amount of room now available for growing the current object.
- @xref{Extra Fast Growing}.
- @item int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
- The mask used for aligning the beginning of an object. This is an
- lvalue. @xref{Obstacks Data Alignment}.
- @item int obstack_chunk_size (struct obstack *@var{obstack-ptr})
- The size for allocating chunks. This is an lvalue. @xref{Obstack Chunks}.
- @item void *obstack_base (struct obstack *@var{obstack-ptr})
- Tentative starting address of the currently growing object.
- @xref{Status of an Obstack}.
- @item void *obstack_next_free (struct obstack *@var{obstack-ptr})
- Address just after the end of the currently growing object.
- @xref{Status of an Obstack}.
- @end table
- @node Variable Size Automatic
- @subsection Automatic Storage with Variable Size
- @cindex automatic freeing
- @cindex @code{alloca} function
- @cindex automatic storage with variable size
- The function @code{alloca} supports a kind of half-dynamic allocation in
- which blocks are allocated dynamically but freed automatically.
- Allocating a block with @code{alloca} is an explicit action; you can
- allocate as many blocks as you wish, and compute the size at run time. But
- all the blocks are freed when you exit the function that @code{alloca} was
- called from, just as if they were automatic variables declared in that
- function. There is no way to free the space explicitly.
- The prototype for @code{alloca} is in @file{stdlib.h}. This function is
- a BSD extension.
- @pindex stdlib.h
- @deftypefun {void *} alloca (size_t @var{size})
- @standards{GNU, stdlib.h}
- @standards{BSD, stdlib.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- The return value of @code{alloca} is the address of a block of @var{size}
- bytes of memory, allocated in the stack frame of the calling function.
- @end deftypefun
- Do not use @code{alloca} inside the arguments of a function call---you
- will get unpredictable results, because the stack space for the
- @code{alloca} would appear on the stack in the middle of the space for
- the function arguments. An example of what to avoid is @code{foo (x,
- alloca (4), y)}.
- @c This might get fixed in future versions of GCC, but that won't make
- @c it safe with compilers generally.
- @menu
- * Alloca Example:: Example of using @code{alloca}.
- * Advantages of Alloca:: Reasons to use @code{alloca}.
- * Disadvantages of Alloca:: Reasons to avoid @code{alloca}.
- * GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative
- method of allocating dynamically and
- freeing automatically.
- @end menu
- @node Alloca Example
- @subsubsection @code{alloca} Example
- As an example of the use of @code{alloca}, here is a function that opens
- a file name made from concatenating two argument strings, and returns a
- file descriptor or minus one signifying failure:
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
- @}
- @end smallexample
- @noindent
- Here is how you would get the same results with @code{malloc} and
- @code{free}:
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1);
- int desc;
- if (name == 0)
- fatal ("virtual memory exceeded");
- stpcpy (stpcpy (name, str1), str2);
- desc = open (name, flags, mode);
- free (name);
- return desc;
- @}
- @end smallexample
- As you can see, it is simpler with @code{alloca}. But @code{alloca} has
- other, more important advantages, and some disadvantages.
- @node Advantages of Alloca
- @subsubsection Advantages of @code{alloca}
- Here are the reasons why @code{alloca} may be preferable to @code{malloc}:
- @itemize @bullet
- @item
- Using @code{alloca} wastes very little space and is very fast. (It is
- open-coded by the GNU C compiler.)
- @item
- Since @code{alloca} does not have separate pools for different sizes of
- blocks, space used for any size block can be reused for any other size.
- @code{alloca} does not cause memory fragmentation.
- @item
- @cindex longjmp
- Nonlocal exits done with @code{longjmp} (@pxref{Non-Local Exits})
- automatically free the space allocated with @code{alloca} when they exit
- through the function that called @code{alloca}. This is the most
- important reason to use @code{alloca}.
- To illustrate this, suppose you have a function
- @code{open_or_report_error} which returns a descriptor, like
- @code{open}, if it succeeds, but does not return to its caller if it
- fails. If the file cannot be opened, it prints an error message and
- jumps out to the command level of your program using @code{longjmp}.
- Let's change @code{open2} (@pxref{Alloca Example}) to use this
- subroutine:@refill
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open_or_report_error (name, flags, mode);
- @}
- @end smallexample
- @noindent
- Because of the way @code{alloca} works, the memory it allocates is
- freed even when an error occurs, with no special effort required.
- By contrast, the previous definition of @code{open2} (which uses
- @code{malloc} and @code{free}) would develop a memory leak if it were
- changed in this way. Even if you are willing to make more changes to
- fix it, there is no easy way to do so.
- @end itemize
- @node Disadvantages of Alloca
- @subsubsection Disadvantages of @code{alloca}
- @cindex @code{alloca} disadvantages
- @cindex disadvantages of @code{alloca}
- These are the disadvantages of @code{alloca} in comparison with
- @code{malloc}:
- @itemize @bullet
- @item
- If you try to allocate more memory than the machine can provide, you
- don't get a clean error message. Instead you get a fatal signal like
- the one you would get from an infinite recursion; probably a
- segmentation violation (@pxref{Program Error Signals}).
- @item
- Some @nongnusystems{} fail to support @code{alloca}, so it is less
- portable. However, a slower emulation of @code{alloca} written in C
- is available for use on systems with this deficiency.
- @end itemize
- @node GNU C Variable-Size Arrays
- @subsubsection GNU C Variable-Size Arrays
- @cindex variable-sized arrays
- In GNU C, you can replace most uses of @code{alloca} with an array of
- variable size. Here is how @code{open2} would look then:
- @smallexample
- int open2 (char *str1, char *str2, int flags, int mode)
- @{
- char name[strlen (str1) + strlen (str2) + 1];
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
- @}
- @end smallexample
- But @code{alloca} is not always equivalent to a variable-sized array, for
- several reasons:
- @itemize @bullet
- @item
- A variable size array's space is freed at the end of the scope of the
- name of the array. The space allocated with @code{alloca}
- remains until the end of the function.
- @item
- It is possible to use @code{alloca} within a loop, allocating an
- additional block on each iteration. This is impossible with
- variable-sized arrays.
- @end itemize
- @strong{NB:} If you mix use of @code{alloca} and variable-sized arrays
- within one function, exiting a scope in which a variable-sized array was
- declared frees all blocks allocated with @code{alloca} during the
- execution of that scope.
- @node Resizing the Data Segment
- @section Resizing the Data Segment
- The symbols in this section are declared in @file{unistd.h}.
- You will not normally use the functions in this section, because the
- functions described in @ref{Memory Allocation} are easier to use. Those
- are interfaces to a @glibcadj{} memory allocator that uses the
- functions below itself. The functions below are simple interfaces to
- system calls.
- @deftypefun int brk (void *@var{addr})
- @standards{BSD, unistd.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{brk} sets the high end of the calling process' data segment to
- @var{addr}.
- The address of the end of a segment is defined to be the address of the
- last byte in the segment plus 1.
- The function has no effect if @var{addr} is lower than the low end of
- the data segment. (This is considered success, by the way.)
- The function fails if it would cause the data segment to overlap another
- segment or exceed the process' data storage limit (@pxref{Limits on
- Resources}).
- The function is named for a common historical case where data storage
- and the stack are in the same segment. Data storage allocation grows
- upward from the bottom of the segment while the stack grows downward
- toward it from the top of the segment and the curtain between them is
- called the @dfn{break}.
- The return value is zero on success. On failure, the return value is
- @code{-1} and @code{errno} is set accordingly. The following @code{errno}
- values are specific to this function:
- @table @code
- @item ENOMEM
- The request would cause the data segment to overlap another segment or
- exceed the process' data storage limit.
- @end table
- @c The Brk system call in Linux (as opposed to the GNU C Library function)
- @c is considerably different. It always returns the new end of the data
- @c segment, whether it succeeds or fails. The GNU C library Brk determines
- @c it's a failure if and only if the system call returns an address less
- @c than the address requested.
- @end deftypefun
- @deftypefun void *sbrk (ptrdiff_t @var{delta})
- @standards{BSD, unistd.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This function is the same as @code{brk} except that you specify the new
- end of the data segment as an offset @var{delta} from the current end
- and on success the return value is the address of the resulting end of
- the data segment instead of zero.
- This means you can use @samp{sbrk(0)} to find out what the current end
- of the data segment is.
- @end deftypefun
- @node Memory Protection
- @section Memory Protection
- @cindex memory protection
- @cindex page protection
- @cindex protection flags
- When a page is mapped using @code{mmap}, page protection flags can be
- specified using the protection flags argument. @xref{Memory-mapped
- I/O}.
- The following flags are available:
- @vtable @code
- @item PROT_WRITE
- @standards{POSIX, sys/mman.h}
- The memory can be written to.
- @item PROT_READ
- @standards{POSIX, sys/mman.h}
- The memory can be read. On some architectures, this flag implies that
- the memory can be executed as well (as if @code{PROT_EXEC} had been
- specified at the same time).
- @item PROT_EXEC
- @standards{POSIX, sys/mman.h}
- The memory can be used to store instructions which can then be executed.
- On most architectures, this flag implies that the memory can be read (as
- if @code{PROT_READ} had been specified).
- @item PROT_NONE
- @standards{POSIX, sys/mman.h}
- This flag must be specified on its own.
- The memory is reserved, but cannot be read, written, or executed. If
- this flag is specified in a call to @code{mmap}, a virtual memory area
- will be set aside for future use in the process, and @code{mmap} calls
- without the @code{MAP_FIXED} flag will not use it for subsequent
- allocations. For anonymous mappings, the kernel will not reserve any
- physical memory for the allocation at the time the mapping is created.
- @end vtable
- The operating system may keep track of these flags separately even if
- the underlying hardware treats them the same for the purposes of access
- checking (as happens with @code{PROT_READ} and @code{PROT_EXEC} on some
- platforms). On GNU systems, @code{PROT_EXEC} always implies
- @code{PROT_READ}, so that users can view the machine code which is
- executing on their system.
- Inappropriate access will cause a segfault (@pxref{Program Error
- Signals}).
- After allocation, protection flags can be changed using the
- @code{mprotect} function.
- @deftypefun int mprotect (void *@var{address}, size_t @var{length}, int @var{protection})
- @standards{POSIX, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- A successful call to the @code{mprotect} function changes the protection
- flags of at least @var{length} bytes of memory, starting at
- @var{address}.
- @var{address} must be aligned to the page size for the mapping. The
- system page size can be obtained by calling @code{sysconf} with the
- @code{_SC_PAGESIZE} parameter (@pxref{Sysconf Definition}). The system
- page size is the granularity in which the page protection of anonymous
- memory mappings and most file mappings can be changed. Memory which is
- mapped from special files or devices may have larger page granularity
- than the system page size and may require larger alignment.
- @var{length} is the number of bytes whose protection flags must be
- changed. It is automatically rounded up to the next multiple of the
- system page size.
- @var{protection} is a combination of the @code{PROT_*} flags described
- above.
- The @code{mprotect} function returns @math{0} on success and @math{-1}
- on failure.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item ENOMEM
- The system was not able to allocate resources to fulfill the request.
- This can happen if there is not enough physical memory in the system for
- the allocation of backing storage. The error can also occur if the new
- protection flags would cause the memory region to be split from its
- neighbors, and the process limit for the number of such distinct memory
- regions would be exceeded.
- @item EINVAL
- @var{address} is not properly aligned to a page boundary for the
- mapping, or @var{length} (after rounding up to the system page size) is
- not a multiple of the applicable page size for the mapping, or the
- combination of flags in @var{protection} is not valid.
- @item EACCES
- The file for a file-based mapping was not opened with open flags which
- are compatible with @var{protection}.
- @item EPERM
- The system security policy does not allow a mapping with the specified
- flags. For example, mappings which are both @code{PROT_EXEC} and
- @code{PROT_WRITE} at the same time might not be allowed.
- @end table
- @end deftypefun
- If the @code{mprotect} function is used to make a region of memory
- inaccessible by specifying the @code{PROT_NONE} protection flag and
- access is later restored, the memory retains its previous contents.
- On some systems, it may not be possible to specify additional flags
- which were not present when the mapping was first created. For example,
- an attempt to make a region of memory executable could fail if the
- initial protection flags were @samp{PROT_READ | PROT_WRITE}.
- In general, the @code{mprotect} function can be used to change any
- process memory, no matter how it was allocated. However, portable use
- of the function requires that it is only used with memory regions
- returned by @code{mmap} or @code{mmap64}.
- @subsection Memory Protection Keys
- @cindex memory protection key
- @cindex protection key
- @cindex MPK
- On some systems, further restrictions can be added to specific pages
- using @dfn{memory protection keys}. These restrictions work as follows:
- @itemize @bullet
- @item
- All memory pages are associated with a protection key. The default
- protection key does not cause any additional protections to be applied
- during memory accesses. New keys can be allocated with the
- @code{pkey_alloc} function, and applied to pages using
- @code{pkey_mprotect}.
- @item
- Each thread has a set of separate access right restriction for each
- protection key. These access rights can be manipulated using the
- @code{pkey_set} and @code{pkey_get} functions.
- @item
- During a memory access, the system obtains the protection key for the
- accessed page and uses that to determine the applicable access rights,
- as configured for the current thread. If the access is restricted, a
- segmentation fault is the result ((@pxref{Program Error Signals}).
- These checks happen in addition to the @code{PROT_}* protection flags
- set by @code{mprotect} or @code{pkey_mprotect}.
- @end itemize
- New threads and subprocesses inherit the access rights of the current
- thread. If a protection key is allocated subsequently, existing threads
- (except the current) will use an unspecified system default for the
- access rights associated with newly allocated keys.
- Upon entering a signal handler, the system resets the access rights of
- the current thread so that pages with the default key can be accessed,
- but the access rights for other protection keys are unspecified.
- Applications are expected to allocate a key once using
- @code{pkey_alloc}, and apply the key to memory regions which need
- special protection with @code{pkey_mprotect}:
- @smallexample
- int key = pkey_alloc (0, PKEY_DISABLE_ACCESS);
- if (key < 0)
- /* Perform error checking, including fallback for lack of support. */
- ...;
- /* Apply the key to a special memory region used to store critical
- data. */
- if (pkey_mprotect (region, region_length,
- PROT_READ | PROT_WRITE, key) < 0)
- ...; /* Perform error checking (generally fatal). */
- @end smallexample
- If the key allocation fails due to lack of support for memory protection
- keys, the @code{pkey_mprotect} call can usually be skipped. In this
- case, the region will not be protected by default. It is also possible
- to call @code{pkey_mprotect} with a key value of @math{-1}, in which
- case it will behave in the same way as @code{mprotect}.
- After key allocation assignment to memory pages, @code{pkey_set} can be
- used to temporarily acquire access to the memory region and relinquish
- it again:
- @smallexample
- if (key >= 0 && pkey_set (key, 0) < 0)
- ...; /* Perform error checking (generally fatal). */
- /* At this point, the current thread has read-write access to the
- memory region. */
- ...
- /* Revoke access again. */
- if (key >= 0 && pkey_set (key, PKEY_DISABLE_ACCESS) < 0)
- ...; /* Perform error checking (generally fatal). */
- @end smallexample
- In this example, a negative key value indicates that no key had been
- allocated, which means that the system lacks support for memory
- protection keys and it is not necessary to change the the access rights
- of the current thread (because it always has access).
- Compared to using @code{mprotect} to change the page protection flags,
- this approach has two advantages: It is thread-safe in the sense that
- the access rights are only changed for the current thread, so another
- thread which changes its own access rights concurrently to gain access
- to the mapping will not suddenly see its access rights revoked. And
- @code{pkey_set} typically does not involve a call into the kernel and a
- context switch, so it is more efficient.
- @deftypefun int pkey_alloc (unsigned int @var{flags}, unsigned int @var{restrictions})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
- Allocate a new protection key. The @var{flags} argument is reserved and
- must be zero. The @var{restrictions} argument specifies access rights
- which are applied to the current thread (as if with @code{pkey_set}
- below). Access rights of other threads are not changed.
- The function returns the new protection key, a non-negative number, or
- @math{-1} on error.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item ENOSYS
- The system does not implement memory protection keys.
- @item EINVAL
- The @var{flags} argument is not zero.
- The @var{restrictions} argument is invalid.
- The system does not implement memory protection keys or runs in a mode
- in which memory protection keys are disabled.
- @item ENOSPC
- All available protection keys already have been allocated.
- @end table
- @end deftypefun
- @deftypefun int pkey_free (int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Deallocate the protection key, so that it can be reused by
- @code{pkey_alloc}.
- Calling this function does not change the access rights of the freed
- protection key. The calling thread and other threads may retain access
- to it, even if it is subsequently allocated again. For this reason, it
- is not recommended to call the @code{pkey_free} function.
- @table @code
- @item ENOSYS
- The system does not implement memory protection keys.
- @item EINVAL
- The @var{key} argument is not a valid protection key.
- @end table
- @end deftypefun
- @deftypefun int pkey_mprotect (void *@var{address}, size_t @var{length}, int @var{protection}, int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Similar to @code{mprotect}, but also set the memory protection key for
- the memory region to @code{key}.
- Some systems use memory protection keys to emulate certain combinations
- of @var{protection} flags. Under such circumstances, specifying an
- explicit protection key may behave as if additional flags have been
- specified in @var{protection}, even though this does not happen with the
- default protection key. For example, some systems can support
- @code{PROT_EXEC}-only mappings only with a default protection key, and
- memory with a key which was allocated using @code{pkey_alloc} will still
- be readable if @code{PROT_EXEC} is specified without @code{PROT_READ}.
- If @var{key} is @math{-1}, the default protection key is applied to the
- mapping, just as if @code{mprotect} had been called.
- The @code{pkey_mprotect} function returns @math{0} on success and
- @math{-1} on failure. The same @code{errno} error conditions as for
- @code{mprotect} are defined for this function, with the following
- addition:
- @table @code
- @item EINVAL
- The @var{key} argument is not @math{-1} or a valid memory protection
- key allocated using @code{pkey_alloc}.
- @item ENOSYS
- The system does not implement memory protection keys, and @var{key} is
- not @math{-1}.
- @end table
- @end deftypefun
- @deftypefun int pkey_set (int @var{key}, unsigned int @var{rights})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Change the access rights of the current thread for memory pages with the
- protection key @var{key} to @var{rights}. If @var{rights} is zero, no
- additional access restrictions on top of the page protection flags are
- applied. Otherwise, @var{rights} is a combination of the following
- flags:
- @vtable @code
- @item PKEY_DISABLE_WRITE
- @standards{Linux, sys/mman.h}
- Subsequent attempts to write to memory with the specified protection
- key will fault.
- @item PKEY_DISABLE_ACCESS
- @standards{Linux, sys/mman.h}
- Subsequent attempts to write to or read from memory with the specified
- protection key will fault.
- @end vtable
- Operations not specified as flags are not restricted. In particular,
- this means that the memory region will remain executable if it was
- mapped with the @code{PROT_EXEC} protection flag and
- @code{PKEY_DISABLE_ACCESS} has been specified.
- Calling the @code{pkey_set} function with a protection key which was not
- allocated by @code{pkey_alloc} results in undefined behavior. This
- means that calling this function on systems which do not support memory
- protection keys is undefined.
- The @code{pkey_set} function returns @math{0} on success and @math{-1}
- on failure.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item EINVAL
- The system does not support the access rights restrictions expressed in
- the @var{rights} argument.
- @end table
- @end deftypefun
- @deftypefun int pkey_get (int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Return the access rights of the current thread for memory pages with
- protection key @var{key}. The return value is zero or a combination of
- the @code{PKEY_DISABLE_}* flags; see the @code{pkey_set} function.
- Calling the @code{pkey_get} function with a protection key which was not
- allocated by @code{pkey_alloc} results in undefined behavior. This
- means that calling this function on systems which do not support memory
- protection keys is undefined.
- @end deftypefun
- @node Locking Pages
- @section Locking Pages
- @cindex locking pages
- @cindex memory lock
- @cindex paging
- You can tell the system to associate a particular virtual memory page
- with a real page frame and keep it that way --- i.e., cause the page to
- be paged in if it isn't already and mark it so it will never be paged
- out and consequently will never cause a page fault. This is called
- @dfn{locking} a page.
- The functions in this chapter lock and unlock the calling process'
- pages.
- @menu
- * Why Lock Pages:: Reasons to read this section.
- * Locked Memory Details:: Everything you need to know locked
- memory
- * Page Lock Functions:: Here's how to do it.
- @end menu
- @node Why Lock Pages
- @subsection Why Lock Pages
- Because page faults cause paged out pages to be paged in transparently,
- a process rarely needs to be concerned about locking pages. However,
- there are two reasons people sometimes are:
- @itemize @bullet
- @item
- Speed. A page fault is transparent only insofar as the process is not
- sensitive to how long it takes to do a simple memory access. Time-critical
- processes, especially realtime processes, may not be able to wait or
- may not be able to tolerate variance in execution speed.
- @cindex realtime processing
- @cindex speed of execution
- A process that needs to lock pages for this reason probably also needs
- priority among other processes for use of the CPU. @xref{Priority}.
- In some cases, the programmer knows better than the system's demand
- paging allocator which pages should remain in real memory to optimize
- system performance. In this case, locking pages can help.
- @item
- Privacy. If you keep secrets in virtual memory and that virtual memory
- gets paged out, that increases the chance that the secrets will get out.
- If a passphrase gets written out to disk swap space, for example, it might
- still be there long after virtual and real memory have been wiped clean.
- @end itemize
- Be aware that when you lock a page, that's one fewer page frame that can
- be used to back other virtual memory (by the same or other processes),
- which can mean more page faults, which means the system runs more
- slowly. In fact, if you lock enough memory, some programs may not be
- able to run at all for lack of real memory.
- @node Locked Memory Details
- @subsection Locked Memory Details
- A memory lock is associated with a virtual page, not a real frame. The
- paging rule is: If a frame backs at least one locked page, don't page it
- out.
- Memory locks do not stack. I.e., you can't lock a particular page twice
- so that it has to be unlocked twice before it is truly unlocked. It is
- either locked or it isn't.
- A memory lock persists until the process that owns the memory explicitly
- unlocks it. (But process termination and exec cause the virtual memory
- to cease to exist, which you might say means it isn't locked any more).
- Memory locks are not inherited by child processes. (But note that on a
- modern Unix system, immediately after a fork, the parent's and the
- child's virtual address space are backed by the same real page frames,
- so the child enjoys the parent's locks). @xref{Creating a Process}.
- Because of its ability to impact other processes, only the superuser can
- lock a page. Any process can unlock its own page.
- The system sets limits on the amount of memory a process can have locked
- and the amount of real memory it can have dedicated to it. @xref{Limits
- on Resources}.
- In Linux, locked pages aren't as locked as you might think.
- Two virtual pages that are not shared memory can nonetheless be backed
- by the same real frame. The kernel does this in the name of efficiency
- when it knows both virtual pages contain identical data, and does it
- even if one or both of the virtual pages are locked.
- But when a process modifies one of those pages, the kernel must get it a
- separate frame and fill it with the page's data. This is known as a
- @dfn{copy-on-write page fault}. It takes a small amount of time and in
- a pathological case, getting that frame may require I/O.
- @cindex copy-on-write page fault
- @cindex page fault, copy-on-write
- To make sure this doesn't happen to your program, don't just lock the
- pages. Write to them as well, unless you know you won't write to them
- ever. And to make sure you have pre-allocated frames for your stack,
- enter a scope that declares a C automatic variable larger than the
- maximum stack size you will need, set it to something, then return from
- its scope.
- @node Page Lock Functions
- @subsection Functions To Lock And Unlock Pages
- The symbols in this section are declared in @file{sys/mman.h}. These
- functions are defined by POSIX.1b, but their availability depends on
- your kernel. If your kernel doesn't allow these functions, they exist
- but always fail. They @emph{are} available with a Linux kernel.
- @strong{Portability Note:} POSIX.1b requires that when the @code{mlock}
- and @code{munlock} functions are available, the file @file{unistd.h}
- define the macro @code{_POSIX_MEMLOCK_RANGE} and the file
- @code{limits.h} define the macro @code{PAGESIZE} to be the size of a
- memory page in bytes. It requires that when the @code{mlockall} and
- @code{munlockall} functions are available, the @file{unistd.h} file
- define the macro @code{_POSIX_MEMLOCK}. @Theglibc{} conforms to
- this requirement.
- @deftypefun int mlock (const void *@var{addr}, size_t @var{len})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{mlock} locks a range of the calling process' virtual pages.
- The range of memory starts at address @var{addr} and is @var{len} bytes
- long. Actually, since you must lock whole pages, it is the range of
- pages that include any part of the specified range.
- When the function returns successfully, each of those pages is backed by
- (connected to) a real frame (is resident) and is marked to stay that
- way. This means the function may cause page-ins and have to wait for
- them.
- When the function fails, it does not affect the lock status of any
- pages.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. @code{errno} values
- specific to this function are:
- @table @code
- @item ENOMEM
- @itemize @bullet
- @item
- At least some of the specified address range does not exist in the
- calling process' virtual address space.
- @item
- The locking would cause the process to exceed its locked page limit.
- @end itemize
- @item EPERM
- The calling process is not superuser.
- @item EINVAL
- @var{len} is not positive.
- @item ENOSYS
- The kernel does not provide @code{mlock} capability.
- @end table
- @end deftypefun
- @deftypefun int mlock2 (const void *@var{addr}, size_t @var{len}, unsigned int @var{flags})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This function is similar to @code{mlock}. If @var{flags} is zero, a
- call to @code{mlock2} behaves exactly as the equivalent call to @code{mlock}.
- The @var{flags} argument must be a combination of zero or more of the
- following flags:
- @vtable @code
- @item MLOCK_ONFAULT
- @standards{Linux, sys/mman.h}
- Only those pages in the specified address range which are already in
- memory are locked immediately. Additional pages in the range are
- automatically locked in case of a page fault and allocation of memory.
- @end vtable
- Like @code{mlock}, @code{mlock2} returns zero on success and @code{-1}
- on failure, setting @code{errno} accordingly. Additional @code{errno}
- values defined for @code{mlock2} are:
- @table @code
- @item EINVAL
- The specified (non-zero) @var{flags} argument is not supported by this
- system.
- @end table
- @end deftypefun
- You can lock @emph{all} a process' memory with @code{mlockall}. You
- unlock memory with @code{munlock} or @code{munlockall}.
- To avoid all page faults in a C program, you have to use
- @code{mlockall}, because some of the memory a program uses is hidden
- from the C code, e.g. the stack and automatic variables, and you
- wouldn't know what address to tell @code{mlock}.
- @deftypefun int munlock (const void *@var{addr}, size_t @var{len})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{munlock} unlocks a range of the calling process' virtual pages.
- @code{munlock} is the inverse of @code{mlock} and functions completely
- analogously to @code{mlock}, except that there is no @code{EPERM}
- failure.
- @end deftypefun
- @deftypefun int mlockall (int @var{flags})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{mlockall} locks all the pages in a process' virtual memory address
- space, and/or any that are added to it in the future. This includes the
- pages of the code, data and stack segment, as well as shared libraries,
- user space kernel data, shared memory, and memory mapped files.
- @var{flags} is a string of single bit flags represented by the following
- macros. They tell @code{mlockall} which of its functions you want. All
- other bits must be zero.
- @vtable @code
- @item MCL_CURRENT
- Lock all pages which currently exist in the calling process' virtual
- address space.
- @item MCL_FUTURE
- Set a mode such that any pages added to the process' virtual address
- space in the future will be locked from birth. This mode does not
- affect future address spaces owned by the same process so exec, which
- replaces a process' address space, wipes out @code{MCL_FUTURE}.
- @xref{Executing a File}.
- @end vtable
- When the function returns successfully, and you specified
- @code{MCL_CURRENT}, all of the process' pages are backed by (connected
- to) real frames (they are resident) and are marked to stay that way.
- This means the function may cause page-ins and have to wait for them.
- When the process is in @code{MCL_FUTURE} mode because it successfully
- executed this function and specified @code{MCL_CURRENT}, any system call
- by the process that requires space be added to its virtual address space
- fails with @code{errno} = @code{ENOMEM} if locking the additional space
- would cause the process to exceed its locked page limit. In the case
- that the address space addition that can't be accommodated is stack
- expansion, the stack expansion fails and the kernel sends a
- @code{SIGSEGV} signal to the process.
- When the function fails, it does not affect the lock status of any pages
- or the future locking mode.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. @code{errno} values
- specific to this function are:
- @table @code
- @item ENOMEM
- @itemize @bullet
- @item
- At least some of the specified address range does not exist in the
- calling process' virtual address space.
- @item
- The locking would cause the process to exceed its locked page limit.
- @end itemize
- @item EPERM
- The calling process is not superuser.
- @item EINVAL
- Undefined bits in @var{flags} are not zero.
- @item ENOSYS
- The kernel does not provide @code{mlockall} capability.
- @end table
- You can lock just specific pages with @code{mlock}. You unlock pages
- with @code{munlockall} and @code{munlock}.
- @end deftypefun
- @deftypefun int munlockall (void)
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{munlockall} unlocks every page in the calling process' virtual
- address space and turns off @code{MCL_FUTURE} future locking mode.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. The only way this
- function can fail is for generic reasons that all functions and system
- calls can fail, so there are no specific @code{errno} values.
- @end deftypefun
- @ignore
- @c This was never actually implemented. -zw
- @node Relocating Allocator
- @section Relocating Allocator
- @cindex relocating memory allocator
- Any system of dynamic memory allocation has overhead: the amount of
- space it uses is more than the amount the program asks for. The
- @dfn{relocating memory allocator} achieves very low overhead by moving
- blocks in memory as necessary, on its own initiative.
- @c @menu
- @c * Relocator Concepts:: How to understand relocating allocation.
- @c * Using Relocator:: Functions for relocating allocation.
- @c @end menu
- @node Relocator Concepts
- @subsection Concepts of Relocating Allocation
- @ifinfo
- The @dfn{relocating memory allocator} achieves very low overhead by
- moving blocks in memory as necessary, on its own initiative.
- @end ifinfo
- When you allocate a block with @code{malloc}, the address of the block
- never changes unless you use @code{realloc} to change its size. Thus,
- you can safely store the address in various places, temporarily or
- permanently, as you like. This is not safe when you use the relocating
- memory allocator, because any and all relocatable blocks can move
- whenever you allocate memory in any fashion. Even calling @code{malloc}
- or @code{realloc} can move the relocatable blocks.
- @cindex handle
- For each relocatable block, you must make a @dfn{handle}---a pointer
- object in memory, designated to store the address of that block. The
- relocating allocator knows where each block's handle is, and updates the
- address stored there whenever it moves the block, so that the handle
- always points to the block. Each time you access the contents of the
- block, you should fetch its address anew from the handle.
- To call any of the relocating allocator functions from a signal handler
- is almost certainly incorrect, because the signal could happen at any
- time and relocate all the blocks. The only way to make this safe is to
- block the signal around any access to the contents of any relocatable
- block---not a convenient mode of operation. @xref{Nonreentrancy}.
- @node Using Relocator
- @subsection Allocating and Freeing Relocatable Blocks
- @pindex malloc.h
- In the descriptions below, @var{handleptr} designates the address of the
- handle. All the functions are declared in @file{malloc.h}; all are GNU
- extensions.
- @comment malloc.h
- @comment GNU
- @c @deftypefun {void *} r_alloc (void **@var{handleptr}, size_t @var{size})
- This function allocates a relocatable block of size @var{size}. It
- stores the block's address in @code{*@var{handleptr}} and returns
- a non-null pointer to indicate success.
- If @code{r_alloc} can't get the space needed, it stores a null pointer
- in @code{*@var{handleptr}}, and returns a null pointer.
- @end deftypefun
- @comment malloc.h
- @comment GNU
- @c @deftypefun void r_alloc_free (void **@var{handleptr})
- This function is the way to free a relocatable block. It frees the
- block that @code{*@var{handleptr}} points to, and stores a null pointer
- in @code{*@var{handleptr}} to show it doesn't point to an allocated
- block any more.
- @end deftypefun
- @comment malloc.h
- @comment GNU
- @c @deftypefun {void *} r_re_alloc (void **@var{handleptr}, size_t @var{size})
- The function @code{r_re_alloc} adjusts the size of the block that
- @code{*@var{handleptr}} points to, making it @var{size} bytes long. It
- stores the address of the resized block in @code{*@var{handleptr}} and
- returns a non-null pointer to indicate success.
- If enough memory is not available, this function returns a null pointer
- and does not modify @code{*@var{handleptr}}.
- @end deftypefun
- @end ignore
- @ignore
- @comment No longer available...
- @comment @node Memory Warnings
- @comment @section Memory Usage Warnings
- @comment @cindex memory usage warnings
- @comment @cindex warnings of memory almost full
- @pindex malloc.c
- You can ask for warnings as the program approaches running out of memory
- space, by calling @code{memory_warnings}. This tells @code{malloc} to
- check memory usage every time it asks for more memory from the operating
- system. This is a GNU extension declared in @file{malloc.h}.
- @comment malloc.h
- @comment GNU
- @comment @deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *))
- Call this function to request warnings for nearing exhaustion of virtual
- memory.
- The argument @var{start} says where data space begins, in memory. The
- allocator compares this against the last address used and against the
- limit of data space, to determine the fraction of available memory in
- use. If you supply zero for @var{start}, then a default value is used
- which is right in most circumstances.
- For @var{warn-func}, supply a function that @code{malloc} can call to
- warn you. It is called with a string (a warning message) as argument.
- Normally it ought to display the string for the user to read.
- @end deftypefun
- The warnings come when memory becomes 75% full, when it becomes 85%
- full, and when it becomes 95% full. Above 95% you get another warning
- each time memory usage increases.
- @end ignore
|