Blame src/lib/libast/man/aso.3

Packit Service a8c26c
.fp 5 CW
Packit Service a8c26c
.TH LIBASO 3
Packit Service a8c26c
.SH NAME
Packit Service a8c26c
\fBASO\fP \- Atomic Scalar Operations
Packit Service a8c26c
.SH SYNOPSIS
Packit Service a8c26c
.de Tp
Packit Service a8c26c
.fl
Packit Service a8c26c
.ne 2
Packit Service a8c26c
.TP
Packit Service a8c26c
..
Packit Service a8c26c
.de Ss
Packit Service a8c26c
.fl
Packit Service a8c26c
.ne 2
Packit Service a8c26c
.SS "\\$1"
Packit Service a8c26c
..
Packit Service a8c26c
.de Cs
Packit Service a8c26c
.nf
Packit Service a8c26c
.ft 5
Packit Service a8c26c
..
Packit Service a8c26c
.de Ce
Packit Service a8c26c
.ft 1
Packit Service a8c26c
.fi
Packit Service a8c26c
..
Packit Service a8c26c
.ta 1.0i 2.0i 3.0i 4.0i 5.0i
Packit Service a8c26c
.Cs
Packit Service a8c26c
#include <aso.h>
Packit Service a8c26c
.Ce
Packit Service a8c26c
.Ss "TYPES"
Packit Service a8c26c
.Cs
Packit Service a8c26c
typedef int (*Asoerror_f)(int, const char*);
Packit Service a8c26c
typedef void* (*Asoinit_f)(void*, const char*);
Packit Service a8c26c
typedef ssize_t (*Asolock_f)(void*, ssize_t, void volatile*);
Packit Service a8c26c
Packit Service a8c26c
typedef struct Asodisc_s
Packit Service a8c26c
{
Packit Service a8c26c
	uint32_t	version;
Packit Service a8c26c
	unsigned int	hung;
Packit Service a8c26c
	Asoerror_f	errorf;
Packit Service a8c26c
} Asodisc_t;
Packit Service a8c26c
Packit Service a8c26c
typedef struct Asometh_s
Packit Service a8c26c
{
Packit Service a8c26c
	const char*	name;
Packit Service a8c26c
	int		type;
Packit Service a8c26c
	Asoinit_f	initf;
Packit Service a8c26c
	Asolock_f	lockf;
Packit Service a8c26c
	const char*	details;
Packit Service a8c26c
} Asometh_t;
Packit Service a8c26c
.Ce
Packit Service a8c26c
.Ss "OPERATIONS"
Packit Service a8c26c
.Cs
Packit Service a8c26c
uint8_t		asocas8(uint8_t volatile*, int, int);
Packit Service a8c26c
uint8_t		asoget8(uint8_t volatile*);
Packit Service a8c26c
uint8_t		asoinc8(uint8_t volatile*);
Packit Service a8c26c
uint8_t		asodec8(uint8_t volatile*);
Packit Service a8c26c
Packit Service a8c26c
uint16_t	asocas16(uint16_t volatile*, uint16_t, uint16_t);
Packit Service a8c26c
uint16_t	asoget16(uint16_t volatile*);
Packit Service a8c26c
uint16_t	asoinc16(uint16_t volatile*);
Packit Service a8c26c
uint16_t	asodec16(uint16_t volatile*);
Packit Service a8c26c
Packit Service a8c26c
uint32_t	asocas32(uint32_t volatile*, uint32_t, uint32_t);
Packit Service a8c26c
uint32_t	asoget32(uint32_t volatile*);
Packit Service a8c26c
uint32_t	asoinc32(uint32_t volatile*);
Packit Service a8c26c
uint32_t	asodec32(uint32_t volatile*);
Packit Service a8c26c
Packit Service a8c26c
uint64_t	asocas64(uint64_t volatile*, uint64_t, uint64_t);
Packit Service a8c26c
uint64_t	asoget64(uint64_t volatile*);
Packit Service a8c26c
uint64_t	asoinc64(uint64_t volatile*);
Packit Service a8c26c
uint64_t	asodec64(uint64_t volatile*);
Packit Service a8c26c
Packit Service a8c26c
unsigned char	asocaschar(unsigned char volatile*, int, int);
Packit Service a8c26c
unsigned char	asogetchar(unsigned char volatile*);
Packit Service a8c26c
unsigned char	asoincchar(unsigned char volatile*);
Packit Service a8c26c
unsigned char	asodecchar(unsigned char volatile*);
Packit Service a8c26c
Packit Service a8c26c
unsigned short	asocasshort(unsigned short volatile*, unsigned short, unsigned short);
Packit Service a8c26c
unsigned short	asogetshort(unsigned short volatile*);
Packit Service a8c26c
unsigned short	asoincshort(unsigned short volatile*);
Packit Service a8c26c
unsigned short	asodecshort(unsigned short volatile*);
Packit Service a8c26c
Packit Service a8c26c
unsigned int	asocasint(unsigned int volatile*, unsigned int, unsigned int);
Packit Service a8c26c
unsigned int	asogetint(unsigned int volatile*);
Packit Service a8c26c
unsigned int	asoincint(unsigned int volatile*);
Packit Service a8c26c
unsigned int	asodecint(unsigned int volatile*);
Packit Service a8c26c
Packit Service a8c26c
unsigned long	asocaslong(unsigned long volatile*, unsigned long, unsigned long);
Packit Service a8c26c
unsigned long	asogetlong(unsigned long volatile*);
Packit Service a8c26c
unsigned long	asoinclong(unsigned long volatile*);
Packit Service a8c26c
unsigned long	asodeclong(unsigned long volatile*);
Packit Service a8c26c
Packit Service a8c26c
size_t		asocassize(size_t volatile*, size_t, size_t);
Packit Service a8c26c
size_t		asogetsize(size_t volatile*);
Packit Service a8c26c
size_t		asoincsize(size_t volatile*);
Packit Service a8c26c
size_t		asodecsize(size_t volatile*);
Packit Service a8c26c
Packit Service a8c26c
void*		asocasptr(void volatile*, void*, void*);
Packit Service a8c26c
void*		asogetptr(void volatile*);
Packit Service a8c26c
Packit Service a8c26c
void		ASODISC(Asodisc_t*, Asoerror_f);
Packit Service a8c26c
Asometh_t*	asometh(int, void*);
Packit Service a8c26c
int		asoinit(const char*, Asometh_t*, Asodisc_t*);
Packit Service a8c26c
int		asolock(unsigned int volatile*, unsigned int, int);
Packit Service a8c26c
int		asoloop(uintmax_t);
Packit Service a8c26c
int		asorelax(long);
Packit Service a8c26c
.Ce
Packit Service a8c26c
.SH DESCRIPTION
Packit Service a8c26c
.PP
Packit Service a8c26c
\fIASO\fP provides functions to perform atomic scalar operations.
Packit Service a8c26c
The functions on the type \f5uint32_t\fP will be fully described below.
Packit Service a8c26c
Other functions work similarly on their respective types.
Packit Service a8c26c
Some of the functions may be macros that call other functions.
Packit Service a8c26c
64 bit operations are provided if the compiler supports 64 bit integers and/or pointers.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "TYPES"
Packit Service a8c26c
.PP
Packit Service a8c26c
\f5uint8_t, uint16_t, uint32_t, uint64_t\fP
Packit Service a8c26c
Packit Service a8c26c
These are \fIunsigned integer\fP types of different sizes in bits.
Packit Service a8c26c
For example, \f5uint32_t\fP represents the type of unsigned integer with 32 bits or 4 bytes.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "OPERATIONS"
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  uint32_t asoget32(uint32_t* from);"
Packit Service a8c26c
This function returns the value \f5*from\fP.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  uint32_t asoinc32(uint32_t* dest);"
Packit Service a8c26c
.Ss "  uint32_t asodec32(uint32_t* dest);"
Packit Service a8c26c
These functions increment \f5*dest\fP by 1 and decrement \f5*dest\fP by 1 in an atomic step.
Packit Service a8c26c
The return value is the old value in \f5*dest\fP.
Packit Service a8c26c
Packit Service a8c26c
Consider an example where two concurrent threads/processes call \f5asoinc32()\fP
Packit Service a8c26c
on the same \f5dest\fP with values, say \fIv1\fP and \fIv2\fP.
Packit Service a8c26c
The eventual value in \f5dest\fP
Packit Service a8c26c
will be as if \f5*dest += 2\fP was performed in a single-threaded execution.
Packit Service a8c26c
Packit Service a8c26c
That should be constrasted with a situation where, instead of \f5asoinc32()\fP or \f5asodec32()\fP,
Packit Service a8c26c
only normal increment (++) or decrement (--) were used.
Packit Service a8c26c
Then, the end result could be either \f5*dest += 1\fP or \f5*dest += 2\fP,
Packit Service a8c26c
depending on states of the hardware cache and process scheduling.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  uint32_t asocas32(uint32_t* dest, uint32_t tstval, uint32_t newval);"
Packit Service a8c26c
This function provides the atomic \fIcompare-and-swap\fP operation.
Packit Service a8c26c
If the current content of \f5dest\fP is equal to \f5tstval\fP then it will be set to \f5newval\fP.
Packit Service a8c26c
If multiple threads/processes are performing the same operations only one will succeed with a
Packit Service a8c26c
return value of \f5tstval\fP.
Packit Service a8c26c
The return value is the old value in \f5*dest\fP.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  void asorelax(long nsec)"
Packit Service a8c26c
This function causes the calling process or thread to briefly pause
Packit Service a8c26c
for \f5nsec\fP nanoseconds.
Packit Service a8c26c
It is useful to implement tight loops that occasionally yield control.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  int asolock(unsigned int* lock, unsigned int key, int type)"
Packit Service a8c26c
This function uses \f5key\fP, a non-zero unsigned integer, to lock or unlock the \f5lock\fP.
Packit Service a8c26c
It returns \f50\fP on success and \f5-1\fP on failure.
Packit Service a8c26c
The argument \f5type\fP can take one of the following values:
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_UNLOCK\fP:
Packit Service a8c26c
This unlocks the lock if it was locked with \f5key\fP. It is an error to try
Packit Service a8c26c
unlocking a lock of a different key.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_TRYLOCK\fP:
Packit Service a8c26c
This makes a single attempt to use the given \f5key\fP to acquire a lock.
Packit Service a8c26c
An error will result if the lock is already locked with a different key.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_LOCK\fP:
Packit Service a8c26c
This is a regular locking call. If the lock is locked with a different key,
Packit Service a8c26c
this call will wait until the lock is open, then lock it with the given \f5key\fP.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_SPINLOCK\fP:
Packit Service a8c26c
Regardless of what key is currently locking the lock,
Packit Service a8c26c
this call will always wait until the lock is open, then lock it with the given \f5key\fP.
Packit Service a8c26c
Note that, if the lock is already locked with \f5key\fP, this call can result
Packit Service a8c26c
in a deadlock unless that lock can be opened by some other mechanism, e.g.,
Packit Service a8c26c
by a different process or thread.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "  int asoloop(uintmax_t iteration);"
Packit Service a8c26c
This function is used to implement spin locks that periodically relinquish the processor:
Packit Service a8c26c
.Cs
Packit Service a8c26c
uintmax_t iteration;
Packit Service a8c26c
iteration = 0;
Packit Service a8c26c
for (;;) {
Packit Service a8c26c
    /* test resource with an aso*() call */
Packit Service a8c26c
    if (asoloop(++iteration))
Packit Service a8c26c
        /* an error occurred */;
Packit Service a8c26c
}
Packit Service a8c26c
.Ce
Packit Service a8c26c
The value of \f5iteration\fP should be \f51\fP (\fInot\fP \f50\fP) for the first loop iteration.
Packit Service a8c26c
\f50\fP is returned on success, \f5-1\fP on failure.
Packit Service a8c26c
If \f5iteration mod 4\fP is \f50\fP then \f5asorelax(1)\fP is called to temporarily relinquish
Packit Service a8c26c
the processor.
Packit Service a8c26c
If \f5Asodisc_t.hung != 0\fP and \f5Asodisc_t.errorf != 0\fP and
Packit Service a8c26c
\f5iteration mod (2**Asodisc_t.hung-1)\fP is \f50\fP,
Packit Service a8c26c
then \f5Asodisc_t.errorf\fP is called with type \f5ASO_HUNG\fP
Packit Service a8c26c
and \f5-1\fP is returned.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "DISCIPLINE"
Packit Service a8c26c
.PP
Packit Service a8c26c
The Asodisc_t discipline structure allows the caller to modify default behavior.
Packit Service a8c26c
The \fIASO\fP discipline is global for all threads and forked children of the current process.
Packit Service a8c26c
The discipline is set and modified by the \f5asoinit()\fP function, described below.
Packit Service a8c26c
The structure members are:
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5uint32_t version;\fP
Packit Service a8c26c
This must be set to \f5ASO_VERSION\fP by the caller and is used by the implementation to detect
Packit Service a8c26c
release differences between the caller and the implementation.
Packit Service a8c26c
The version is integer of the form \fIYYYYMMDD\fP where \fIYYYY\fP is the release year, \fIMM\fP
Packit Service a8c26c
is the release month, and \fIDD\fP is the release day of month.
Packit Service a8c26c
This allows the implementation to be forwards and backwards binary compatible with all releases.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5unsigned int hung;\fP
Packit Service a8c26c
An error occurs if \f5asoloop\fP() is called \f52**Asometh_t.hung\fP times without gaining access to the loop resource.
Packit Service a8c26c
The default value \f50\fP disables the test.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5Asoerror_f errorf;\fP
Packit Service a8c26c
\f5int (*errorf)(int type, const char* mesg);\fP
Packit Service a8c26c
If \f5errorf\fP != \f50\fP then it is called for each \fIASO\fP fatal library condition.
Packit Service a8c26c
\f5type\fP may be one of: \f5ASO_METHOD\fP - a method error; \f5ASO_HUNG\fP - \f5asoloop\fP() was called
Packit Service a8c26c
\f52**Asometh_t.hung\fP times with no access to the loop resource.
Packit Service a8c26c
\f5mesg\fP is a 0-terminated messsage description.
Packit Service a8c26c
.Ss "  void ASODISC(Asodisc_t* disc, Asoerror_f errorf);"
Packit Service a8c26c
.PP
Packit Service a8c26c
This function-like-macro initializes \f5disc->version = ASO_VERSION\fP, \f5disc->errorf = errorf\fP,
Packit Service a8c26c
and the remaining \f5disc\fP members to \f50\fP.
Packit Service a8c26c
.PP
Packit Service a8c26c
.Ss "METHODS"
Packit Service a8c26c
.PP
Packit Service a8c26c
Several atomic locking methods are implemented for atomic operations
Packit Service a8c26c
not supported by \fIintrinsic\fP functions or assembly instructions.
Packit Service a8c26c
Methods are controlled by the \f5asometh()\fP and \f5asoinit()\fP
Packit Service a8c26c
functions, described below.
Packit Service a8c26c
The \fIASO\fP method is global for all threads and forked children of the current process.
Packit Service a8c26c
A given method may have multiple types.
Packit Service a8c26c
The methods types are:
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_INTRINSIC\fP:
Packit Service a8c26c
Some hardware platforms provide machine instructions to implement these operations directly.
Packit Service a8c26c
In that case, if a local compiler permits, calls to these \fIintrinsic\fP functions
Packit Service a8c26c
may be translated directly into their corresponding machine instructions.
Packit Service a8c26c
When necessary the implementation can use only the intrinsic \fIcompare-and-swap\fP
Packit Service a8c26c
function on the largest integer type to emulate all other \fIASO\fP operations.
Packit Service a8c26c
The \f5ASO_INTRINSIC\fP method type is the default when supported by the compiler.
Packit Service a8c26c
It may be used for single-process single-thread, multi-thread, and
Packit Service a8c26c
multi-process applications.
Packit Service a8c26c
When supported by the hardware / compiler, the library provides the "\fBintrinsic\fP" method with type
Packit Service a8c26c
\f5ASO_INTRINSIC|ASO_PROCESS|ASO_THREAD|ASO_SIGNAL\fP.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_SIGNAL\fP:
Packit Service a8c26c
This method type is suitable only for single-process single-thread applications.
Packit Service a8c26c
It can be used to provide locking between asyncronous \fBsignal\fP(2) handlers
Packit Service a8c26c
and the main program.
Packit Service a8c26c
The library provides the "\fBsignal\fP" method with type \f5ASO_SIGNAL\fP.
Packit Service a8c26c
This is the default method type when \f5ASO_INTRINSIC\fP is not supported.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_THREAD\fP:
Packit Service a8c26c
This method type is suitable for single-process single-thread, and multi-thread applications.
Packit Service a8c26c
It typically requires thread library support, and since the default \f5aso\fP library
Packit Service a8c26c
is not linked with a thread library, no \f5ASO_THREAD\fP method is provided by default.
Packit Service a8c26c
Threaded applications must link with \fB-ltaso\fP (before \fB-laso\fP or \fB-last\fP)
Packit Service a8c26c
in order to access \f5ASO_THREAD\fP methods.
Packit Service a8c26c
The \fB-ltaso\fP library provides the "\fBspin\fP" (using \fBpthread_spin_lock\fP(3)) and
Packit Service a8c26c
"\fBmutex"\fP (using \fBpthread_mutex_lock\fP(3)) methods with type \f5ASO_THREAD|ASO_SIGNAL\fP.
Packit Service a8c26c
.Tp
Packit Service a8c26c
\f5ASO_PROCESS\fP:
Packit Service a8c26c
This method type is suitable for single-process single-thread, and multi-process applications.
Packit Service a8c26c
Some \f5ASO_PROCESS\fP methods may also be suitable for multi-thread applications (if they have the \f5ASO_THREAD\fP type.)
Packit Service a8c26c
These methods are typically and noticably \fIslow\fP, up to 2 orders of magnitude slower than
Packit Service a8c26c
\f5ASO_INTRINSIC\fP for some applications.
Packit Service a8c26c
They are provided as a last resort when other methods are not available.
Packit Service a8c26c
The library provides the "\fBsemaphore\fP" method with type \f5ASO_PROCESS|ASO_THREAD|ASO_SIGNAL\fP
Packit Service a8c26c
and the "\fBfcntl\fP" method with type \f5ASO_PROCESS|ASO_SIGNAL\fP.
Packit Service a8c26c
Packit Service a8c26c
.Ss "  Asometh_t* asometh(int type, void* data);"
Packit Service a8c26c
This function looks up methods by type or name.
Packit Service a8c26c
If type is \f50\fP and \f5data\fP is \f50\fP then the current method is returned; a valid method
Packit Service a8c26c
will always be returned for this call.
Packit Service a8c26c
If type is \f50\fP then \f5data\fP is treated as a \f50\fP-terminated string method name;
Packit Service a8c26c
\f50\fP is returned if no matching method is found.
Packit Service a8c26c
The pseudo-type \f5ASO_NEXT\fP generates the list of all methods in successive calls:
Packit Service a8c26c
.Cs
Packit Service a8c26c
Asometh_t* meth;
Packit Service a8c26c
meth = 0;
Packit Service a8c26c
while (meth = asometh(ASO_NEXT, meth))
Packit Service a8c26c
	/* examine meth->... */
