xref: /dflybsd-src/contrib/gdb-7/gdb/common/vec.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1*ef5ccd6cSJohn Marino /* Vector API for GDB.
2*ef5ccd6cSJohn Marino    Copyright (C) 2004-2013 Free Software Foundation, Inc.
3*ef5ccd6cSJohn Marino    Contributed by Nathan Sidwell <nathan@codesourcery.com>
4*ef5ccd6cSJohn Marino 
5*ef5ccd6cSJohn Marino    This file is part of GDB.
6*ef5ccd6cSJohn Marino 
7*ef5ccd6cSJohn Marino    This program is free software; you can redistribute it and/or modify
8*ef5ccd6cSJohn Marino    it under the terms of the GNU General Public License as published by
9*ef5ccd6cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
10*ef5ccd6cSJohn Marino    (at your option) any later version.
11*ef5ccd6cSJohn Marino 
12*ef5ccd6cSJohn Marino    This program is distributed in the hope that it will be useful,
13*ef5ccd6cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ef5ccd6cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*ef5ccd6cSJohn Marino    GNU General Public License for more details.
16*ef5ccd6cSJohn Marino 
17*ef5ccd6cSJohn Marino    You should have received a copy of the GNU General Public License
18*ef5ccd6cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*ef5ccd6cSJohn Marino 
20*ef5ccd6cSJohn Marino #ifdef GDBSERVER
21*ef5ccd6cSJohn Marino #include "server.h"
22*ef5ccd6cSJohn Marino #else
23*ef5ccd6cSJohn Marino #include "defs.h"
24*ef5ccd6cSJohn Marino #endif
25*ef5ccd6cSJohn Marino 
26*ef5ccd6cSJohn Marino #include "vec.h"
27*ef5ccd6cSJohn Marino 
28*ef5ccd6cSJohn Marino struct vec_prefix
29*ef5ccd6cSJohn Marino {
30*ef5ccd6cSJohn Marino   unsigned num;
31*ef5ccd6cSJohn Marino   unsigned alloc;
32*ef5ccd6cSJohn Marino   void *vec[1];
33*ef5ccd6cSJohn Marino };
34*ef5ccd6cSJohn Marino 
35*ef5ccd6cSJohn Marino /* Calculate the new ALLOC value, making sure that abs(RESERVE) slots
36*ef5ccd6cSJohn Marino    are free.  If RESERVE < 0 grow exactly, otherwise grow
37*ef5ccd6cSJohn Marino    exponentially.  */
38*ef5ccd6cSJohn Marino 
39*ef5ccd6cSJohn Marino static inline unsigned
calculate_allocation(const struct vec_prefix * pfx,int reserve)40*ef5ccd6cSJohn Marino calculate_allocation (const struct vec_prefix *pfx, int reserve)
41*ef5ccd6cSJohn Marino {
42*ef5ccd6cSJohn Marino   unsigned alloc = 0;
43*ef5ccd6cSJohn Marino   unsigned num = 0;
44*ef5ccd6cSJohn Marino 
45*ef5ccd6cSJohn Marino   if (pfx)
46*ef5ccd6cSJohn Marino     {
47*ef5ccd6cSJohn Marino       alloc = pfx->alloc;
48*ef5ccd6cSJohn Marino       num = pfx->num;
49*ef5ccd6cSJohn Marino     }
50*ef5ccd6cSJohn Marino   else if (!reserve)
51*ef5ccd6cSJohn Marino     /* If there's no prefix, and we've not requested anything, then we
52*ef5ccd6cSJohn Marino        will create a NULL vector.  */
53*ef5ccd6cSJohn Marino     return 0;
54*ef5ccd6cSJohn Marino 
55*ef5ccd6cSJohn Marino   /* We must have run out of room.  */
56*ef5ccd6cSJohn Marino   gdb_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve));
57*ef5ccd6cSJohn Marino 
58*ef5ccd6cSJohn Marino   if (reserve < 0)
59*ef5ccd6cSJohn Marino     /* Exact size.  */
60*ef5ccd6cSJohn Marino     alloc = num + -reserve;
61*ef5ccd6cSJohn Marino   else
62*ef5ccd6cSJohn Marino     {
63*ef5ccd6cSJohn Marino       /* Exponential growth.  */
64*ef5ccd6cSJohn Marino       if (!alloc)
65*ef5ccd6cSJohn Marino 	alloc = 4;
66*ef5ccd6cSJohn Marino       else if (alloc < 16)
67*ef5ccd6cSJohn Marino 	/* Double when small.  */
68*ef5ccd6cSJohn Marino 	alloc = alloc * 2;
69*ef5ccd6cSJohn Marino       else
70*ef5ccd6cSJohn Marino 	/* Grow slower when large.  */
71*ef5ccd6cSJohn Marino 	alloc = (alloc * 3 / 2);
72*ef5ccd6cSJohn Marino 
73*ef5ccd6cSJohn Marino       /* If this is still too small, set it to the right size.  */
74*ef5ccd6cSJohn Marino       if (alloc < num + reserve)
75*ef5ccd6cSJohn Marino 	alloc = num + reserve;
76*ef5ccd6cSJohn Marino     }
77*ef5ccd6cSJohn Marino   return alloc;
78*ef5ccd6cSJohn Marino }
79*ef5ccd6cSJohn Marino 
80*ef5ccd6cSJohn Marino /* Ensure there are at least abs(RESERVE) free slots in VEC.  If
81*ef5ccd6cSJohn Marino    RESERVE < 0 grow exactly, else grow exponentially.  As a special
82*ef5ccd6cSJohn Marino    case, if VEC is NULL, and RESERVE is 0, no vector will be created.  */
83*ef5ccd6cSJohn Marino 
84*ef5ccd6cSJohn Marino void *
vec_p_reserve(void * vec,int reserve)85*ef5ccd6cSJohn Marino vec_p_reserve (void *vec, int reserve)
86*ef5ccd6cSJohn Marino {
87*ef5ccd6cSJohn Marino   return vec_o_reserve (vec, reserve,
88*ef5ccd6cSJohn Marino 			offsetof (struct vec_prefix, vec), sizeof (void *));
89*ef5ccd6cSJohn Marino }
90*ef5ccd6cSJohn Marino 
91*ef5ccd6cSJohn Marino /* As vec_p_reserve, but for object vectors.  The vector's trailing
92*ef5ccd6cSJohn Marino    array is at VEC_OFFSET offset and consists of ELT_SIZE sized
93*ef5ccd6cSJohn Marino    elements.  */
94*ef5ccd6cSJohn Marino 
95*ef5ccd6cSJohn Marino void *
vec_o_reserve(void * vec,int reserve,size_t vec_offset,size_t elt_size)96*ef5ccd6cSJohn Marino vec_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size)
97*ef5ccd6cSJohn Marino {
98*ef5ccd6cSJohn Marino   struct vec_prefix *pfx = vec;
99*ef5ccd6cSJohn Marino   unsigned alloc = calculate_allocation (pfx, reserve);
100*ef5ccd6cSJohn Marino 
101*ef5ccd6cSJohn Marino   if (!alloc)
102*ef5ccd6cSJohn Marino     return NULL;
103*ef5ccd6cSJohn Marino 
104*ef5ccd6cSJohn Marino   vec = xrealloc (vec, vec_offset + alloc * elt_size);
105*ef5ccd6cSJohn Marino   ((struct vec_prefix *)vec)->alloc = alloc;
106*ef5ccd6cSJohn Marino   if (!pfx)
107*ef5ccd6cSJohn Marino     ((struct vec_prefix *)vec)->num = 0;
108*ef5ccd6cSJohn Marino 
109*ef5ccd6cSJohn Marino   return vec;
110*ef5ccd6cSJohn Marino }
111*ef5ccd6cSJohn Marino 
112*ef5ccd6cSJohn Marino #if 0
113*ef5ccd6cSJohn Marino /* Example uses.  */
114*ef5ccd6cSJohn Marino DEF_VEC_I (int);
115*ef5ccd6cSJohn Marino typedef struct X
116*ef5ccd6cSJohn Marino {
117*ef5ccd6cSJohn Marino   int i;
118*ef5ccd6cSJohn Marino } obj_t;
119*ef5ccd6cSJohn Marino typedef obj_t *ptr_t;
120*ef5ccd6cSJohn Marino 
121*ef5ccd6cSJohn Marino DEF_VEC_P (ptr_t);
122*ef5ccd6cSJohn Marino DEF_VEC_O (obj_t);
123*ef5ccd6cSJohn Marino #endif
124