Chapter Contents |
Previous |
Next |
pool |
Portability: | SAS/C extension |
SYNOPSIS | |
DESCRIPTION | |
RETURN VALUE | |
ERRORS | |
DIAGNOSTICS | |
IMPLEMENTATION | |
EXAMPLE | |
RELATED FUNCTIONS | |
SEE ALSO |
SYNOPSIS |
#include <pool.h> int pool(POOL_t *p, unsigned eltsize, unsigned initial, unsigned extend);
DESCRIPTION |
pool
creates a storage pool from which elements of a given size can be quickly
allocated and freed. The arguments are as follows:
If
initial
is 0,
the
pool
routine computes a convenient
initial number of elements. If
extend
is 0, it is set equal to
initial
.
In a situation that requires allocation of many items
of the same size, using a storage pool is more efficient than using
malloc
in terms of execution time. It also can
be more efficient in terms of storage usage if the
initial
and
extend
values are reasonably
chosen.
RETURN VALUE |
The return value is 1 if a pool is successfully
created, or 0 if it is not. If a pool is created, its address and other information
is stored in the area addressed by the first argument to
pool
.
ERRORS |
User ABEND 1205 or 1206 may occur if memory management data areas are overlaid.
DIAGNOSTICS |
The pool pointer is set to 0 if there is no storage available for the new pool.
IMPLEMENTATION |
Under an XA or ESA operating system, memory allocated
by
pool
resides above the 16-megabyte line
for programs that run in 31-bit addressing mode.
The initial pool storage, as well as additional storage
for extending the pool, is obtained by calling
malloc
. The performance of
palloc
and
pfree
is improved because the frequency
of calls to
malloc
and
free
is thereby reduced.
EXAMPLE |
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <pool.h> #define WORD_LENGTH 24 #define BUFFER_LENGTH 255 #define DELIMITERS " +-*/&=!%^*`~.,;:|?"'{}[]<>()\a\b\f\n\r\t\v" typedef struct tagLINE { struct tagLINE *next; int number; int count; } line_t; typedef struct tagWORD{ struct tagWORD *left, *right; line_t *first_line, *last_line; char token[WORD_LENGTH+1]; } word_t; static POOL_t word_pool; static POOL_t line_pool; static word_t *word_tree = NULL; static word_t *alloc_word(const char *); static line_t *alloc_line(int); static void add_to_xref(const char *, int); static word_t *find_word(word_t *, word_t *); static void add_line(word_t *, int); static void add_word(word_t **, word_t *); static void print_xref(word_t *); static void print_word(word_t *); /* Read a file of text, such as this file, from stdin. Separate */ /* each line of input into tokens. Write a sorted */ /* "cross-reference" of the file to stdout, having one line for */ /* each distinct token. For each token, show the line number(s) */ /* on which the token is found. If the token appears more than */ /* once on a line, show the number of times it appears on that */ /* line. */ /* */ /* Here's a sample of the output produced by this program, using */ /* this file as input: */ /* */ /* stdin : 36, 46, 84, 85(2), 93, 96, 97 */ /* stdio : 1, 47 */ /* stdlib : 3, 48 */ /* stdout : 38, 49, 295, 304, 305 */ /* storage : 50, 107 */ main() { int success; int line_number; char input_buffer[BUFFER_LENGTH+2]; /* Allocate a pool of binary tree elements */ /* to hold the "words". */ success = pool(&word_pool, sizeof(word_t), 100, 100); if (!success) { puts("Can't allocate word pool."); exit(4); } /* Allocate a pool of list elements to hold the */ /* line numbers. */ success = pool(&line_pool, sizeof(line_t), 500, 250); if (!success) { puts("Can't allocate line count pool."); exit(4); } /* Read each line in the input file. Pick out tokens */ /* and add them to the cross-reference tree. */ line_number = 0; fgets(input_buffer, BUFFER_LENGTH, stdin); while (!feof(stdin) && !ferror(stdin)) { char *token; line_number += 1; token = strtok(input_buffer, DELIMITERS); while (token) { add_to_xref(token, line_number); token = strtok(NULL, DELIMITERS); } fgets(input_buffer, BUFFER_LENGTH, stdin); } if (ferror(stdin)) { puts("Error reading stdin."); exit(8); } /* Print the cross-reference, one word per line. */ print_xref(word_tree); /* Free the storage pools and exit. */ pdel(&word_pool); pdel(&line_pool); exit(0); } /* Allocate a new word_t element from the word pool. */ /* Initialize all members and save a copy of the token, */ /* truncating the token if it's longer than WORD_LENGTH. */ /* Exit with an error message if palloc fails. */ static word_t *alloc_word(const char *token) { word_t *new_word; new_word = (word_t *) palloc(&word_pool); if (new_word == NULL) { puts("Can't allocate element from word pool"); exit(12); } new_word->left = NULL; new_word->right = NULL; new_word->first_line = NULL; new_word->last_line = NULL; strncpy(new_word->token, token, WORD_LENGTH); new_word->token[WORD_LENGTH] = '\0'; return new_word; } /* Allocate a new line_t element from the line pool. Initialize */ /* all members. Exit with an error message if palloc fails. */ static line_t *alloc_line(int line_number) { line_t *new_line; new_line = (line_t *) palloc(&line_pool); if (new_line == NULL) { puts("Can't allocate element from line pool"); exit(12); } new_line->next = NULL; new_line->number = line_number; new_line->count = 1; return new_line; } /* Add this instance of the word to the cross-reference tree. */ static void add_to_xref(const char *token, int line_number) { word_t *word, *new_word; /* Go ahead and copy the token to a word_t element. */ new_word = alloc_word(token); /* If the word is already in the tree, free the */ /* word_t element we just allocated and add the */ /* line number to the word_t element we found. */ /* Otherwise, add the new word_t element to the */ /* tree and add this line number. */ word = find_word(word_tree, new_word); if (word != NULL) { pfree(&word_pool, new_word); add_line(word, line_number); } else { add_word(&word_tree, new_word); add_line(new_word, line_number); } } /* Search for the word in the word binary tree. */ /* Return NULL if the word is not on the tree. */ static word_t *find_word(word_t *subtree, word_t *new_word) { word_t *word; if (subtree == NULL) return NULL; word = find_word(subtree->left, new_word); if (word != NULL) return word; if (strcmp(subtree->token, new_word->token) == 0) return subtree; word = find_word(subtree->right, new_word); if (word != NULL) return word; return NULL; } /* Add an instance of the word for this line. If */ /* the word has already been used on this line, */ /* simply increment the count for this line number. */ /* Otherwise add a new line_t element for this line */ /* number. */ static void add_line(word_t *word, int line_number) { line_t *line; if (word->last_line != NULL && word->last_line->number == line_number) word->last_line->count += 1; else { line = alloc_line(line_number); if (word->first_line == NULL) word->first_line = line; else word->last_line->next = line; word->last_line = line; } } /* Add the new word_t element to the binary tree. */ static void add_word(word_t **subtree, word_t *new_word) { int relation; if (*subtree == NULL) { *subtree = new_word; return; } relation = strcmp((*subtree)->token, new_word->token); if (relation > 0) add_word(&((*subtree)->left), new_word); else if (relation < 0) add_word(&((*subtree)->right), new_word); else abort(); /* impossible condition */ } /* Print a list of the words in alphabetical order. Beside each */ /* word print the line numbers on which the word appears. If the */ /* word appears more than once on a line, print the line number */ /* followed by a repeat count in parentheses. For example, if */ /* the word appears twice on line number 20, print "20(2)". */ static void print_xref(word_t *subtree) { if (subtree != NULL) { print_xref(subtree->left); print_word(subtree); print_xref(subtree->right); } } /* Print the line number info for a single word. */ static void print_word(word_t *word) { line_t *line; char comma; printf("%-24s: ", word->token); comma = 0; for (line = word->first_line; line != NULL; line = line->next) { if (comma) fputs(", ", stdout); comma = 1; printf("%d", line->number); if (line->count > 1) printf("(%d)", line->count); } putchar('\n'); if (ferror(stdout)) { puts("Error writing to stdout."); exit(12); } }
RELATED FUNCTIONS |
malloc
,
palloc
,
pdel
,
pfree
SEE ALSO |
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.