Packit Service a8c26c
.Ce
Packit Service a8c26c
Otherwise if \f5type\fP is not \f50\fP and not \f5ASO_NEXT\fP it is treated as a combination of the ordered types
Packit Service a8c26c
\f5ASO_THREAD\fP, \f5ASO_SIGNAL\fP, \f5ASO_INTRINSIC\fP, \f5ASO_PROCESS\fP:
Packit Service a8c26c
the first method with \f5(meth->type & type) != 0\fP is returned;
Packit Service a8c26c
\f50\fP is returned if no matching method is found.
Packit Service a8c26c
Packit Service a8c26c
Method names are treated as a name, optionally followed by a list of
Packit Service a8c26c
\fB,\fP\fIname\fP=\fIvalue\fP details, and optionally ending with \fB,\fP\fIpathname\fP.
Packit Service a8c26c
The \fBsemaphore\fP method uses \fBsize\fP=\fInumber\fP to specify
Packit Service a8c26c
the number of semaphores and hashes \fIpathname\fP to determine the semaphore IPC key.
Packit Service a8c26c
The \fBfcntl\fP method uses \fBsize\fP=\fInumber\fP to specify
Packit Service a8c26c
the number of 1 byte file locks and uses \fIpathname\fP as the
Packit Service a8c26c
file to lock using \f5fcntl(F_SETLCK[W])\fP.
Packit Service a8c26c
Packit Service a8c26c
.Ss "  int asoinit(const char* details, Asometh_t* meth, Asodisc_t* disc);"
Packit Service a8c26c
This function sets the global discipline to \f5disc\fP,
Packit Service a8c26c
closes the current method (releasing its resources),
Packit Service a8c26c
temporarily instantiates the default method
Packit Service a8c26c
(either \f5ASO_INTRINSIC\fP if available or \f5AS_SIGNAL\fP otherwise),
Packit Service a8c26c
and initializes \f5meth\fP and instantiates it as the new method.
Packit Service a8c26c
If \f5disc\fP is \f50\fP the the global discpline is not modified.
Packit Service a8c26c
If \f5meth\fP is \f50\fP then \f51\fP is returned if \f5asoinit()\fP has
Packit Service a8c26c
already been called to initialize a method, otherwise \f50\fP is returned.
Packit Service a8c26c
If \f5meth->lockf\fP is \f50\fP and \f5(meth->type & ASO_INTRINSIC) != 0\fP
Packit Service a8c26c
then \f5-1\fP is returned and the current method is not changed.
Packit Service a8c26c
If an error occurs instantiating \f5meth\fP then the current method is
Packit Service a8c26c
set to the default and \f5-1\fP is returned.
Packit Service a8c26c
Otherwise \f50\fP is returned on success.
Packit Service a8c26c
Packit Service a8c26c
Method resources are released by the next \f5asometh()\fP call,
Packit Service a8c26c
or by an \fIASO\fP cleanup function called via \f5atexit\fP(2).
Packit Service a8c26c
System global method resources are released on last use;
Packit Service a8c26c
this includes removing semaphore keys or
Packit Service a8c26c
physical files that may be used by some methods.
Packit Service a8c26c
In some cases \fIASO\fP maintains reference counts within
Packit Service a8c26c
the resource to determine last use.
Packit Service a8c26c
Packit Service a8c26c
An application requiring a specific method must check the default method before
Packit Service a8c26c
using any \fIASO\fP operations. For example, a threaded application would
Packit Service a8c26c
do something like this:
Packit Service a8c26c
.Cs
Packit Service a8c26c
void* data = 0 /* \fIor\fP a method name string with optional details */
Packit Service a8c26c
Asometh_t* meth;
Packit Service a8c26c
if (data || !(asometh(0, 0)->type & (ASO_INTRINSIC|ASO_THREAD))) {
Packit Service a8c26c
    if (!(meth = asometh(ASO_INTRINSIC|ASO_THREAD, data)))
Packit Service a8c26c
        /* error -- suitable method not found */;
Packit Service a8c26c
    else if (asoinit(meth, 0, 0, ASO_VERSION))
Packit Service a8c26c
        /* error -- method initialization error */;
Packit Service a8c26c
}
Packit Service a8c26c
/* ready for \fIASO\fP operaions */
Packit Service a8c26c
.Ce
Packit Service a8c26c
A multi-process application would check for \f5(ASO_INTRINSIC|ASO_PROCESS)\fP
Packit Service a8c26c
instead of \f5(ASO_INTRINSIC|ASO_THREAD)\fP.
Packit Service a8c26c
Packit Service a8c26c
.PP
Packit Service a8c26c
.SH IMPLEMENTATION NOTES
Packit Service a8c26c
Unlike other \fIAST\fP library discipline/method functions which can instantiate
Packit Service a8c26c
multiple discpline/method handles within a single process, the \fIASO\fP
Packit Service a8c26c
library allows only one discipline and method to be set at a time, with the additional
Packit Service a8c26c
restriction that it may only be set by the main and only thread of the calling process.
Packit Service a8c26c
For this reason there is no open/close interface with an instantation handle;
Packit Service a8c26c
instead the global discipline/method is simply initialized by \f5asoinit()\fP.
Packit Service a8c26c
Packit Service a8c26c
\f5ASO_THREAD\fP and \f5ASO_PROCESS\fP methods rely on the \f5Asometh_t.lockf()\fP
Packit Service a8c26c
being sufficiently "heavy" to flush the calling thread/process memory cache
Packit Service a8c26c
so the subsequent \fIASO\fP operation operates on the physical memory location
Packit Service a8c26c
instead of the cached location. There is currently no other portable mechanism
Packit Service a8c26c
that guarantees this other than the \f5ASO_INTRINSIC\fP method.
Packit Service a8c26c
Packit Service a8c26c
.PP
Packit Service a8c26c
.SH AUTHOR
Packit Service a8c26c
Kiem-Phong Vo, Adam Edgar, and Glenn Fowler