1/* 2 * $Id: atp_bufs.c,v 1.5 2009-10-13 22:55:37 didg Exp $ 3 * 4 * Copyright (c) 1990,1991 Regents of The University of Michigan. 5 * All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and distribute this software and 8 * its documentation for any purpose and without fee is hereby granted, 9 * provided that the above copyright notice appears in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation, and that the name of The University 12 * of Michigan not be used in advertising or publicity pertaining to 13 * distribution of the software without specific, written prior 14 * permission. This software is supplied as is without expressed or 15 * implied warranties of any kind. 16 * 17 * Research Systems Unix Group 18 * The University of Michigan 19 * c/o Mike Clark 20 * 535 W. William Street 21 * Ann Arbor, Michigan 22 * +1-313-763-0525 23 * netatalk@itd.umich.edu 24 */ 25 26/* 27 * Our own memory maintenance for atp 28*/ 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif /* HAVE_CONFIG_H */ 33 34#include <stdlib.h> 35#include <string.h> 36#include <errno.h> 37 38#include <sys/types.h> 39#include <sys/time.h> 40#include <sys/socket.h> 41 42#include <netatalk/at.h> 43#include <atalk/atp.h> 44#include "atp_internals.h" 45 46#define N_MORE_BUFS 10 47 48static struct atpbuf *free_list = NULL; /* free buffers */ 49 50#ifdef EBUG 51static int numbufs = 0; 52#endif /* EBUG */ 53 54/* only call this when the free_list is empty... 55 * N_MORE_BUFS must be >= one 56*/ 57static int more_bufs(void) 58{ 59 int i; 60 char *mem; 61 struct atpbuf *bp; 62 63 /* get the whole chunk in one malloc call 64 */ 65 if (( mem = malloc( N_MORE_BUFS * sizeof( struct atpbuf ))) == NULL ) { 66 errno = ENOBUFS; 67 return -1; 68 } 69 /* now split into separate bufs 70 */ 71 bp = free_list = (struct atpbuf *) mem; 72 for ( i = 1; i < N_MORE_BUFS; ++i ) { 73 bp->atpbuf_next = (struct atpbuf *) ( mem += sizeof( struct atpbuf )); 74 bp = bp->atpbuf_next; 75 } 76 bp->atpbuf_next = NULL; 77 78 return 0; 79} 80 81 82#ifdef EBUG 83void atp_print_bufuse(ATP ah, char *s) 84{ 85 struct atpbuf *bp; 86 int i, sentcount, incount, respcount; 87 88 sentcount = 0; 89 for ( bp = ah->atph_sent; bp != NULL; bp = bp->atpbuf_next ) { 90 ++sentcount; 91 for ( i = 0; i < 8; ++i ) { 92 if ( bp->atpbuf_info.atpbuf_xo.atpxo_packet[ i ] != NULL ) { 93 ++sentcount; 94 } 95 } 96 } 97 98 if ( ah->atph_reqpkt != NULL ) { 99 ++sentcount; 100 } 101 102 103 incount = 0; 104 for ( bp = ah->atph_queue; bp != NULL; bp = bp->atpbuf_next, ++incount ); 105 106 respcount = 0; 107 for ( i = 0; i < 8; ++i ) { 108 if ( ah->atph_resppkt[ i ] != NULL ) { 109 ++respcount; 110 } 111 } 112 113 printf( "<%d> %s: bufs total %d sent %d incoming %d req %d resp %d\n", 114 getpid(), s, numbufs, sentcount, incount, 115 ( ah->atph_reqpkt != NULL ) ? 1: 0, respcount ); 116} 117#endif /* EBUG */ 118 119 120struct atpbuf *atp_alloc_buf(void) 121{ 122 struct atpbuf *bp; 123 124 if ( free_list == NULL && more_bufs() ) return NULL; 125 126 bp = free_list; 127 free_list = free_list->atpbuf_next; 128#ifdef EBUG 129 ++numbufs; 130#endif /* EBUG */ 131 return bp; 132} 133 134 135int atp_free_buf(struct atpbuf *bp) 136{ 137 if ( bp == NULL ) { 138 return -1; 139 } 140 bp->atpbuf_next = free_list; 141 free_list = bp; 142#ifdef EBUG 143 --numbufs; 144#endif /* EBUG */ 145 return 0; 146} 147 148 149