home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name isreserv -- Allocate a block and reserve space for use
- * in an ISR or intervention function.
- *
- * Synopsis ercode = isreserv(reserve,blksize,ppblock);
- *
- * int ercode Success code. Possible values include:
- * IS_OK -- Success.
- * IS_NO_MEMORY -- Insufficient memory.
- * IS_RANGE -- reserve or blksize is
- * invalid.
- * size_t reserve Size of space to reserve for use
- * in an ISR.
- * size_t blksize Size of block to allocate via
- * malloc().
- * char **ppblock Address of pointer to receive
- * address of block allocated via
- * malloc(), or to receive NULL if
- * failure.
- *
- * Description This function allocates a block of space via malloc() in
- * such a way that the amount of space specified by
- * "reserve" is available for later allocation from an ISR
- * or intervention function.
- *
- * In the T, S, and M memory models of Turbo C, you should
- * use the resulting allocated block as the stack(s) for
- * the stack of the ISR or intervention function in
- * question. In the C, L, and H memory models of Turbo C,
- * you can place the ISR stack or intervention function
- * stack wherever you wish; "blksize" can be as small as 1.
- *
- * "size_t" is defined in the standard header file
- * STDLIB.H.
- *
- * Method First allocate the reserved block; then allocate blocks
- * of size "blksize" until one is located at a higher
- * memory address than the reserved block. This high block
- * is the one returned. The reserved block and the trial
- * blocks are all freed.
- *
- * Returns ercode Success code. Possible values include:
- * IS_OK -- Success.
- * IS_NO_MEMORY -- Insufficient memory.
- * IS_RANGE -- reserve or blksize is
- * invalid.
- * *pblock Address of block allocated via
- * malloc(), or NULL if failure.
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
-
- #include <stdlib.h> /* For malloc(), free(), and size_t. */
- #include <bintrupt.h>
-
- int isreserv(reserve,blksize,ppblock)
- size_t reserve,blksize;
- char **ppblock;
- {
- void *p_reserve,*ptrial,*pprev;
-
- /* We may allocate many blocks of size "blksize", and in each one */
- /* store the address of its predecessor, so we can clean up. */
- /* Therefore each block must be large enough to contain a pointer;*/
- /* "trial_size" is the size we must use. */
-
- size_t trial_size = max(blksize,sizeof(void *));
-
- *ppblock = NULL; /* In case of premature error. */
-
- if (blksize <= 0 || reserve <= 0) /* Range check. */
- return IS_RANGE;
-
- /* Allocate reserved block. */
- if (NULL == (p_reserve = malloc(reserve)))
- return IS_NO_MEMORY;
-
- /* Search for a block of size "blksize" until we find one at a */
- /* higher address than the reserved block or until no more memory */
- /* is available. In each block, save a pointer to predecessor. */
-
- pprev = NULL;
- while ( NULL != (ptrial = malloc(trial_size))
- && utplong(ptrial) <= utplong(p_reserve))
- {
- * (void **) ptrial = pprev;
- pprev = ptrial;
- }
-
- *ppblock = ptrial; /* Return NULL if no success */
- /* before we ran out of memory; */
- /* otherwise return successful */
- /* trial block. */
-
- while (NULL != (ptrial = pprev)) /* Free the chain of */
- { /* temporary blocks. */
- pprev = * (void **) ptrial;
- free(ptrial);
- }
- free(p_reserve); /* Free the reserved block. */
-
- return (*ppblock ? IS_OK : IS_NO_MEMORY);
- }