.\" 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::smlist 3" .TH ici::doc::pod3::smlist 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" smlist \- shared memory list management library .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #include "smlist.h" \& \& typedef int (*SmListCompareFn) \& (PsmPartition partition, PsmAddress eltData, void *argData); \& typedef void (*SmListDeleteFn) \& (PsmPartition partition, PsmAddress elt, void *argument); \& \& [see description for available functions] .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The smlist library provides functions to create, manipulate and destroy doubly-linked lists in shared memory. As with \fIlyst\fR\|(3), smlist uses two types of objects, \fIlist\fR objects and \&\fIelement\fR objects. However, as these objects are stored in shared memory which is managed by \fIpsm\fR\|(3), pointers to these objects are carried as PsmAddress values. A list knows how many elements it contains and what its first and last elements are. An element knows what list it belongs to and the elements before and after it in its list. An element also knows its content, which is normally the PsmAddress of some object in shared memory. .IP "PsmAddress sm_list_create(PsmPartition partition)" 4 .IX Item "PsmAddress sm_list_create(PsmPartition partition)" Create a new list object without any elements in it, within the memory segment identified by \fIpartition\fR. Returns the PsmAddress of the list, or 0 on any error. .IP "void sm_list_unwedge(PsmPartition partition, PsmAddress list, int interval)" 4 .IX Item "void sm_list_unwedge(PsmPartition partition, PsmAddress list, int interval)" Unwedge, as necessary, the mutex semaphore protecting shared access to the indicated list. For details, see the explanation of the \fIsm_SemUnwedge()\fR function in \fIplatform\fR\|(3). .IP "int sm_list_clear(PsmPartition partition, PsmAddress list, SmListDeleteFn delete, void *argument);" 4 .IX Item "int sm_list_clear(PsmPartition partition, PsmAddress list, SmListDeleteFn delete, void *argument);" Empty a list. Frees each element of the list. If the \fIdelete\fR function is non-NULL, that function is called once for each freed element; when called, that function is passed the PsmAddress of the list element and the \fIargument\fR pointer passed to \fIsm_list_clear()\fR. Returns 0 on success, \&\-1 on any error. .IP "int sm_list_destroy(PsmPartition partition, PsmAddress list, SmListDeleteFn delete, void *argument);" 4 .IX Item "int sm_list_destroy(PsmPartition partition, PsmAddress list, SmListDeleteFn delete, void *argument);" Destroy a list. Same as \fIsm_list_clear()\fR, but additionally frees the list structure itself. Returns 0 on success, \-1 on any error. .IP "int sm_list_user_data_set(PsmPartition partition, PsmAddress list, PsmAddress userData);" 4 .IX Item "int sm_list_user_data_set(PsmPartition partition, PsmAddress list, PsmAddress userData);" Set the value of a user data variable associated with the list as a whole. This value may be used for any purpose; it is typically used to store the PsmAddress of a shared memory block containing data (e.g., state data) which the user wishes to associate with the list. Returns 0 on success, \-1 on any error. .IP "PsmAddress sm_list_user_data(PsmPartition partition, PsmAddress list);" 4 .IX Item "PsmAddress sm_list_user_data(PsmPartition partition, PsmAddress list);" Return the value of the user data variable associated with the list as a whole, or 0 on any error. .IP "int sm_list_length(PsmPartition partition, PsmAddress list);" 4 .IX Item "int sm_list_length(PsmPartition partition, PsmAddress list);" Return the number of elements in the list. .IP "PsmAddress sm_list_insert(PsmPartition partition, PsmAddress list, PsmAddress data, SmListCompareFn compare, void *dataBuffer);" 4 .IX Item "PsmAddress sm_list_insert(PsmPartition partition, PsmAddress list, PsmAddress data, SmListCompareFn compare, void *dataBuffer);" Create a new list element whose data value is \fIdata\fR and insert it into the given list. If the \fIcompare\fR function is \s-1NULL,\s0 the new list element is simply appended to the list; otherwise, the new list element is inserted after the last element in the list whose data value is \*(L"less than or equal to\*(R" the data value of the new element (in \fIdataBuffer\fR) according to the collating sequence established by \fIcompare\fR. Returns the PsmAddress of the new element, or 0 on any error. .IP "PsmAddress sm_list_insert_first(PsmPartition partition, PsmAddress list, PsmAddress data);" 4 .IX Item "PsmAddress sm_list_insert_first(PsmPartition partition, PsmAddress list, PsmAddress data);" .PD 0 .IP "PsmAddress sm_list_insert_last(PsmPartition partition, PsmAddress list, PsmAddress data);" 4 .IX Item "PsmAddress sm_list_insert_last(PsmPartition partition, PsmAddress list, PsmAddress data);" .PD Create a new list element and insert it at the start/end of a list. Returns the PsmAddress of the new element on success, or 0 on any error. Disregards any established sort order in the list. .IP "PsmAddress sm_list_insert_before(PsmPartition partition, PsmAddress elt, PsmAddress data);" 4 .IX Item "PsmAddress sm_list_insert_before(PsmPartition partition, PsmAddress elt, PsmAddress data);" .PD 0 .IP "PsmAddress sm_list_insert_after(PsmPartition partition, PsmAddress elt, PsmAddress data);" 4 .IX Item "PsmAddress sm_list_insert_after(PsmPartition partition, PsmAddress elt, PsmAddress data);" .PD Create a new list element and insert it before/after a given element. Returns the PsmAddress of the new element on success, or 0 on any error. Disregards any established sort order in the list. .IP "int sm_list_delete(PsmPartition partition, PsmAddress elt, SmListDeleteFn delete, void *argument);" 4 .IX Item "int sm_list_delete(PsmPartition partition, PsmAddress elt, SmListDeleteFn delete, void *argument);" Delete an element from a list. If the \fIdelete\fR function is non-NULL, that function is called upon deletion of \fIelt\fR; when called, that function is passed the PsmAddress of the list element and the \fIargument\fR pointer passed to \fIsm_list_delete()\fR. Returns 0 on success, \-1 on any error. .IP "PsmAddress sm_list_first(PsmPartition partition, PsmAddress list);" 4 .IX Item "PsmAddress sm_list_first(PsmPartition partition, PsmAddress list);" .PD 0 .IP "PsmAddress sm_list_last(PsmPartition partition, PsmAddress list);" 4 .IX Item "PsmAddress sm_list_last(PsmPartition partition, PsmAddress list);" .PD Return the PsmAddress of the first/last element in \fIlist\fR, or 0 on any error. .IP "PsmAddress sm_list_next(PsmPartition partition, PsmAddress elt);" 4 .IX Item "PsmAddress sm_list_next(PsmPartition partition, PsmAddress elt);" .PD 0 .IP "PsmAddress sm_list_prev(PsmPartition partition, PsmAddress elt);" 4 .IX Item "PsmAddress sm_list_prev(PsmPartition partition, PsmAddress elt);" .PD Return the PsmAddress of the element following/preceding \fIelt\fR in that element's list, or 0 on any error. .IP "PsmAddress sm_list_search(PsmPartition partition, PsmAddress elt, SmListCompareFn compare, void *dataBuffer);" 4 .IX Item "PsmAddress sm_list_search(PsmPartition partition, PsmAddress elt, SmListCompareFn compare, void *dataBuffer);" Search a list for an element whose data matches the data in \fIdataBuffer\fR. If the \fIcompare\fR function is non-NULL, the list is assumed to be sorted in the order implied by that function and the function is automatically called once for each element of the list until it returns a value that is greater than or equal to zero (where zero indicates an exact match and a value greater than zero indicates that the list contains no matching element); each time \fIcompare\fR is called it is passed the PsmAddress that is the element's data value and the \fIdataBuffer\fR value passed to \fIsm_list_search()\fR. If \fIcompare\fR is \s-1NULL,\s0 then the entire list is searched until an element is located whose data value is equal to ((PsmAddress) \fIdataBuffer\fR). Returns the PsmAddress of the matching element if one is found, 0 otherwise. .IP "PsmAddress sm_list_list(PsmPartition partition, PsmAddress elt);" 4 .IX Item "PsmAddress sm_list_list(PsmPartition partition, PsmAddress elt);" Return the PsmAddress of the list to which \fIelt\fR belongs, or 0 on any error. .IP "PsmAddress sm_list_data(PsmPartition partition, PsmAddress elt);" 4 .IX Item "PsmAddress sm_list_data(PsmPartition partition, PsmAddress elt);" Return the PsmAddress that is the data value for \fIelt\fR, or 0 on any error. .IP "PsmAddress sm_list_data_set(PsmPartition partition, PsmAddress elt, PsmAddress data);" 4 .IX Item "PsmAddress sm_list_data_set(PsmPartition partition, PsmAddress elt, PsmAddress data);" Set the data value for \fIelt\fR to \fIdata\fR, replacing the original value. Returns the original data value for \fIelt\fR, or 0 on any error. The original data value for \fIelt\fR may or may not have been the address of an object in memory; even if it was, that object was \&\s-1NOT\s0 deleted. .Sp Warning: changing the data value of an element of an ordered list may ruin the ordering of the list. .SH "USAGE" .IX Header "USAGE" A user normally creates an element and adds it to a list by doing the following: .ie n .IP "1" 4 .el .IP "\f(CW1\fR" 4 .IX Item "1" obtaining a shared memory block to contain the element's data; .ie n .IP "2" 4 .el .IP "\f(CW2\fR" 4 .IX Item "2" converting the shared memory block's PsmAddress to a character pointer; .ie n .IP "3" 4 .el .IP "\f(CW3\fR" 4 .IX Item "3" using that pointer to write the data into the shared memory block; .ie n .IP "4" 4 .el .IP "\f(CW4\fR" 4 .IX Item "4" calling one of the \fIsm_list_insert\fR functions to create the element structure (which will include the shared memory block's PsmAddress) and insert it into the list. .PP When inserting elements or searching a list, the user may optionally provide a compare function of the form: .PP .Vb 2 \& int user_comp_name(PsmPartition partition, PsmAddress eltData, \& void *dataBuffer); .Ve .PP When provided, this function is automatically called by the smlist function being invoked; when the function is called it is passed the content of a list element (\fIeltData\fR, nominally the PsmAddress of an item in shared memory) and an argument, \fIdataBuffer\fR, which is nominally the address in local memory of some other item in the same format. The user-supplied function normally compares some key values of the two data items and returns 0 if they are equal, an integer less than 0 if \fIeltData\fR's key value is less than that of \fIdataBuffer\fR, and an integer greater than 0 if \fIeltData\fR's key value is greater than that of \&\fIdataBuffer\fR. These return values will produce a list in ascending order. If the user desires the list to be in descending order, the function must reverse the signs of these return values. .PP When deleting an element or destroying a list, the user may optionally provide a delete function of the form: .PP .Vb 1 \& void user_delete_name(PsmPartition partition, PsmAddress elt, void *argData) .Ve .PP When provided, this function is automatically called by the smlist function being invoked; when the function is called it is passed the address of a list element (\fIelt\fR and an argument, \fIargData\fR, which if non-NULL is normally the address in local memory of a data item providing context for the list element deletion. The user-supplied function performs any application-specific cleanup associated with deleting the element, such as freeing the element's content data item and/or other memory associated with the element. .SH "EXAMPLE" .IX Header "EXAMPLE" For an example of the use of smlist, see the file smlistsh.c in the utils directory of \s-1ICI.\s0 .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIlyst\fR\|(3), \fIplatform\fR\|(3), \fIpsm\fR\|(3)