<< Previous | Next >>

pmovebetween

void * pmovebetween( Pool_t * p, void * e, void * d, void * f );

Description

Atomically remove allocated element "e" and re-insert it between allocated elements "d" and "f." "Atomically" means that the POOL_IPSET level is used to lock out other CPU contexts from altering the pool while this operation is in progress. In addition, "d" and "f" are checked to ensure that the following conditions still hold:

   

pprev(p, f) == d

and

   

pnext(p, d) == f

in other words, "f" follows "d." This is useful since your application may have determined "d" and "f" some time ago, but in the meantime some other task may have re-ordered the queue or deleted these elements. In this case, the return value will be null. Your application should then re-evaluate the appropriate queue elements and retry this function.

The pool MUST be set to being a linked pool by using:

   

pool_link(p, <non-zero>)

Otherwise the results are undefined.

Parameters

p
Pool handle structure, as previously passed to pool_init().

e
Address of element to move, obtained by, e.g., plast(). This must be an allocated element in the given pool; otherwise, the results are undefined. If null, then the last element is implied (i.e., whatever plast() would return). If there are no elements at all, or this parameter does not point to a valid allocated element, then the results are undefined (and probably catastrophic).

If e == d or e == f, then there is no action except to check whether "f" follows "d." This parameter may refer to an unlinked (but allocated) element.

d
First reference element. The element "e" will be inserted after this element. On entry, it must be true that pnext(p, d) == f. Otherwise, null is returned. If this parameter is null, then "f" must point to the first element in the list, and "e" is inserted at the start of the list.

f
Second reference element. The element "e" will be inserted before this element. On entry, it must be true that pprev(p, f) == d. Otherwise, null is returned. If this parameter is null, then "d" must point to the last element in the list, and "e" is inserted at the end of the list.

NOTE If both "d" and "f" are null, then it must be true that there are no allocated elements in the linked list, and the element "e" is added as the only element in the list. This proviso only obtains when the element "e" is initially allocated from an empty pool with:
pool_link(p, POOL_LINKED_BY_APP)

The allocated element is not in the linked list of allocated elements.

Return Value

Returns the parameter value "e," unless "e" was null; in which case the value of plast(), if called at function entry, would be returned. If the initial conditions for "d" and "f" do not hold, then null is returned with no further action.

Examples

   

void * d, * e, * f;

e = plast(p);                    // element to move
f = pnext(p, d = pfirst(p));     // d, f are first 2 elements
pmovebetween(p, e, d, f);

Library

POOL.LIB

See Also

pool_init, pool_link, plast, pfirst, pnext, pprev, preorder


Dynamic C Functions << Previous | Next >> rabbit.com