LTP GCOV extension - code coverage report
Current view: directory - work/ustr - ustr-pool-code.h
Test: Ustr coverage
Date: 2008-02-26 Instrumented lines: 133
Code covered: 100.0 % Executed lines: 133

       1                 : /* Copyright (c) 2007 James Antill -- See LICENSE file for terms. */
       2                 : 
       3                 : #ifndef USTR_POOL_H
       4                 : #error " You should have already included ustr-pool.h, or just include ustr.h."
       5                 : #endif
       6                 : 
       7                 : struct Ustr__pool_ll_node
       8                 : {
       9                 :  struct Ustr__pool_ll_node *next;
      10                 :  void *ptr;
      11                 : };
      12                 : 
      13                 : struct Ustr__pool_ll_base
      14                 : { /* "simple" pool implementation */
      15                 :  struct Ustr_pool cbs;
      16                 :  struct Ustr__pool_ll_node *beg;
      17                 :  
      18                 :  struct Ustr__pool_ll_base *sbeg; /* wasting a lot of space for sub pools */
      19                 :  struct Ustr__pool_ll_base *base;
      20                 :  struct Ustr__pool_ll_base *next;
      21                 :  struct Ustr__pool_ll_base *prev;
      22                 : 
      23                 :  unsigned int free_num : 30; /* how many nodes we search to free */
      24                 : 
      25                 :  unsigned int call_realloc : 1;
      26                 : };
      27                 : 
      28                 : #define USTR__POOL_LL_SIB_NULL ((struct Ustr__pool_ll_base *) 0)
      29                 : 
      30                 : USTR_CONF_e_PROTO void *ustr__pool_ll_sys_malloc(struct Ustr_pool *, size_t)
      31                 :     USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_A()
      32                 :     USTR__COMPILE_ATTR_MALLOC();
      33                 : USTR_CONF_e_PROTO
      34                 : void *ustr__pool_ll_sys_realloc(struct Ustr_pool *, void *, size_t, size_t)
      35                 :     USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_L((1))
      36                 :     USTR__COMPILE_ATTR_MALLOC();
      37                 : USTR_CONF_e_PROTO void ustr__pool_ll_sys_free(struct Ustr_pool *, void *)
      38                 :     USTR__COMPILE_ATTR_NONNULL_L((1));
      39                 : 
      40                 : USTR_CONF_e_PROTO
      41                 : struct Ustr_pool *ustr__pool_ll_make_subpool(struct Ustr_pool *)
      42                 :     USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_MALLOC();
      43                 : USTR_CONF_e_PROTO void ustr__pool_ll__clear(struct Ustr__pool_ll_base *, int);
      44                 : USTR_CONF_e_PROTO void ustr__pool_ll_clear(struct Ustr_pool *)
      45                 :     USTR__COMPILE_ATTR_NONNULL_A();
      46                 : USTR_CONF_e_PROTO void ustr__pool_ll__free(struct Ustr__pool_ll_base *, int);
      47                 : USTR_CONF_e_PROTO void ustr__pool_ll_free(struct Ustr_pool *);
      48                 : 
      49                 : USTR_CONF_i_PROTO void *ustr__pool_ll_sys_malloc(struct Ustr_pool *p,size_t len)
      50             868 : {
      51             868 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
      52                 :   struct Ustr__pool_ll_node *np;
      53             868 :   void *ret = USTR_CONF_MALLOC(len);
      54                 : 
      55             225 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
      56                 :                                             sizeof(struct Ustr__pool_ll_base)));
      57                 :   
      58             868 :   if (!ret)
      59              96 :     return (ret);
      60                 : 
      61             772 :   if (!(np = USTR_CONF_MALLOC(sizeof(struct Ustr__pool_ll_node))))
      62                 :   {
      63               4 :     USTR_CONF_FREE(ret);
      64               4 :     return (0);
      65                 :   }
      66                 : 
      67             768 :   np->next = sip->beg;
      68             768 :   sip->beg = np;
      69             768 :   np->ptr  = ret;
      70                 :   
      71             768 :   return (ret);
      72                 : }
      73                 : 
      74                 : USTR_CONF_i_PROTO
      75                 : void *ustr__pool_ll_sys_realloc(struct Ustr_pool *p, void *old,
      76                 :                                 size_t olen, size_t nlen)
      77             250 : {
      78             250 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
      79             250 :   void *ret = 0;
      80                 : 
      81              53 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
      82                 :                                             sizeof(struct Ustr__pool_ll_base)));
      83             119 :   USTR_ASSERT((old && sip->beg && sip->beg->ptr) || !olen);
      84              53 :   ustr_assert(olen ? USTR_CNTL_MALLOC_CHECK_MEM_MINSZ(old, olen) :
      85                 :               (!old || USTR_CNTL_MALLOC_CHECK_MEM(old)));
      86                 : 
      87             250 :   if (!nlen)
      88               4 :     ++nlen;
      89                 :   
      90             369 :   if (olen && (sip->beg->ptr == old) && sip->call_realloc)
      91                 :   { /* let the last allocated Ustrp grow/shrink */
      92             226 :     if ((ret = USTR_CONF_REALLOC(old, nlen)))
      93             192 :       sip->beg->ptr = ret;
      94                 :   }
      95              24 :   else if (olen >= nlen) /* always allow reductions/nothing */
      96                 :   {
      97               2 :     USTR__CNTL_MALLOC_CHECK_FIXUP_REALLOC(old, nlen);
      98               4 :     return (old);
      99                 :   }
     100              20 :   else if ((ret = ustr__pool_ll_sys_malloc(p, nlen)))
     101              16 :     memcpy(ret, old, olen);
     102                 :   
     103             246 :   return (ret);
     104                 : }
     105                 : 
     106                 : USTR_CONF_i_PROTO
     107                 : void ustr__pool_ll_sys_free(struct Ustr_pool *p, void *old)
     108             116 : {
     109             116 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
     110             116 :   struct Ustr__pool_ll_node **op = &sip->beg;
     111             116 :   unsigned int num = sip->free_num;
     112                 : 
     113              30 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
     114                 :                                             sizeof(struct Ustr__pool_ll_base)));
     115              30 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM(old));
     116                 :   
     117             242 :   while (*op && num--)
     118                 :   {
     119             152 :     if ((*op)->ptr == old)
     120                 :     {
     121             112 :       struct Ustr__pool_ll_node *rm = *op;
     122                 :       
     123             112 :       *op = rm->next;
     124                 :       
     125             112 :       USTR_CONF_FREE(rm->ptr);
     126             112 :       USTR_CONF_FREE(rm);
     127             112 :       return;
     128                 :     }
     129                 :     
     130              40 :     op = &(*op)->next;
     131                 :   }
     132                 : }
     133                 : 
     134                 : USTR_CONF_i_PROTO void ustr__pool_ll__clear(struct Ustr__pool_ll_base *base,
     135                 :                                             int siblings)
     136             384 : {
     137                 :   struct Ustr__pool_ll_node *scan;
     138                 :   
     139             384 :   if (!base)
     140             192 :     return;
     141                 : 
     142             192 :   scan = base->beg;
     143            1040 :   while (scan)
     144                 :   {
     145             656 :     struct Ustr__pool_ll_node *scan_next = scan->next;
     146                 : 
     147             656 :     USTR_CONF_FREE(scan->ptr);
     148             656 :     USTR_CONF_FREE(scan);
     149                 : 
     150             656 :     scan = scan_next;
     151                 :   }
     152             192 :   base->beg = 0;
     153                 : 
     154             192 :   if (siblings)
     155              64 :     ustr__pool_ll__clear(base->next, USTR_TRUE);
     156                 : 
     157             192 :   ustr__pool_ll__clear(base->sbeg, USTR_TRUE);
     158                 : }
     159                 : USTR_CONF_i_PROTO void ustr__pool_ll_clear(struct Ustr_pool *base)
     160              40 : {
     161              10 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(base,
     162                 :                                             sizeof(struct Ustr__pool_ll_base)));
     163              40 :   ustr__pool_ll__clear((struct Ustr__pool_ll_base *)base, USTR_FALSE);
     164              40 : }
     165                 : 
     166                 : USTR_CONF_i_PROTO void ustr__pool_ll__free(struct Ustr__pool_ll_base *base,
     167                 :                                            int siblings)
     168             176 : {
     169             176 :   if (!base)
     170              88 :     return;
     171                 :   
     172              88 :   if (siblings)
     173              32 :     ustr__pool_ll__free(base->next, USTR_TRUE);
     174              88 :   ustr__pool_ll__free(base->sbeg, USTR_TRUE);
     175              88 :   base->sbeg = 0;
     176                 :   
     177              88 :   ustr__pool_ll__clear(base, USTR_FALSE);
     178              88 :   USTR_CONF_FREE(base);
     179                 : }
     180                 : USTR_CONF_i_PROTO void ustr__pool_ll_free(struct Ustr_pool *p)
     181              56 : {
     182              56 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
     183                 :   
     184              14 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
     185                 :                                             sizeof(struct Ustr__pool_ll_base)));
     186                 : 
     187              56 :   if (sip->prev)
     188               4 :     sip->prev->next = sip->next;
     189              52 :   else if (sip->base)
     190               4 :     sip->base->sbeg = sip->next;
     191                 : 
     192              56 :   if (sip->next)
     193               8 :     sip->next->prev = sip->prev;
     194                 :   
     195              56 :   ustr__pool_ll__free(sip, USTR_FALSE);
     196              56 : }
     197                 : 
     198                 : USTR_CONF_i_PROTO
     199                 : struct Ustr_pool *ustr__pool_ll_make_subpool(struct Ustr_pool *p)
     200              96 : {
     201              96 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
     202                 :   struct Ustr__pool_ll_base *tmp;
     203                 : 
     204              96 :   if (!(tmp = USTR_CONF_MALLOC(sizeof(struct Ustr__pool_ll_base))))
     205                 : 
     206               8 :     return (USTR_POOL_NULL);
     207                 : 
     208              88 :   tmp->cbs.pool_sys_malloc   = ustr__pool_ll_sys_malloc;
     209              88 :   tmp->cbs.pool_sys_realloc  = ustr__pool_ll_sys_realloc;
     210              88 :   tmp->cbs.pool_sys_free     = ustr__pool_ll_sys_free;
     211                 : 
     212              88 :   tmp->cbs.pool_make_subpool = ustr__pool_ll_make_subpool;
     213              88 :   tmp->cbs.pool_clear        = ustr__pool_ll_clear;
     214              88 :   tmp->cbs.pool_free         = ustr__pool_ll_free;
     215                 : 
     216              88 :   tmp->beg  = 0;
     217              88 :   tmp->sbeg = USTR__POOL_LL_SIB_NULL;
     218              88 :   tmp->prev = USTR__POOL_LL_SIB_NULL;
     219                 : 
     220              88 :   tmp->next = USTR__POOL_LL_SIB_NULL;
     221              88 :   tmp->base = USTR__POOL_LL_SIB_NULL;
     222                 : 
     223              88 :   tmp->free_num = 2; /* magic number, allows dupx + copy + free */
     224                 : 
     225              88 :   tmp->call_realloc = USTR_TRUE;
     226                 :   
     227              88 :   if (!p)
     228              48 :     return (&tmp->cbs);
     229                 :   
     230              10 :   ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
     231                 :                                             sizeof(struct Ustr__pool_ll_base)));
     232                 : 
     233              40 :   if ((tmp->next = sip->sbeg))
     234              24 :     tmp->next->prev = tmp;
     235              40 :   sip->sbeg = tmp;
     236                 : 
     237              40 :   tmp->base = sip;
     238                 :   
     239              40 :   return (&tmp->cbs);
     240                 : }
     241                 : 
     242                 : /* linked list pool API */
     243                 : USTR_CONF_I_PROTO struct Ustr_pool *ustr_pool_ll_make(void)
     244              48 : { return (ustr__pool_ll_make_subpool(USTR_POOL_NULL)); }
     245                 : 
     246                 : #include <stdarg.h> /* va_list for va_arg() functionality */
     247                 : 
     248                 : USTR_CONF_I_PROTO
     249                 : int ustr_pool_ll_cntl(struct Ustr_pool *p, int option, ...)
     250              24 : {
     251              24 :   struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
     252              24 :   int ret = USTR_FALSE;
     253                 :   va_list ap;
     254                 :   
     255              24 :   va_start(ap, option);
     256                 : 
     257              24 :   switch (option)
     258                 :   {
     259                 :     case USTR_POOL_LL_CNTL_GET_FREE_CMP:
     260                 :     {
     261               8 :       unsigned int *num = va_arg(ap, unsigned int *);
     262                 :    
     263               8 :       *num = sip->free_num;
     264                 : 
     265               8 :       ret = USTR_TRUE;
     266                 :     }
     267               8 :     break;
     268                 :     case USTR_POOL_LL_CNTL_SET_FREE_CMP:
     269                 :     {
     270               4 :       unsigned int num = va_arg(ap, unsigned int);
     271                 :       
     272               4 :       USTR_ASSERT_RET((num <= 65535), USTR_FALSE); /* 2 ** 16 */
     273                 :    
     274               4 :       sip->free_num = num;
     275                 : 
     276               4 :       ret = USTR_TRUE;
     277                 :     }
     278               4 :     break;
     279                 :     
     280                 :     case USTR_POOL_LL_CNTL_GET_REALLOC:
     281                 :     {
     282               8 :       int *toggle = va_arg(ap, int *);
     283                 :       
     284               8 :       *toggle = sip->call_realloc;
     285                 : 
     286               8 :       ret = USTR_TRUE;
     287                 :     }
     288               8 :     break;
     289                 :     case USTR_POOL_LL_CNTL_SET_REALLOC:
     290                 :     {
     291               4 :       int toggle = va_arg(ap, int);
     292                 :       
     293               4 :       USTR_ASSERT_RET((toggle == !!toggle), USTR_FALSE);
     294                 :       
     295               4 :       sip->call_realloc = toggle;
     296                 : 
     297               4 :       ret = USTR_TRUE;
     298                 :     }
     299                 :     break;
     300                 :   }
     301                 :   
     302              12 :   USTR_ASSERT(ret);
     303                 :   
     304              24 :   va_end(ap);
     305                 : 
     306              24 :   return (ret);
     307                 : }
     308                 : 
     309                 : /* "block" pool API */
     310                 : /* USTR_CONF_I_PROTO struct Ustr_pool *ustr_pool_blk_make(void)
     311                 :    { return (ustr__pool_blk_make_subpool(USTR_POOL_NULL)); } */
     312                 : 
     313                 : /* choose one of the above -- linked list */
     314                 : USTR_CONF_I_PROTO struct Ustr_pool *ustr_pool_make_pool(void)
     315               4 : { return (ustr__pool_ll_make_subpool(USTR_POOL_NULL)); }
     316                 : 

Generated by: LTP GCOV extension version 1.4