www.pudn.com > streamrtp.rar > bufpool.c
/*------------------------------------------------------------------------- * bufpool.c - bufpoolinit, bufpoolgetbuf, bufpoolfreebuf, bufpooldestroy * * Bufferpool design is adapted from: * * Comer, D. E., Operating System Design: The XINU Approach, Prentice-Hall, * 1984. *------------------------------------------------------------------------- */ #include#include #include /*------------------------------------------------------------------------ * bufpoolinit - allocate memory for a pool of fixed-size buffers * and link together *------------------------------------------------------------------------ */ int bufpoolinit(struct bufpool *pbp, int bufsize, int numbufs) { char *where; if (bufsize < BPMINB) return ERROR; where = pbp->bp_base = (char *) malloc((bufsize + sizeof(struct bufpool *)) * numbufs); if (where == NULL) return ERROR; pbp->bp_total = numbufs; pbp->bp_next = where; pbp->bp_size = bufsize; sem_init(&pbp->bp_sem, FALSE, numbufs); pthread_mutex_init(&pbp->bp_mutex, NULL); bufsize += sizeof(struct bufpool *); for (numbufs-- ; numbufs > 0 ; numbufs--, where += bufsize) *((int *) where ) = (int) (where + bufsize); *((int *) where) = (int) NULL; return OK; } /*------------------------------------------------------------------------ * bufpoolgetbuf - get a fixed size buffer *------------------------------------------------------------------------ */ int * bufpoolgetbuf(struct bufpool *pbp) { int *buf; if (sem_trywait(&pbp->bp_sem) != 0) return NULL; if (pthread_mutex_lock(&pbp->bp_mutex) != 0) { sem_post(&pbp->bp_sem); return NULL; } buf = (int *) pbp->bp_next; pbp->bp_next = (char *) *buf; pthread_mutex_unlock(&pbp->bp_mutex); *buf = (int) pbp; return buf + 1; } /*------------------------------------------------------------------------ * bufpoolfreebuf - free a buffer that was allocated from a pool by getbuf *------------------------------------------------------------------------ */ void bufpoolfreebuf(void *vbuf) { int *buf = (int *) vbuf; struct bufpool *pbp; pbp = (struct bufpool *) *(--buf); pthread_mutex_lock(&pbp->bp_mutex); *buf = (int) pbp->bp_next; pbp->bp_next = (char *) buf; pthread_mutex_unlock(&pbp->bp_mutex); sem_post(&pbp->bp_sem); } /*------------------------------------------------------------------------ * bufpooldestroy - destroy a pool of buffers *------------------------------------------------------------------------ */ int bufpooldestroy(struct bufpool *pbp) { int i; if (pbp == NULL) return ERROR; for (i = 0; i < pbp->bp_total; i++) sem_wait(&pbp->bp_sem); free(pbp->bp_base); sem_destroy(&pbp->bp_sem); pthread_mutex_destroy(&pbp->bp_mutex); return OK; }