diff -r 159c7e7ca171 sys/man/9/0intro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/0intro Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,53 @@ +.TH INTRO 9 +.SH NAME +intro \- introduction to kernel functions +.SH DESCRIPTION +This section of the manual +describes the functions publicly available to the authors of +kernel code, particularly device drivers (real and virtual). +This section will eventually be much expanded, but this makes a start. +.PP +The +.SM SYNOPSIS +subsections do not show the header files needed for +the standard kernel declarations. +The primary combinations summarised below: +.IP +.RS +.ta \w'\fL#include 'u +.nf +.B +#include "u.h" +.B +#include "../port/lib.h" +.B +#include "mem.h" +.B +#include "dat.h" +.B +#include "fns.h" +.B +#include "../port/error.h" +.PP +.I "furthermore, added in IP code:" +.br +.B +#include "../ip/ip.h" +.PP +.I "furthermore, in hardware device drivers:" +.br +.B +#include "io.h" +.br +.B +#include "ureg.h" +.PP +.I "furthermore, in network interfaces or ether drivers:" +.B +#include "../port/netif.h" +.fi +.RE +.PP +There might also be specific include files needed by +drivers on particular platforms or to use specialised kernel interfaces. +The easiest method is to check the source of likely-looking drivers nearby. diff -r 159c7e7ca171 sys/man/9/allocb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/allocb Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,343 @@ +.TH ALLOCB 9 +.SH NAME +allocb, iallocb, freeb, freeblist, BLEN, BALLOC, blocklen, blockalloclen, readblist, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb \- data block management +.SH SYNOPSIS +.ta \w'\fLBlock* 'u +.B +Block* allocb(int size) +.PP +.B +Block* iallocb(int size) +.PP +.B +void freeb(Block *b) +.PP +.B +void freeblist(Block *b) +.PP +.B +int blocklen(Block *b) +.PP +.B +int blockalloclen(Block *b) +.PP +.B +long readblist(Block *b, uchar *p, long n, ulong offset) +.PP +.B +Block* concatblock(Block *b) +.PP +.B +Block* copyblock(Block *b, int n) +.PP +.B +Block* trimblock(Block *b, int offset, int n) +.PP +.B +Block* packblock(Block *b) +.PP +.B +Block* padblock(Block *b, int n) +.PP +.B +int pullblock(Block **bph, int n) +.PP +.B +Block* pullupblock(Block *b, int n) +.PP +.B +Block* adjustblock(Block *b, int n) +.PP +.B +void checkb(Block *b, char *msg) +.sp 0.1 +.PP +.B +#define BLEN(s) ((s)->wp - (s)->rp) +.PP +.B +#define BALLOC(s) ((s)->lim - (s)->base) +.SH DESCRIPTION +A +.B Block +provides a receptacle for data: +.IP +.EX +.DT +typedef +struct Block +{ + Block* next; + Block* list; + uchar* rp; /* first unconsumed byte */ + uchar* wp; /* first empty byte */ + uchar* lim; /* 1 past the end of the buffer */ + uchar* base; /* start of the buffer */ + void (*free)(Block*); + ushort flag; + ushort checksum; /* IP checksum of complete packet */ +} Block; +.EE +.PP +Each +.B Block +has an associated buffer, located at +.BR base , +and accessed via +.B wp +when filling the buffer, or +.B rp +when fetching data from it. +Each pointer should be incremented to reflect the amount of data written or read. +A +.B Block +is empty when +.B rp +reaches +.BR wp . +The pointer +.B lim +bounds the allocated space. +Some operations described below accept lists of +.BR Block s, +which are +chained via their +.B next +pointers, with a null pointer ending the list. +.B Blocks +are usually intended for a +.B Queue +(see +.IR qio (9)), +but can be used independently. +.PP +A +.B Block +and its buffer are normally allocated by one call to +.IR malloc (9) +and aligned on an 8 byte (\fLBY2V\fP) boundary. +Some devices with particular allocation constraints +(eg, requiring certain addresses for DMA) might allocate their own +.B Block +and buffer; +.B free +must then point to a function that can deallocate the specially allocated +.BR Block . +.PP +Many +.B Block +operations cannot be used in interrupt handlers +because they either +.IR sleep (9) +or raise an +.IR error (9). +Of operations that allocate blocks, only +.IR iallocb +is usable. +.PP +.I Allocb +allocates a +.B Block +of at least +.IR size +bytes. +The block +is initially empty: +.B rp +and +.B wp +point to the start of the data. +If it cannot allocate memory, +.I allocb +raises an +.IR error (9); +it cannot be used by an interrupt handler. +.PP +.IR Iallocb +is similar to +.IR allocb +but is intended for use by interrupt handlers, +and returns a null pointer if no memory is available. +It also limits its allocation to a quota allocated at system initialisation to interrupt-time buffering. +.PP +.I Freeb +frees a single +.B Block +(and its buffer). +.PP +.I Freeblist +frees the whole +list of blocks headed by +.IR b . +.PP +.I BLEN +returns the number of unread bytes in a single block. +.PP +.I BALLOC +returns the number of allocated bytes in a single block. +.PP +.I Blocklen +returns the number of bytes of unread data in the whole list of blocks headed by +.IR b . +.PP +.I Blockalloclen +returns the number of total bytes allocated in the whole list of blocks headed by +.IR b . +.PP +.I Readblist +copies +.I n +bytes of data at offset +.I offset +from the list of blocks headed by +.I b +into +.IR p , +then returns the amount of bytes copied. It leaves the block list intact. +.PP +.I Concatblock +returns +.I b +if it is not a list, and otherwise +returns a single +.B Block +containing all the data in the list of blocks +.IR b , +which it frees. +.PP +.I Copyblock +by contrast returns a single +.B Block +containing a copy of the first +.I n +bytes of data in the block list +.IR b , +padding with zeroes if the list contained less than +.I n +bytes. +The list +.I b +is unchanged. +.PP +.I Padblock +can pad a single +.B Block +at either end, to reserve space for protocol headers or trailers. +If +.IR n ≥ 0 , +it inserts +.I n +bytes at the start of the block, +setting the read pointer +.B rp +to point to the new space. +If +.IR n < 0 , +it adds +.I n +bytes at the end of the block, +leaving the write pointer +.B wp +pointing at the new space. +In both cases, it allocates a new +.B Block +if necessary, freeing the old, and +it always returns a pointer to the resulting +.BR Block . +.PP +.I Trimblock +trims the list +.I b +to contain no more than +.I n +bytes starting at +.I offset +bytes into the data of the original list. +It returns a new list, freeing unneeded parts of the old. +If no data remains, it returns a null pointer. +.PP +.I Packblock +examines each +.B Block +in the list +.IR b , +reallocating any block in the list that has four times more available space than actual data. +It returns a pointer to the revised list. +.PP +.I Pullblock +discards up to +.I n +bytes from the start of the list headed by +.BI * bph \f1.\f0 +Unneeded blocks are freed. +.I Pullblock +sets +.BI * bph +to point to the new list head +and returns the number of bytes discarded (which might be less than +.IR n ). +It is used by transport protocols to discard ack'd data at +the head of a retransmission queue. +.PP +.I Pullupblock +rearranges the data in the list of blocks +.I b +to ensure that there are at least +.I n +bytes of contiguous data in the first block, +and returns a pointer to the new list head. +It frees any blocks that it empties. +It returns a null pointer if there is not enough data in the list. +.PP +.I Adjustblock +ensures that the block +.I b +has at least +.I n +bytes of data, reallocating or padding with zero if necessary. +It returns a pointer to the new +.BR Block . +(If +.I n +is negative, it frees the block and returns a null pointer.) +.PP +.I Checkb +does some consistency checking of +the state of +.IR b ; +a +.IR panic (9) +results if things look grim. +It is intended for internal use by the queue I/O routines (see +.IR qio (9)) +but could be used elsewhere. +.PP +The only functions that can be called at interrupt level are +.IR iallocb , +.IR freeb , +.IR freeblist , +.IR BLEN , +.IR BALLOC , +.IR blocklen , +.IR blockalloclen , +.IR readblist +and +.IR trimblock . +The others allocate memory and can potentially block. +.SH SOURCE +.B /sys/src/9/port/allocb.c +.br +.B /sys/src/9/port/qio.c +.SH DIAGNOSTICS +Many functions directly or indirectly can raise an +.IR error (9), +and callers must therefore provide for proper error recovery +as described therein to prevent memory leaks and other bugs. +Except for +.IR iallocb , +any functions that allocate new blocks or lists +are unsuitable for use by interrupt handlers. +.IR Iallocb +returns a null pointer when it runs out of memory. +.SH SEE ALSO +.IR qio (9) diff -r 159c7e7ca171 sys/man/9/delay --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/delay Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,46 @@ +.TH DELAY 9 +.SH NAME +delay, microdelay, addclock0link \- small delays, clock interrupts +.SH SYNOPSIS +.ta \w'\fLTimer* 'u +.B +void delay(int ms) +.PP +.B +void microdelay(int µs) +.PP +.B +Timer* addclock0link(void(*clockf)(void), int ms) +.SH DESCRIPTION +.I Delay +busy waits for +.I ms +milliseconds, forced to be at least one millisecond on some architectures. +.PP +.I Microdelay +works exactly the same as +.I delay +but using microseconds instead. +.PP +For delays on the order of clock ticks, +.I tsleep +(see +.IR sleep (9)) +provides a better alternative to the busy waiting of these routines. +.PP +.I Addclock0link +adds a new periodic timer to the current processor's timer list, with +.I clockf +executing every +.I ms +milliseconds. If +.I ms +is zero a default clock is used, it will panic otherwise (i.e. +.I ms +< 0). +.SH SOURCE +.B /sys/src/9/port/portclock.c +.br +.B /sys/src/9/*/clock.c +.SH SEE ALSO +.IR sleep (9) diff -r 159c7e7ca171 sys/man/9/error --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/error Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,171 @@ +.TH ERROR 9 +.SH NAME +error, nexterror, poperror, waserror \- error handling functions +.SH SYNOPSIS +.ta \w'\fL#define 'u +.B +void error(char*) +.PP +.B +void nexterror(void) +.sp 0.1 +.PP +.B +#define poperror() (up->nerrlab--) +.PP +.B +#define waserror() (setlabel(&up->errlab[up->nerrlab++])) +.SH DESCRIPTION +The kernel handles error conditions using non-local gotos, +similar to +.IR setjmp (2), +but using a stack of error labels to implement nested exception handling. +This simplifies many of the internal interfaces by eliminating the need +for returning and checking error codes at every level of the call stack, +at the cost of requiring kernel routines to adhere to a strict discipline. +.PP +Each process has in its defining kernel +.B Proc +structure a stack of labels, +.B NERR +(currently 64) elements deep. +A kernel function that must perform a clean up or recovery action on an error +makes a stylised call to +.IR waserror , +.IR nexterror +and +.IR poperror : +.IP +.EX +.DT +if(waserror()){ + /* recovery action */ + nexterror(); +} +/* normal action */ +poperror(); +.EE +.PP +When called in the normal course of events, +.I waserror +registers an error handling block by pushing its label onto the stack, +and returns zero. +The return value of +.I waserror +should be tested as shown above. +If non-zero (true), the calling function should perform the needed +error recovery, ended by a call to +.I nexterror +to transfer control to the next location on the error stack. +Typical recovery actions include deallocating memory, unlocking resources, and +resetting state variables. +.PP +Within the recovery block, +after handling an error condition, there must normally +be a call to +.I nexterror +to transfer control to any error recovery lower down in the stack. +The main exception is in the outermost function in a process, +which must not call +.I nexterror +(there being nothing further on the stack), but calls +.I pexit +(see +.IR kproc (9)) +instead, +to terminate the process. +.PP +When the need to recover a particular resource has passed, +a function that has called +.I waserror +must +remove the corresponding label from the stack by calling +.IR poperror . +This +must +be done before returning from the function; otherwise, a subsequent call to +.I error +will return to an obsolete activation record, with unpredictable but unpleasant consequences. +.PP +.I Error +copies the given error message, which is limited to +.B ERRMAX +bytes, into the +.B Proc.errstr +of the current process, +enables interrupts by calling +.I spllo +.RI ( native +only), +and finally calls +.I nexterror +to start invoking the recovery procedures currently stacked by +.IR waserror . +The file +.B /sys/src/9/port/error.h +offers a wide selection of predefined error messages, suitable for almost any occasion. +The message set by the most recent call to +.I error +can be obtained within the kernel by examining +.B up->error +and in an application, by using the +.L %r +directive of +.IR print (2). +.PP +A complex function can have nested error handlers. +A +.I waserror +block will follow the acquisition of a resource, releasing it +on error before calling +.I nexterror, +and a +.I poperror +will precede its release in the normal case. +For example: +.IP +.EX +.DT +void +outer(Thing *t) +{ + qlock(t); + if(waserror()){ /* A */ + qunlock(t); + nexterror(); + } + m = mallocz(READSTR, 0); + if(m == nil) + error(Enomem); /* returns to A */ + if(waserror()){ /* B */ + free(m); + nexterror(); /* invokes A */ + } + inner(t); + poperror(); /* pops B */ + free(m); + poperror(); /* pops A */ + qunlock(t); +} +.sp 1v +void +inner(Thing *t) +{ + if(t->bad) + error(Egreg); /* returns to B */ + t->valid++; +} +.EE +.SH SOURCE +.B /sys/src/9/port/proc.c +.SH CAVEATS +The description above has many instances of +.IR should , +.IR will , +.I must +and +.IR "must not" . +.SH SEE ALSO +.IR panic (9), +.IR kproc (9), +.IR splhi (9) diff -r 159c7e7ca171 sys/man/9/eve --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/eve Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,46 @@ +.TH EVE 9 +.SH NAME +eve, iseve \- privileged user +.SH SYNOPSIS +.ta \w'\fLchar* 'u +.B +char *eve; +.PP +.B +int iseve(void) +.SH DESCRIPTION +.I Eve +is a null-terminated string containing the name of the owner of +the Plan 9 system (sometimes called the `host owner', +see +.IR cons (3)). +The identity is set on a terminal to the name of the user who logs in. +It is set on a CPU server to the +.I authid +obtained either from NVRAM or by a console prompt. +The initial process created by system initialisation is given the +.I eve +identity. +.PP +.I Iseve +returns true if the current user is +.IR eve . +Several drivers use +.I iseve +to check the caller's identity +before granting permission to perform certain actions. +For example, the console driver allows only the user +.I eve +to write a new identity into the +.B /dev/user +file. +The privileges are strictly local and do not extend into the network +(in particular, to file servers—even ones running on the local machine). +.SH SOURCE +.B /sys/src/9/port/auth.c +.SH SEE ALSO +.IR auth (2), +.IR cap (3), +.IR cons (3), +.IR authsrv (6), +.IR auth (8) diff -r 159c7e7ca171 sys/man/9/intrenable --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/intrenable Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,106 @@ +.TH INTRENABLE 9 +.SH NAME +intrenable, intrdisable \- enable (disable) an interrupt handler +.SH SYNOPSIS +.ta \w'\fLvoid* 'u +.B +void intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) +.PP +.B +void intrdisable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) +.SH DESCRIPTION +.I Intrenable +registers +.I f +to be called by the kernel's interrupt controller driver each time +an interrupt denoted by +.I v +occurs, and unmasks the corresponding interrupt in the interrupt controller. +The encoding of +.I v +is platform-dependent; it is often an interrupt vector number, but +can be more complex. +.I Tbdf +is a platform-dependent value that might further qualify +.IR v . +It might for instance +denote the type of bus, bus instance, device number and function +(following the PCI device indexing scheme), hence its name, +but can have platform-dependent meaning. +.I Name +is a string that should uniquely identify the corresponding device (eg, \f5"uart0"\fP); +again it is usually platform-dependent. +.I Intrenable +supports sharing of interrupt levels when the hardware does. +.PP +Almost invariably +.I f +is a function defined in a device driver to carry out the device-specific work associated with a given interrupt. +The pointer +.I a +is passed to +.IR f ; +typically it points to the driver's data for a given device or controller. +It also passes +.I f +a +.B Ureg* +value that +contains the registers saved by the interrupt handler (the +contents are platform specific; +see the platform's include file +.BR "ureg.h" ). +.PP +.I F +is invoked by underlying code in the kernel that is invoked directly from the hardware vectors. +It is therefore not running in any process (see +.IR kproc (9); +indeed, on many platforms +the current process pointer +.RB ( up ) +will be nil. +There are many restrictions on kernel functions running outside a process, but a fundamental one is that +they must not +.IR sleep (9), +although they often call +.B wakeup +to signal the occurrence of an event associated with the interrupt. +.IR Qio (9) +and other manual pages note which functions are safe for +.I f +to call. +.PP +The interrupt controller driver does whatever is +required to acknowledge or dismiss the interrupt signal in the interrupt controller, +before calling +.IR f , +for edge-triggered interrupts, +and after calling +.I f +for level-triggered ones. +.I F +is responsible for dealing with the cause of the interrupt in the device, including any +acknowledgement required in the device, before it returns. +.PP +.I Intrdisable +removes any registration previously made by +.I intrenable +with matching parameters, and if no other +interrupt is active on +.IR v , +it masks the interrupt in the controller. +Device drivers that are not dynamically configured tend to call +.I intrenable +during reset or initialisation (see +.IR dev (9)), +but can call it at any appropriate time, and +instead of calling +.I intrdisable +they can simply enable or disable interrupts in the device as required. +.SH SOURCE +.B /sys/src/9/*/trap.c +.SH SEE ALSO +.IR malloc (9), +.IR qio (9), +.IR sleep (9), +.IR splhi (9) diff -r 159c7e7ca171 sys/man/9/kproc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/kproc Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,134 @@ +.TH KPROC 9 +.SH NAME +kproc, pexit, postnote \- kernel process creation, termination and interruption +.SH SYNOPSIS +.ta \w'\fLvoid 'u +.B +void kproc(char *name, void (*func)(void*), void *arg) +.PP +.B +void pexit(char *note, int freemem) +.PP +.B +int postnote(Proc *p, int dolock, char *n, int flag) +.SH DESCRIPTION +.I Kproc +creates a new kernel process +to run the function +.IR func , +which is invoked as +.BR "(*func)(arg)" . +The string +.I name +is copied into the +.B text +field of the +.B Proc +structure of the new process; this value is the name of the kproc in +the output of +.IR ps (1). +The process is made runnable; it +will run when selected by the scheduler +.IR sched (9). +The process is created with base and current priorities set to +.BR PriKproc . +It shares the kernel process group and thus name space. +.PP +A kernel process terminates only when it calls +.IR pexit , +thereby terminating itself. +There is no mechanism for one process to force the termination of another, +although it can send a software interrupt using +.IR postnote . +.I Note +is a null string on normal termination, or +the cause of +If +.I freemem +is non-zero, +any memory allocated by the process is discarded; +it should normally be non-zero for any process created +by +.IR kproc . +Use the following to terminate a kernel process normally: +.IP +.EX +pexit("", 1); +.EE +.PP +to terminate a kernel process normally. +.PP +.I Postnote +sends a software interrupt to process +.IR p , +causing it, if necessary, to wake from +.IR sleep (9) +or break out of a +.IR rendezvous (2) +or an +.IR eqlock(9), +with an +.IR error (9) +`interrupted'. +Up to +.B NNOTE +notes can be pending at once (currently 5); +if more than that arrive, the process is forced +out of +.IR sleep , +.I rendezvous +and +.IR eqlock , +but the message itself is discarded. +.I Postnote +returns non-zero iff the note has been +delivered successfully. +If +.I dolock +is non-zero, +.I postnote +synchronises delivery of the note with the debugger +and other operations of +.IR proc (3). +.I Flag +is zero, or one of the following +.TP +.B NDebug +Print the note message on the user's standard error. +Furthermore, suspend the process in a +.B Broken +state, preserving its memory, for later debugging. +.TP +.B NExit +Deliver the note quietly. +.TP +.B NUser +The note comes from another process, not the system. +.PP +The kernel uses +.I postnote +to signal processes that commit grave faults, +and to implement the note and kill functions of +.IR proc (3). +A device driver should use +.I postnote +only to tell a service process, +previously started by the driver using +.I kproc , +that it should stop; +the note will cause that process to raise an +.IR error (9). +For example, a process started to read packets from a network device could +be stopped as follows when the interface is unbound: +.IP +.EX +postnote(readp, 1, "unbind", 0); +.EE +.PP +where +.I readp +points to the appropriate +.BR Proc . +The text of the message is typically irrelevant. +.SH SOURCE +.B /sys/src/9/port/proc.c diff -r 159c7e7ca171 sys/man/9/malloc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/malloc Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,187 @@ +.TH MALLOC 9 +.SH NAME +malloc, mallocz, smalloc, realloc, free, msize, secalloc, secfree, setmalloctag, setrealloctag, getmalloctag, getrealloctag \- kernel memory allocator +.SH SYNOPSIS +.ta \w'\fLvoid* 'u +.B +void* malloc(ulong size) +.PP +.B +void* mallocalign(ulong size, ulong align, long offset, ulong span) +.PP +.B +void* mallocz(ulong size, int clr) +.PP +.B +void* smalloc(ulong size) +.PP +.B +void* realloc(void *p, ulong size) +.PP +.B +void free(void *ptr) +.PP +.B +ulong msize(void *ptr) +.PP +.B +void* secalloc(ulong size) +.PP +.B +void secfree(void *ptr) +.PP +.B +void setmalloctag(void *ptr, ulong tag) +.PP +.B +ulong getmalloctag(void *ptr) +.PP +.B +void setrealloctag(void *ptr, ulong tag) +.PP +.B +ulong getrealloctag(void *ptr) +.PP +.SH DESCRIPTION +These are kernel versions of the functions in +.IR malloc (2). +They allocate memory from the +.B mainmem +memory pool, +which is managed by +the allocator +.IR pool (2), +which in turn replenishes the pool as required by calling +.IR xalloc (9). +All but +.I smalloc +(which calls +.IR sleep (9)) +may safely be called by interrupt handlers. +.PP +.I Malloc +returns a pointer to a block of at least +.I size +bytes, initialised to zero. +The block is suitably aligned for storage of any type of object. +The call +.B malloc(0) +returns a valid pointer rather than null. +.I Mallocz +is similar, but only clears the memory if +.I clr +is non-zero. +.PP +.I Smalloc +returns a pointer to a block of +.I size +bytes, initialised to zero. +If the memory is not immediately available, +.I smalloc +retries every 100 milliseconds until the memory is acquired. +.PP +.I Mallocalign +allocates a block of at least +.I n +bytes of memory respecting alignment contraints. +If +.I align +is non-zero, +the returned pointer is aligned to be equal to +.I offset +modulo +.IR align . +If +.I span +is non-zero, +the +.I n +byte block allocated will not span a +.IR span -byte +boundary. +.PP +.I Realloc +changes the size of the block pointed to by +.I p +to +.I size +bytes, +if possible without moving the data, +and returns a pointer to the block. +The contents are unchanged up to the lesser of old and new sizes, +and any new space allocated is initialised to zero. +.I Realloc +takes on special meanings when one or both arguments are zero: +.TP +.B "realloc(0,\ size) +means +.LR malloc(size) ; +returns a pointer to the newly-allocated memory +.TP +.B "realloc(ptr,\ 0) +means +.LR free(ptr) ; +returns null +.TP +.B "realloc(0,\ 0) +no-op; returns null +.PD +.PP +The argument to +.I free +is a pointer to a block of memory allocated by one of the routines above, which +is returned to the allocation pool, or a null pointer, which is ignored. +.PP +When a block is allocated, sometimes there is some extra unused space at the end. +.I Msize +grows the block to encompass this unused space and returns the new number +of bytes that may be used. +.PP +.I Secalloc +and +.I secfree +are security-aware functions that use a pool flagged by +.B POOL_ANTAGONISM +(see +.IR pool (2)), +which fills every allocated block with garbage before and after its +use, to prevent leakage. +.PP +The memory allocator maintains two word-sized fields +associated with each block, the ``malloc tag'' and the ``realloc tag''. +By convention, the malloc tag is the PC that allocated the block, +and the realloc tag the PC that last reallocated the block. +These may be set or examined with +.IR setmalloctag , +.IR getmalloctag , +.IR setrealloctag , +and +.IR getrealloctag . +When allocating blocks directly with +.I malloc +and +.IR realloc , +these tags will be set properly. +If a custom allocator wrapper is used, +the allocator wrapper can set the tags +itself (usually by passing the result of +.IR getcallerpc (2) +to +.IR setmalloctag ) +to provide more useful information about +the source of allocation. +.SH SOURCE +.B /sys/src/9/port/alloc.c +.SH DIAGNOSTICS +All functions except +.I smalloc +return a null pointer if space is unavailable. +If the allocated blocks have no malloc or realloc tags, +.I getmalloctag +and +.I getrealloctag +return +.BR ~0 . +.SH SEE ALSO +.IR pool (2), +.IR xalloc (9) diff -r 159c7e7ca171 sys/man/9/panic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/panic Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,25 @@ +.TH PANIC 9 +.SH NAME +panic \- abandon hope, all ye who enter here +.SH SYNOPSIS +.ta \w'\fLvoid 'u +.B +void panic(char *fmt, ...) +.SH DESCRIPTION +.I Panic +writes a message to the console and +causes the system to give up the host. +It enables interrupts, dumps the kernel stack, +and halts the current processor; +if more than one, others will gradually come to a halt. +Depending on configuration settings, the platform-dependent +.I exit +might reboot the system. +The format +.I fmt +and associated arguments are the same as those for +.IR print (9). +.I Panic +adds a prefix +.L "panic: " +and a trailing newline. diff -r 159c7e7ca171 sys/man/9/qlock --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/qlock Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,138 @@ +.TH QLOCK 9 +.SH NAME +qlock, qunlock, canqlock, rlock, runlock, wlock, wunlock \- serial synchronisation +.SH SYNOPSIS +.de PB +.PP +.ft L +.nf +.. +.PB +typedef struct +{ + Lock use; /* to access Qlock structure */ + Proc *head; /* next process waiting for object */ + Proc *tail; /* last process waiting for object */ + int locked; /* flag */ +} QLock; +.PB +typedef struct +{ + Lock use; + Proc *head; /* list of waiting processes */ + Proc *tail; + uintptr wpc; /* pc of writer */ + Proc *wproc; /* writing proc */ + int readers; /* number of readers */ + int writer; /* number of writers */ +} RWlock; +.ta \w'\fLvoid 'u +.PP +.B +void eqlock(QLock *l) +.PP +.B +void qlock(QLock *l) +.PP +.B +void qunlock(QLock *l) +.PP +.B +int canqlock(QLock *l) +.PP +.B +void rlock(RWlock *l) +.PP +.B +void runlock(RWlock *l) +.PP +.B +int canrlock(RWlock *l) +.PP +.B +void wlock(RWlock *l) +.PP +.B +void wunlock(RWlock *l) +.SH DESCRIPTION +The primitive locking functions described in +.IR lock (9) +guarantee mutual exclusion, but they implement spin locks, +and should not be used if the process might +.IR sleep (9) +within a critical section. +The following functions serialise access to a resource by forming an orderly +queue of processes. +.PP +Each resource to be controlled is given an associated +.B QLock +structure; it is usually most straightforward to put the +.B QLock +in the structure that represents the resource. +It must be initialised to zero before use +(as guaranteed for global variables and for structures allocated by +.IR malloc ). +.PP +On return from +.IR qlock , +the process has acquired the lock +.IR l , +and can assume exclusive access to the associated resource. +If the lock is not immediately available, the requesting process is placed on a +FIFO queue of processes that have requested the lock. +Processes on this list are blocked in the +.L Queueing +state. +.PP +.I Eqlock +is an interruptible form of +.IR qlock. +.PP +.I Qunlock +unlocks +.I l +and schedules the first process queued for it (if any). +.PP +.I Canqlock +is a non-blocking form of +.IR qlock . +It tries to obtain the lock +.I l +and returns true if successful, and 0 otherwise; +it always returns immediately. +.PP +.B RWlock +is a form of lock for resources that have distinct readers and writers. +It allows concurrent readers but gives each writer exclusive access. +A caller announces its read or write intentions by choice of lock (and unlock) function; +the system assumes the caller will not modify a structure accessed under read lock. +.PP +.I Rlock +acquires +.I l +for reading. +The holder can read but agrees not to modify the resource. +There may be several concurrent readers. +.I Canrlock +is non-blocking: it returns non-zero if it successfully acquired the lock immediately, +and 0 if the resource was unavailable. +.PP +.I Runlock +returns a read lock; +the last reader out enables the first writer waiting (if any). +.PP +.I Wlock +acquires a write lock. +The holder of such a lock may assume exclusive access to the resource, +and is allowed to modify it. +.PP +.I Wunlock +returns a write lock. +The next pending process, whether reader or writer, is scheduled. +.SH SOURCE +.B /sys/src/9/port/qlock.c +.br +.SH SEE ALSO +.IR lock (9), +.IR malloc (9), +.IR splhi (9) diff -r 159c7e7ca171 sys/man/9/sleep --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/sleep Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,125 @@ +.TH SLEEP 9 +.SH NAME +sleep, wakeup, tsleep, return0 \- process synchronisation +.SH SYNOPSIS +.ta \w'\fLvoid 'u +.B +void sleep(Rendez *r, int (*f)(void*), void *arg) +.PP +.B +void wakeup(Rendez *r) +.PP +.B +void tsleep(Rendez *r, int (*f)(void*), void *arg, ulong ms) +.PP +.B +int return0(void *arg) +.PP +.SH DESCRIPTION +A process running in the kernel can use these functions to +synchronise with an interrupt handler or another kernel process. +In particular, they are used by device drivers to wait for an event to be signalled on +receipt of an interrupt. +(In practice, they are most often used indirectly, through +.IR qio (9) +for instance.) +.PP +The caller of +.I sleep +and a caller of +.I wakeup +share a +.B Rendez +structure, to provide a rendezvous point between them +to synchronise on an event. +.I Sleep +uses a condition function +.I f +that returns true if the event has occurred. +.PP +.I Sleep +evaluates +.IB f ( arg ). +If true, the event has happened and +.I sleep +returns immediately. +Otherwise, +.I sleep +blocks on the event variable +.IR r , +awaiting +.IR wakeup . +.PP +.I Wakeup +is called by either a process or an interrupt handler to wake any process +sleeping at +.IR r , +signifying that the corresponding condition is true (the event has occurred). +It has no effect if there is no sleeping process. +.PP +.I Tsleep +is similar to +.IR sleep , +except that if the condition +.IB f ( arg ) +is false and the caller does sleep, +and nothing else wakes it within +.I ms +millliseconds, +the system will wake it. +.IR Tsleep 's +caller must check its environment to decide whether timeout or the event +occurred. +The timing provided by +.I tsleep +is imprecise, but adequate in practice for the normal use of protecting against +lost interrupts and otherwise unresponsive devices or software. +.PP +.I Return0 +ignores its arguments and returns zero. It is commonly used as +the predicate +.I f +in a call to +.I tsleep +to obtain a time delay, using the +.B Rendez +variable +.B sleep +in the +.B Proc +structure, for example: +.IP +.B tsleep(&up->sleep, return0, nil, 10); +.PP +Both +.I sleep +and +.I tsleep +can be interrupted by +.IR swiproc +(see +.IR kproc (9)), +causing a non-local goto through a call to +.IR error (9). +.SH SOURCE +.B /sys/src/9/port/proc.c +.br +.B /sys/src/9/port/sysproc.c +.SH DIAGNOSTICS +There can be at most one process waiting on a +.BR Rendez , +and if two processes collide, the system will +.IR panic (9) +.RB (`` "double sleep" ''). +Access to a +.B Rendez +must therefore be serialised by some other mechanism, usually +.IR qlock (9). +.SH SEE ALSO +.IR lock (9), +.IR qlock (9), +.IR delay (9) +.br +``Process Sleep and Wakeup on a Shared-memory Multiprocessor'', +in +.I "Plan 9 Programmer's Manual: Volume 2". diff -r 159c7e7ca171 sys/man/9/splhi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/splhi Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,56 @@ +.TH SPLHI 9 +.SH NAME +splhi, spllo, splx, islo \- enable and disable interrupts +.SH SYNOPSIS +.ta \w'\fLvoid 'u +.B +int spllo(void) +.PP +.B +int splhi(void) +.PP +.B +void splx(int x) +.PP +.B +int islo(void) +.SH DESCRIPTION +These primitives enable and disable maskable interrupts on the current +processor. +Generally, device drivers should use +.I ilock +(see +.IR lock (9)), +.IR sleep (9), +or the functions in +.IR qio (9) +to control interaction between processes and interrupt handlers. +Those routines (but not these) provide correct synchronisation on multiprocessors. +.PP +.I Spllo +enables interrupts and returns a flag representing the previous interrupt enable state. +It must not normally be called from interrupt level. +.PP +.I Splhi +disables all maskable interrupts and returns the previous interrupt enable state. +The period during which interrupts are disabled had best be short, +or real-time applications will suffer. +.PP +.I Splx +restores the interrupt enable state to +.IR x , +which must be a value returned +by a previous call to +.I splhi +or +.IR spllo . +.PP +.I Islo +returns true (non-zero) if interrupts are currently enabled, and 0 otherwise. +.SH SOURCE +.B /sys/src/9/*/l.s +.SH SEE ALSO +.IR lock (9), +.IR qio (9), +.IR sleep (9), +.IR intrenable (9) diff -r 159c7e7ca171 sys/man/9/xalloc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/man/9/xalloc Tue Nov 19 18:52:53 2019 +0100 @@ -0,0 +1,81 @@ +.TH XALLOC 9 +.SH NAME +xalloc, xallocz, xspanalloc, xfree, xsummary \- basic memory management +.SH SYNOPSIS +.ta \w'\fLvoid* 'u +.B +void* xalloc(ulong size) +.PP +.B +void* xallocz(ulong size, int clr) +.PP +.B +void* xspanalloc(ulong size, int align, ulong span) +.PP +.B +void xfree(void *p) +.PP +.B +void xsummary(void) +.SH DESCRIPTION +These are primitives used by higher-level memory allocators in the kernel, +such as +.IR malloc (9). +They are not intended for use directly by most kernel routines. +The main exceptions are routines that permanently allocate large structures, +or need the special alignment properties guaranteed by +.IR xspanalloc . +.PP +.I Xalloc +returns a pointer to a range of size bytes of memory. The memory will be zero filled and aligned on a 8 byte +.RB ( BY2V ) +address. If the memory is not available, +.B xalloc +returns a null pointer. +.PP +.I Xmallocz +will clear the memory after allocation if +.I clr +is set to a value other than zero. Since it is used by +.IR xmalloc , +the same diagnostics apply. +.PP +.I Xspanalloc +allocates memory given alignment and spanning constraints. +The block returned will contain +.I size +bytes, aligned on a boundary that is +.BI "0 mod" " align," +in such a way that the memory in the block does not +span an address that is +.BI "0 mod" " span." +.I Xspanalloc +is intended for use +allocating hardware data structures (eg, page tables) or I/O buffers +that must satisfy specific alignment restrictions. +If +.I xspanalloc +cannot allocate memory to satisfy the given constraints, it will +.IR panic (9). +The technique it uses can sometimes cause memory to be wasted. +Consequently, +.I xspanalloc +should be used sparingly. +.PP +.I Xfree +frees the block of memory at +.IR p , +which must be an address previously returned by +.I xalloc +(not +.IR xspanalloc ). +.PP +.I Xsummary +dumps memory allocation statistics to the console. +The output includes the total free space, the number of free holes, +and a summary of active holes. +Each line shows `address top size'. +.SH SOURCE +.B /sys/src/9/port/xalloc.c +.SH SEE ALSO +.IR malloc (9)