add start of section 9 manpages (thanks rgl)

this change adds some of the kernel manpages from 9legacy,
fixed and updated to match the changes in 9front.
This commit is contained in:
Ori Bernstein 2019-11-19 12:30:40 -08:00
parent 37d6ddd8f3
commit 0b6f0c70db
15 changed files with 1639 additions and 0 deletions

53
sys/man/9/0intro Normal file
View file

@ -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.

67
sys/man/9/INDEX Normal file
View file

@ -0,0 +1,67 @@
0intro 0intro
intro 0intro
BALLOC allocb
BLEN allocb
adjustblock allocb
allocb allocb
blockalloclen allocb
blocklen allocb
checkb allocb
concatblock allocb
copyblock allocb
freeb allocb
freeblist allocb
iallocb allocb
packblock allocb
padblock allocb
pullblock allocb
pullupblock allocb
readblist allocb
trimblock allocb
addclock0link delay
delay delay
microdelay delay
error error
nexterror error
poperror error
waserror error
eve eve
iseve eve
intrdisable intrenable
intrenable intrenable
kproc kproc
pexit kproc
postnote kproc
free malloc
getmalloctag malloc
getrealloctag malloc
malloc malloc
mallocz malloc
msize malloc
realloc malloc
secalloc malloc
secfree malloc
setmalloctag malloc
setrealloctag malloc
smalloc malloc
panic panic
canqlock qlock
qlock qlock
qunlock qlock
rlock qlock
runlock qlock
wlock qlock
wunlock qlock
return0 sleep
sleep sleep
tsleep sleep
wakeup sleep
islo splhi
splhi splhi
spllo splhi
splx splhi
xalloc xalloc
xallocz xalloc
xfree xalloc
xspanalloc xalloc
xsummary xalloc

61
sys/man/9/INDEX.html Normal file
View file

@ -0,0 +1,61 @@
<HEAD>
<TITLE>plan 9 man section 9</TITLE>
</HEAD>
<BODY>
<B>[<A HREF="/sys/man/index.html">manual index</A>]</B>
<H2>Plan 9 from Bell Labs - Section 9 - </H2>
<HR>
<DL>
<DT><A HREF="/magic/man2html/9/0intro">0intro</A>
- introduction to kernel functions
<DD><TT> intro</TT>
</DT>
<DT><A HREF="/magic/man2html/9/allocb">allocb</A>
- data block management
<DD><TT> allocb, iallocb, freeb, freeblist, BLEN, BALLOC, blocklen, blockalloclen, readblist, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb</TT>
</DT>
<DT><A HREF="/magic/man2html/9/delay">delay</A>
- small delays, clock interrupts
<DD><TT> delay, microdelay, addclock0link</TT>
</DT>
<DT><A HREF="/magic/man2html/9/error">error</A>
- error handling functions
<DD><TT> error, nexterror, poperror, waserror</TT>
</DT>
<DT><A HREF="/magic/man2html/9/eve">eve</A>
- privileged user
<DD><TT> eve, iseve</TT>
</DT>
<DT><A HREF="/magic/man2html/9/intrenable">intrenable</A>
- enable (disable) an interrupt handler
<DD><TT> intrenable, intrdisable</TT>
</DT>
<DT><A HREF="/magic/man2html/9/kproc">kproc</A>
- kernel process creation, termination and interruption
<DD><TT> kproc, pexit, postnote</TT>
</DT>
<DT><A HREF="/magic/man2html/9/malloc">malloc</A>
- kernel memory allocator
<DD><TT> malloc, mallocz, smalloc, realloc, free, msize, secalloc, secfree, setmalloctag, setrealloctag, getmalloctag, getrealloctag</TT>
</DT>
<DT><A HREF="/magic/man2html/9/panic">panic</A>
- abandon hope, all ye who enter here
<DD><TT> panic</TT>
</DT>
<DT><A HREF="/magic/man2html/9/qlock">qlock</A>
- serial synchronisation
<DD><TT> qlock, qunlock, canqlock, rlock, runlock, wlock, wunlock</TT>
</DT>
<DT><A HREF="/magic/man2html/9/sleep">sleep</A>
- process synchronisation
<DD><TT> sleep, wakeup, tsleep, return0</TT>
</DT>
<DT><A HREF="/magic/man2html/9/splhi">splhi</A>
- enable and disable interrupts
<DD><TT> splhi, spllo, splx, islo</TT>
</DT>
<DT><A HREF="/magic/man2html/9/xalloc">xalloc</A>
- basic memory management
<DD><TT> xalloc, xallocz, xspanalloc, xfree, xsummary</TT>
</DT>
</DL>

343
sys/man/9/allocb Normal file
View file

@ -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)

46
sys/man/9/delay Normal file
View file

@ -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)

171
sys/man/9/error Normal file
View file

@ -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)

46
sys/man/9/eve Normal file
View file

@ -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)

106
sys/man/9/intrenable Normal file
View file

@ -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)

134
sys/man/9/kproc Normal file
View file

@ -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

187
sys/man/9/malloc Normal file
View file

@ -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)

25
sys/man/9/panic Normal file
View file

@ -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.

138
sys/man/9/qlock Normal file
View file

@ -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)

125
sys/man/9/sleep Normal file
View file

@ -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".

56
sys/man/9/splhi Normal file
View file

@ -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)

81
sys/man/9/xalloc Normal file
View file

@ -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)