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