.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "ici::doc::pod3::sdr 3" .TH ici::doc::pod3::sdr 3 "2016-07-07" "perl v5.24.1" "ICI library functions" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" sdr \- Simple Data Recorder library .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #include "sdr.h" \& \& [see below for available functions] .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\s-1SDR\s0 is a library of functions that support the use of an abstract data recording device called an \*(L"\s-1SDR\*(R" \s0(\*(L"simple data recorder\*(R") for persistent storage of data. The \s-1SDR\s0 abstraction insulates software not only from the specific characteristics of any single data storage device but also from some kinds of persistent data storage and retrieval chores. The underlying principle is that an \s-1SDR\s0 provides standardized support for user data organization at object granularity, with direct access to persistent user data objects, rather than supporting user data organization only at \*(L"file\*(R" granularity and requiring the user to implement access to the data objects accreted within those files. .PP The \s-1SDR\s0 library is designed to provide some of the same kinds of directory services as a file system together with support for complex data structures that provide more operational flexibility than files. (As an example of this flexibility, consider how much easier and faster it is to delete a given element from the middle of a linked list than it is to delete a range of bytes from the middle of a text file.) The intent is to enable the software developer to take maximum advantage of the high speed and direct byte addressability of a non-volatile flat address space in the management of persistent data. The \s-1SDR\s0 equivalent of a \*(L"record\*(R" of data is simply a block of nominally persistent memory allocated from this address space. The \s-1SDR\s0 equivalent of a \*(L"file\*(R" is a \fIcollection\fR object. Like files, collections can have names, can be located by name within persistent storage, and can impose structure on the data items they encompass. But, as discussed later, \s-1SDR\s0 collection objects can impose structures other than the strict \&\s-1FIFO\s0 accretion of records or bytes that characterizes a file. .PP The notional data recorder managed by the \s-1SDR\s0 library takes the form of a single array of randomly accessible, contiguous, nominally persistent memory locations called a \fIheap\fR. Physically, the heap may be implemented as a region of shared memory, as a single file of predefined size, or both \*(-- that is, the heap may be a region of shared memory that is automatically mirrored in a file. .PP \&\s-1SDR\s0 services that manage \s-1SDR\s0 data are provided in several layers, each of which relies on the services implemented at lower levels: .Sp .RS 4 At the highest level, a cataloguing service enables retrieval of persistent objects by name. .Sp Services that manage three types of persistent data collections are provided for use both by applications and by the cataloguing service: linked lists, self-delimiting tables (which function as arrays that remember their own dimensions), and self-delimiting strings (short character arrays that remember their lengths, for speedier retrieval). .Sp Basic \s-1SDR\s0 heap space management services, analogous to \fImalloc()\fR and \fIfree()\fR, enable the creation and destruction of objects of arbitrary type. .Sp Farther down the service stack are memcpy-like low-level functions for reading from and writing to the heap. .Sp Protection of \s-1SDR\s0 data integrity across a series of reads and writes is provided by a \fItransaction\fR mechanism. .RE .PP \&\s-1SDR\s0 persistent data are referenced in application code by Object values and Address values, both of which are simply displacements (offsets) within \s-1SDR\s0 address space. The difference between the two is that an Object is always the address of a block of heap space returned by some call to \fIsdr_malloc()\fR, while an Address can refer to any byte in the address space. That is, an Address is the \s-1SDR\s0 functional equivalent of a C pointer in \s-1DRAM,\s0 and some Addresses point to Objects. .PP Before using \s-1SDR\s0 services, the services must be loaded to the target machine and initialized by invoking the \fIsdr_initialize()\fR function and the management profiles of one or more \s-1SDR\s0's must be loaded by invoking the \fIsdr_load_profile()\fR function. These steps are normally performed only once, at application load time. .PP An application gains access to an \s-1SDR\s0 by passing the name of the \&\s-1SDR\s0 to the \fIsdr_start_using()\fR function, which returns an Sdr pointer. Most other \s-1SDR\s0 library functions take an Sdr pointer as first argument. .PP All writing to an \s-1SDR\s0 heap must occur during a \fItransaction\fR that was initiated by the task issuing the write. Transactions are single-threaded; if task B wants to start a transaction while a transaction begun by task A is still in progress, it must wait until A's transaction is either ended or cancelled. A transaction is begun by calling \fIsdr_begin_xn()\fR. The current transaction is normally ended by calling the \fIsdr_end_xn()\fR function, which returns an error return code value in the event that any serious SDR-related processing error was encountered in the course of the transaction. Transactions may safely be nested, provided that every level of transaction activity that is begun is properly ended. .PP The current transaction may instead be cancelled by calling \fIsdr_cancel_xn()\fR, which is normally used to indicate that some sort of serious SDR-related processing error has been encountered. Canceling a transaction reverses all \s-1SDR\s0 update activity performed up to that point within the scope of the transaction \*(-- and, if the canceled transaction is an inner, nested transaction, all \s-1SDR\s0 update activity performed within the scope of every outer transaction encompassing that transaction \fIand\fR every other transaction nested within any of those outer transactions \*(-- provided the \s-1SDR\s0 was configured for transaction \fIreversibility\fR. When an \s-1SDR\s0 is configured for reversibility, all heap write operations performed during a transaction are recorded in a log file that is retained until the end of the transaction. Each log file entry notes the location at which the write operation was performed, the length of data written, and the content of the overwritten heap bytes prior to the write operation. Canceling the transaction causes the log entries to be read and processed in reverse order, restoring all overwritten data. Ending the transaction, on the other hand, simply causes the log to be discarded. .PP If a log file exists at the time that the profile for an \s-1SDR\s0 is loaded (typically during application initialization), the transaction that was being logged is automatically canceled and reversed. This ensures that, for example, a power failure that occurs in the middle of a transaction will never wreck the \s-1SDR\s0's data integrity: either all updates issued during a given transaction are reflected in the current database content or none are. .PP As a further measure to protect \s-1SDR\s0 data integrity, an \s-1SDR\s0 may additionally be configured for \fIobject bounding\fR. When an \s-1SDR\s0 is configured to be \*(L"bounded\*(R", every heap write operation is restricted to the extent of a single object allocated from heap space; that is, it's impossible to overwrite part of one object by writing beyond the end of another. To enable the library to enforce this mechanism, application code is prohibited from writing anywhere but within the extent of an object that either (a) was allocated from managed heap space during the same transaction (directly or indirectly via some collection management function) or (b) was \fIstaged\fR \*(-- identified as an update target \*(-- during the same transaction (again, either directly or via some collection management function). .PP Note that both transaction reversibility and object bounding consume processing cycles and inhibit performance to some degree. Determining the right balance between operational safety and processing speed is left to the user. .PP Note also that, since \s-1SDR\s0 transactions are single-threaded, they can additionally be used as a general mechanism for simply implementing \*(L"critical sections\*(R" in software that is already using \s-1SDR\s0 for other purposes: the beginning of a transaction marks the start of code that can't be executed concurrently by multiple tasks. To support this use of the \s-1SDR\s0 transaction mechanism, the additional transaction termination function \fIsdr_exit_xn()\fR is provided. \fIsdr_exit_xn()\fR simply ends a transaction without either signaling an error or checking for errors. Like \fIsdr_cancel_xn()\fR, \fIsdr_exit_xn()\fR has no return value; unlike \fIsdr_cancel_xn()\fR, it assures that ending an inner, nested transaction does not cause the outer transaction to be aborted and backed out. But this capability must be used carefully: the protection of \s-1SDR\s0 data integrity requires that transactions which are ended by \fIsdr_exit_xn()\fR must not encompass any \s-1SDR\s0 update activity whatsoever. .PP The heap space management functions of the \s-1SDR\s0 library are adapted directly from the Personal Space Management (\fIpsm\fR) function library. The manual page for \fIpsm\fR\|(3) explains the algorithms used and the rationale behind them. The principal difference between \s-1PSM\s0 memory management and \s-1SDR\s0 heap management is that, for performance reasons, \s-1SDR\s0 reserves the \*(L"small pool\*(R" for its own use only; all user data space is allocated from the \*(L"large pool\*(R", via the \fIsdr_malloc()\fR function. .SS "\s-1RETURN VALUES AND ERROR HANDLING\s0" .IX Subsection "RETURN VALUES AND ERROR HANDLING" Whenever an \s-1SDR\s0 function call fails, a diagnostic message explaining the failure of the function is recorded in the error message pool managed by the \*(L"platform\*(R" system (see the discussion of \fIputErrmsg()\fR in \fIplatform\fR\|(3)). .PP The failure of any function invoked in the course of an \s-1SDR\s0 transaction causes all subsequent \s-1SDR\s0 activity in that transaction to fail immediately. This can streamline \s-1SDR\s0 application code somewhat: it may not be necessary to check the return value of every \s-1SDR\s0 function call executed during a transaction. If the \fIsdr_end_xn()\fR call returns zero, all updates performed during the transaction must have succeeded. .SH "SYSTEM ADMINISTRATION FUNCTIONS" .IX Header "SYSTEM ADMINISTRATION FUNCTIONS" .IP "int sdr_initialize(int wmSize, char *wmPtr, int wmKey, char *wmName)" 4 .IX Item "int sdr_initialize(int wmSize, char *wmPtr, int wmKey, char *wmName)" Initializes the \s-1SDR\s0 system. \fIsdr_initialize()\fR must be called once every time the computer on which the system runs is rebooted, before any call to any other \s-1SDR\s0 library function. .Sp This function attaches to a pool of shared memory, managed by \s-1PSM \&\s0(see \fIpsm\fR\|(3), that enables \s-1SDR\s0 library operations. If the \s-1SDR\s0 system is to access a common pool of shared memory with one or more other systems, the key of that shared memory segment must be provided in \&\fIwmKey\fR and the \s-1PSM\s0 partition name associated with that memory segment must be provided in \fIwmName\fR; otherwise \fIwmKey\fR must be zero and \&\fIwmName\fR must be \s-1NULL,\s0 causing \fIsdr_initialize()\fR to assign default values. If a shared memory segment identified by the effective value of \fIwmKey\fR already exists, then \fIwmSize\fR may be zero and the value of \&\fIwmPtr\fR is ignored. Otherwise the size of the shared memory pool must be provided in \fIwmSize\fR and a new shared memory segment is created in a manner that is dependent on \fIwmPtr\fR: if \fIwmPtr\fR is \s-1NULL\s0 then \fIwmSize\fR bytes of shared memory are dynamically acquired, allocated, and assigned to the newly created shared memory segment; otherwise the memory located at \fIwmPtr\fR is assumed to have been pre-allocated and is merely assigned to the newly created shared memory segment. .Sp \&\fIsdr_initialize()\fR also creates a semaphore to serialize access to the \&\s-1SDR\s0 system's private array of \s-1SDR\s0 profiles. .Sp Returns 0 on success, \-1 on any failure. .IP "void sdr_wm_usage(PsmUsageSummary *summary)" 4 .IX Item "void sdr_wm_usage(PsmUsageSummary *summary)" Loads \fIsummary\fR with a snapshot of the usage of the \s-1SDR\s0 system's private working memory. To print the snapshot, use \fIpsm_report()\fR. (See \fIpsm\fR\|(3).) .IP "void sdr_shutdown( )" 4 .IX Item "void sdr_shutdown( )" Ends all access to all SDRs (see \fIsdr_stop_using()\fR), detaches from the \&\s-1SDR\s0 system's working memory (releasing the memory if it was dynamically allocated by \fIsdr_initialize()\fR), and destroys the \s-1SDR\s0 system's private semaphore. After \fIsdr_shutdown()\fR, \fIsdr_initialize()\fR must be called again before any call to any other \s-1SDR\s0 library function. .SH "DATABASE ADMINISTRATION FUNCTIONS" .IX Header "DATABASE ADMINISTRATION FUNCTIONS" .IP "int sdr_load_profile(char *name, int configFlags, long heapWords, int memKey, char *pathName, char *restartCmd, unsigned int restartLatency)" 4 .IX Item "int sdr_load_profile(char *name, int configFlags, long heapWords, int memKey, char *pathName, char *restartCmd, unsigned int restartLatency)" Loads the profile for an \s-1SDR\s0 into the system's private list of \s-1SDR\s0 profiles. Although SDRs themselves are persistent, \s-1SDR\s0 profiles are not: in order for an application to access an \s-1SDR,\s0 \fIsdr_load_profile()\fR must have been called to load the profile of the \s-1SDR\s0 since the last invocation of \fIsdr_initialize()\fR. .Sp \&\fIname\fR is the name of the \s-1SDR,\s0 required for any subsequent \fIsdr_start_using()\fR call. .Sp \&\fIconfigFlags\fR specifies the configuration of the \&\s-1SDR,\s0 the bitwise \*(L"or\*(R" of some combination of the following: .RS 4 .IP "\s-1SDR_IN_DRAM\s0" 4 .IX Item "SDR_IN_DRAM" \&\s-1SDR\s0 is implemented as a region of shared memory. .IP "\s-1SDR_IN_FILE\s0" 4 .IX Item "SDR_IN_FILE" \&\s-1SDR\s0 is implemented as a file. .IP "\s-1SDR_REVERSIBLE\s0" 4 .IX Item "SDR_REVERSIBLE" \&\s-1SDR\s0 transactions are logged and are reversed if canceled. .IP "\s-1SDR_BOUNDED\s0" 4 .IX Item "SDR_BOUNDED" Heap updates are not allowed to cross object boundaries. .RE .RS 4 .Sp \&\fIheapWords\fR specifies the size of the heap in words; word size depends on machine architecture, i.e., a word is 4 bytes on a 32\-bit machine, 8 bytes on a 64\-bit machine. Note that each \s-1SDR\s0 prepends to the heap a \*(L"map\*(R" of predefined, fixed size. The total amount of space occupied by an \s-1SDR\s0 in memory and/or in a file is the sum of the size of the map plus the product of word size and \fIheapWords\fR. .Sp \&\fImemKey\fR is ignored if \fIconfigFlags\fR does not include \s-1SDR_IN_DRAM. \s0 It should normally be \s-1SM_NO_KEY,\s0 causing the shared memory region for the \s-1SDR\s0 to be allocated dynamically and shared using a dynamically selected shared memory key. If specified, \fImemKey\fR must be a shared memory key identifying a pre-allocated region of shared memory whose length is equal to the total \&\s-1SDR\s0 size, shared via the indicated key. .Sp \&\fIpathName\fR is ignored if \fIconfigFlags\fR includes neither \s-1SDR_REVERSIBLE\s0 nor \&\s-1SDR_IN_FILE. \s0 It is the fully qualified name of the directory into which the \&\s-1SDR\s0's log file and/or database file will be written. The name of the log file (if any) will be \*(L".sdrlog\*(R". The name of the database file (if any) will be \*(L".sdr\*(R"; this file will be automatically created and filled with zeros if it does not exist at the time the \s-1SDR\s0's profile is loaded. .Sp If a cleanup task must be run whenever a transaction is reversed, the command to execute this task must be provided in \fIrestartCmd\fR and the number of seconds to wait for this task to finish before resuming operations must be provided in \fIrestartLatency\fR. If \fIrestartCmd\fR is \s-1NULL\s0 or \fIrestartLatency\fR is zero then no cleanup task will be run upon transaction reversal. .Sp Returns 0 on success, \-1 on any error. .RE .IP "int sdr_reload_profile(char *name, int configFlags, long heapWords, int memKey, char *pathName, char *restartCmd, unsigned int restartLatency)" 4 .IX Item "int sdr_reload_profile(char *name, int configFlags, long heapWords, int memKey, char *pathName, char *restartCmd, unsigned int restartLatency)" For use when the state of an \s-1SDR\s0 is thought to be inconsistent, perhaps due to crash of a program that had a transaction open. Unloads the profile for the \s-1SDR,\s0 forcing the reversal of any transaction that is currently in progress when the \s-1SDR\s0's profile is re-loaded. Then calls \fIsdr_load_profile()\fR to re-load the profile for the \s-1SDR. \s0 Same return values as sdr_load_profile. .IP "Sdr sdr_start_using(char *name)" 4 .IX Item "Sdr sdr_start_using(char *name)" Locates \s-1SDR\s0 profile by \fIname\fR and returns a handle that can be used for all functions that operate on that \s-1SDR. \s0 On any failure, returns \s-1NULL.\s0 .IP "char *sdr_name(Sdr sdr)" 4 .IX Item "char *sdr_name(Sdr sdr)" Returns the name of the sdr. .IP "long sdr_heap_size(Sdr sdr)" 4 .IX Item "long sdr_heap_size(Sdr sdr)" Returns the total size of the \s-1SDR\s0 heap, in bytes. .IP "void sdr_stop_using(Sdr sdr)" 4 .IX Item "void sdr_stop_using(Sdr sdr)" Terminates access to the \s-1SDR\s0 via this handle. Other users of the \s-1SDR\s0 are not affected. Frees the Sdr object. .IP "void sdr_abort(Sdr sdr)" 4 .IX Item "void sdr_abort(Sdr sdr)" Terminates the task. In flight configuration, also terminates all use of the \s-1SDR\s0 system by all tasks. .IP "void sdr_destroy(Sdr sdr)" 4 .IX Item "void sdr_destroy(Sdr sdr)" Ends all access to this \s-1SDR,\s0 unloads the \s-1SDR\s0's profile, and erases the \s-1SDR\s0 from memory and file system. .SH "DATABASE TRANSACTION FUNCTIONS" .IX Header "DATABASE TRANSACTION FUNCTIONS" .IP "void sdr_begin_xn(Sdr sdr)" 4 .IX Item "void sdr_begin_xn(Sdr sdr)" Initiates a transaction. Note that transactions are single-threaded; any task that calls \fIsdr_begin_xn()\fR is suspended until all previously requested transactions have been ended or canceled. .IP "int sdr_in_xn(Sdr sdr)" 4 .IX Item "int sdr_in_xn(Sdr sdr)" Returns 1 if called in the course of a transaction, 0 otherwise. .IP "void sdr_exit_xn(Sdr sdr)" 4 .IX Item "void sdr_exit_xn(Sdr sdr)" Simply abandons the current transaction, ceasing the calling task's lock on \&\s-1ION. \s0 Must \fBnot\fR be used if any database modifications were performed during the transaction; \fIsdr_end_xn()\fR must be called instead, to commit those modifications. .IP "void sdr_cancel_xn(Sdr sdr)" 4 .IX Item "void sdr_cancel_xn(Sdr sdr)" Cancels the current transaction. If reversibility is enabled for the \s-1SDR,\s0 canceling a transaction reverses all heap modifications performed during that transaction. .IP "int sdr_end_xn(Sdr sdr)" 4 .IX Item "int sdr_end_xn(Sdr sdr)" Ends the current transaction. Returns 0 if the transaction completed without any error; returns \-1 if any operation performed in the course of the transaction failed, in which case the transaction was automatically canceled. .SH "DATABASE I/O FUNCTIONS" .IX Header "DATABASE I/O FUNCTIONS" .IP "void sdr_read(Sdr sdr, char *into, Address from, int length)" 4 .IX Item "void sdr_read(Sdr sdr, char *into, Address from, int length)" Copies \fIlength\fR characters at \fIfrom\fR (a location in the indicated \s-1SDR\s0) to the memory location given by \fIinto\fR. The data are copied from the shared memory region in which the \s-1SDR\s0 resides, if any; otherwise they are read from the file in which the \s-1SDR\s0 resides. .IP "void sdr_peek(sdr, variable, from)" 4 .IX Item "void sdr_peek(sdr, variable, from)" \&\fIsdr_peek()\fR is a macro that uses \fIsdr_read()\fR to load \fIvariable\fR from the indicated address in the \s-1SDR\s0 database; the size of \fIvariable\fR is used as the number of bytes to copy. .IP "void sdr_write(Sdr sdr, Address into, char *from, int length)" 4 .IX Item "void sdr_write(Sdr sdr, Address into, char *from, int length)" Copies \fIlength\fR characters at \fIfrom\fR (a location in memory) to the \s-1SDR\s0 heap location given by \fIinto\fR. Can only be performed during a transaction, and if the \s-1SDR\s0 is configured for object bounding then heap locations \fIinto\fR through (\fIinto\fR + (\fIlength\fR \- 1)) must be within the extent of some object that was either allocated or staged within the same transaction. The data are copied both to the shared memory region in which the \s-1SDR\s0 resides, if any, and also to the file in which the \s-1SDR\s0 resides, if any. .IP "void sdr_poke(sdr, into, variable)" 4 .IX Item "void sdr_poke(sdr, into, variable)" \&\fIsdr_poke()\fR is a macro that uses \fIsdr_write()\fR to store \fIvariable\fR at the indicated address in the \s-1SDR\s0 database; the size of \fIvariable\fR is used as the number of bytes to copy. .IP "char *sdr_pointer(Sdr sdr, Address address)" 4 .IX Item "char *sdr_pointer(Sdr sdr, Address address)" Returns a pointer to the indicated location in the heap \- a \*(L"heap pointer\*(R" \- or \&\s-1NULL\s0 if the indicated address is invalid. \s-1NOTE\s0 that this function \fIcannot be used\fR if the \s-1SDR\s0 does not reside in a shared memory region. .Sp Providing an alternative to using \fIsdr_read()\fR to retrieve objects into local memory, \fIsdr_pointer()\fR can help make SDR-based applications run very quickly, but it must be used \s-1WITH GREAT CAUTION\s0! Never use a direct pointer into the heap when not within a transaction, because you will have no assurance at any time that the object pointed to by that pointer has not changed (or is even still there). And \s-1NEVER\s0 de-reference a heap pointer in order to write directly into the heap: this makes transaction reversal impossible. Whenever writing to the \s-1SDR,\s0 always use \&\fIsdr_write()\fR. .IP "Address sdr_address(Sdr sdr, char *pointer)" 4 .IX Item "Address sdr_address(Sdr sdr, char *pointer)" Returns the address within the \s-1SDR\s0 heap of the indicated location, which must be (or be derived from) a heap pointer as returned by \fIsdr_pointer()\fR. Returns zero if the indicated location is not greater than the start of the heap mirror. \s-1NOTE\s0 that this function \fIcannot be used\fR if the \s-1SDR\s0 does not reside in a shared memory region. .IP "void sdr_get(sdr, variable, heap_pointer)" 4 .IX Item "void sdr_get(sdr, variable, heap_pointer)" \&\fIsdr_get()\fR is a macro that uses \fIsdr_read()\fR to load \fIvariable\fR from the \s-1SDR\s0 address given by \fIheap_pointer\fR; \fIheap_pointer\fR must be (or be derived from) a heap pointer as returned by \fIsdr_pointer()\fR. The size of \fIvariable\fR is used as the number of bytes to copy. .IP "void sdr_set(sdr, heap_pointer, variable)" 4 .IX Item "void sdr_set(sdr, heap_pointer, variable)" \&\fIsdr_set()\fR is a macro that uses \fIsdr_write()\fR to store \fIvariable\fR at the \s-1SDR\s0 address given by \fIheap_pointer\fR; \fIheap_pointer\fR must be (or be derived from) a heap pointer as returned by \fIsdr_pointer()\fR. The size of \fIvariable\fR is used as the number of bytes to copy. .SH "HEAP SPACE MANAGEMENT FUNCTIONS" .IX Header "HEAP SPACE MANAGEMENT FUNCTIONS" .IP "Object sdr_malloc(Sdr sdr, unsigned long size)" 4 .IX Item "Object sdr_malloc(Sdr sdr, unsigned long size)" Allocates a block of space from the of the indicated \s-1SDR\s0's heap. \fIsize\fR is the size of the block to allocate; the maximum size is 1/2 of the maximum address space size (i.e., 2G for a 32\-bit machine). Returns block address if successful, zero if block could not be allocated. .IP "Object sdr_insert(Sdr sdr, char *from, unsigned long size)" 4 .IX Item "Object sdr_insert(Sdr sdr, char *from, unsigned long size)" Uses \fIsdr_malloc()\fR to obtain a block of space of size \fIsize\fR and, if this allocation is successful, uses \fIsdr_write()\fR to copy \fIsize\fR bytes of data from memory at \fIfrom\fR into the newly allocated block. Returns block address if successful, zero if block could not be allocated. .IP "Object sdr_stow(sdr, variable)" 4 .IX Item "Object sdr_stow(sdr, variable)" \&\fIsdr_stow()\fR is a macro that uses \fIsdr_insert()\fR to insert a copy of \fIvariable\fR into the database. The size of \fIvariable\fR is used as the number of bytes to copy. .IP "int sdr_object_length(Sdr sdr, Object object)" 4 .IX Item "int sdr_object_length(Sdr sdr, Object object)" Returns the number of bytes of heap space allocated to the application data at \fIobject\fR. .IP "void sdr_free(Sdr sdr, Object object)" 4 .IX Item "void sdr_free(Sdr sdr, Object object)" Frees for subsequent re-allocation the heap space occupied by \fIobject\fR. .IP "void sdr_stage(Sdr sdr, char *into, Object from, int length)" 4 .IX Item "void sdr_stage(Sdr sdr, char *into, Object from, int length)" Like \fIsdr_read()\fR, this function will copy \fIlength\fR characters at \fIfrom\fR (a location in the heap of the indicated \s-1SDR\s0) to the memory location given by \fIinto\fR. Unlike \&\fIsdr_get()\fR, \fIsdr_stage()\fR requires that \fIfrom\fR be the address of some allocated object, not just any location within the heap. \fIsdr_stage()\fR, when called from within a transaction, notifies the \s-1SDR\s0 library that the indicated object may be updated later in the transaction; this enables the library to retrieve the object's size for later reference in validating attempts to write into some location within the object. If \fIlength\fR is zero, the object's size is privately retrieved by \s-1SDR\s0 but none of the object's content is copied into memory. .IP "long sdr_unused(Sdr sdr)" 4 .IX Item "long sdr_unused(Sdr sdr)" Returns number of bytes of heap space not yet allocated to either the large or small objects pool. .IP "void sdr_usage(Sdr sdr, SdrUsageSummary *summary)" 4 .IX Item "void sdr_usage(Sdr sdr, SdrUsageSummary *summary)" Loads the indicated SdrUsageSummary structure with a snapshot of the \s-1SDR\s0's usage status. SdrUsageSummary is defined by: .Sp .Vb 10 \& typedef struct \& { \& char sdrName[MAX_SDR_NAME + 1]; \& unsigned int sdrSize; \& unsigned int smallPoolSize; \& unsigned int smallPoolFreeBlockCount[SMALL_SIZES]; \& unsigned int smallPoolFree; \& unsigned int smallPoolAllocated; \& unsigned int largePoolSize; \& unsigned int largePoolFreeBlockCount[LARGE_ORDERS]; \& unsigned int largePoolFree; \& unsigned int largePoolAllocated; \& unsigned int unusedSize; \& } SdrUsageSummary; .Ve .IP "void sdr_report(SdrUsageSummary *summary)" 4 .IX Item "void sdr_report(SdrUsageSummary *summary)" Sends to stdout a printed summary of the \s-1SDR\s0's usage status. .IP "int sdr_heap_depleted(Sdr sdr)" 4 .IX Item "int sdr_heap_depleted(Sdr sdr)" A Boolean function: returns 1 if the total available space in the \s-1SDR\s0's heap (small pool free, large pool free, and unused) is less than 1/16 of the total size of the heap. Otherwise returns zero. .SH "HEAP SPACE USAGE TRACING" .IX Header "HEAP SPACE USAGE TRACING" If \s-1SDR_TRACE\s0 is defined at the time the \s-1SDR\s0 source code is compiled, the system includes built-in support for simple tracing of \s-1SDR\s0 heap space usage: heap space allocations are logged, and heap space deallocations are matched to logged allocations, \*(L"closing\*(R" them. This enables heap space leaks and some other kinds of \s-1SDR\s0 heap access problems to be readily investigated. .IP "int sdr_start_trace(Sdr sdr, int traceLogSize, char *traceLogAddress)" 4 .IX Item "int sdr_start_trace(Sdr sdr, int traceLogSize, char *traceLogAddress)" Begins an episode of \s-1SDR\s0 heap space usage tracing. \fItraceLogSize\fR is the number of bytes of shared memory to use for trace activity logging; the frequency with which \*(L"closed\*(R" trace log events must be deleted will vary inversely with the amount of memory allocated for the trace log. \&\fItraceLogAddress\fR is normally \s-1NULL,\s0 causing the trace system to allocate \&\fItraceLogSize\fR bytes of shared memory dynamically for trace logging; if non-NULL, it must point to \fItraceLogSize\fR bytes of shared memory that have been pre-allocated by the application for this purpose. Returns 0 on success, \-1 on any failure. .IP "void sdr_print_trace(Sdr sdr, int verbose)" 4 .IX Item "void sdr_print_trace(Sdr sdr, int verbose)" Prints a cumulative trace report and current usage report for \&\fIsdr\fR. If \fIverbose\fR is zero, only exceptions (notably, trace log events that remain open \*(-- potential \s-1SDR\s0 heap space leaks) are printed; otherwise all activity in the trace log is printed. .IP "void sdr_clear_trace(Sdr sdr)" 4 .IX Item "void sdr_clear_trace(Sdr sdr)" Deletes all closed trace log events from the log, freeing up memory for additional tracing. .IP "void sdr_stop_trace(Sdr sdr)" 4 .IX Item "void sdr_stop_trace(Sdr sdr)" Ends the current episode of \s-1SDR\s0 heap space usage tracing. If the shared memory used for the trace log was allocated by \fIsdr_start_trace()\fR, releases that shared memory. .SH "CATALOGUE FUNCTIONS" .IX Header "CATALOGUE FUNCTIONS" The \s-1SDR\s0 catalogue functions are used to maintain the catalogue of the names, types, and addresses of objects within an \s-1SDR. \s0 The catalogue service includes functions for creating, deleting and finding catalogue entries and a function for navigating through catalogue entries sequentially. .IP "void sdr_catlg(Sdr sdr, char *name, int type, Object object)" 4 .IX Item "void sdr_catlg(Sdr sdr, char *name, int type, Object object)" Associates \fIobject\fR with \fIname\fR in the indicated \s-1SDR\s0's catalogue and notes the \fItype\fR that was declared for this object. \fItype\fR is optional and has no significance other than that conferred on it by the application. .Sp The \s-1SDR\s0 catalogue is flat, not hierarchical like a directory tree, and all names must be unique. The length of \fIname\fR is limited to 15 characters. .IP "Object sdr_find(Sdr sdr, char *name, int *type)" 4 .IX Item "Object sdr_find(Sdr sdr, char *name, int *type)" Locates the Object associated with \fIname\fR in the indicated \s-1SDR\s0's catalogue and returns its address; also reports the catalogued type of the object in \&\fI*type\fR if \fItype\fR is non-NULL. Returns zero if no object is currently catalogued under this name. .IP "void sdr_uncatlg(Sdr sdr, char *name)" 4 .IX Item "void sdr_uncatlg(Sdr sdr, char *name)" Dissociates from \fIname\fR whatever object in the indicated \&\s-1SDR\s0's catalogue is currently catalogued under that name. .IP "Object sdr_read_catlg(Sdr sdr, char *name, int *type, Object *object, Object previous_entry)" 4 .IX Item "Object sdr_read_catlg(Sdr sdr, char *name, int *type, Object *object, Object previous_entry)" Used to navigate through catalogue entries sequentially. If \&\fIprevious_entry\fR is zero, reads the first entry in the indicated \s-1SDR\s0's catalogue; otherwise, reads the next catalogue entry following the one located at \fIprevious_entry\fR. In either case, returns zero if no such catalogue entry exists; otherwise, copies that entry's name, type, and catalogued object address into \fIname\fR, \&\fI*type\fR, and \fI*object\fR, and then returns the address of the catalogue entry (which may be used as \fIprevious_entry\fR in a subsequent call to \fIsdr_read_catlg()\fR). .SH "USER'S GUIDE" .IX Header "USER'S GUIDE" .IP "Compiling an \s-1SDR\s0 application" 4 .IX Item "Compiling an SDR application" Just be sure to \*(L"#include \*(R"sdr.h"" at the top of each source file that includes any \s-1SDR\s0 function calls. .Sp For \s-1UNIX\s0 applications, link with \*(L"\-lsdr\*(R". .IP "Loading an \s-1SDR\s0 application (VxWorks)" 4 .IX Item "Loading an SDR application (VxWorks)" .Vb 1 \& ld < "libsdr.o" .Ve .Sp After the library has been loaded, you can begin loading \s-1SDR\s0 applications. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIsdrlist\fR\|(3), \fIsdrstring\fR\|(3), \fIsdrtable\fR\|(3)