2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * Implementation of dynamic arrays.
36 #include "native_client/include/portability.h"
38 #define DYN_ARRAY_DEBUG 1
43 #include "native_client/service_runtime/dyn_array.h"
46 # include "native_client/service_runtime/nacl_log.h"
49 static INLINE
int BitsToAllocWords(int nbits
)
51 return (nbits
+ kBitsPerWord
- 1) >> kWordIndexShift
;
54 static INLINE
int BitsToIndex(int nbits
)
56 return nbits
>> kWordIndexShift
;
59 static INLINE
int BitsToOffset(int nbits
)
61 return nbits
& (kBitsPerWord
- 1);
64 int DynArrayCtor(struct DynArray
*dap
,
67 if (initial_size
<= 0) {
70 dap
->num_entries
= 0u;
71 dap
->ptr_array
= calloc(initial_size
, sizeof *dap
->ptr_array
);
72 if (NULL
== dap
->ptr_array
) {
75 dap
->available
= calloc(BitsToAllocWords(initial_size
),
76 sizeof *dap
->available
);
77 if (NULL
== dap
->available
) {
79 dap
->ptr_array
= NULL
;
82 dap
->avail_ix
= 0; /* hint */
84 dap
->ptr_array_space
= initial_size
;
88 void DynArrayDtor(struct DynArray
*dap
)
90 dap
->num_entries
= 0; /* assume user has freed entries */
92 dap
->ptr_array
= NULL
;
93 dap
->ptr_array_space
= 0;
95 dap
->available
= NULL
;
98 void *DynArrayGet(struct DynArray
*dap
,
101 if ((unsigned) idx
< (unsigned) dap
->num_entries
) {
102 return dap
->ptr_array
[idx
];
107 int DynArraySet(struct DynArray
*dap
,
115 for (desired_space
= dap
->ptr_array_space
;
116 idx
>= desired_space
;
117 desired_space
= tmp
) {
118 tmp
= 2 * desired_space
;
119 if (tmp
< desired_space
) {
123 if (desired_space
!= dap
->ptr_array_space
) {
128 size_t new_avail_nwords
;
129 size_t old_avail_nwords
;
131 new_space
= realloc(dap
->ptr_array
, desired_space
* sizeof *new_space
);
132 if (NULL
== new_space
) {
135 memset((void *) (new_space
+ dap
->ptr_array_space
),
137 (desired_space
- dap
->ptr_array_space
) * sizeof *new_space
);
138 dap
->ptr_array
= new_space
;
140 old_avail_nwords
= BitsToAllocWords(dap
->ptr_array_space
);
141 new_avail_nwords
= BitsToAllocWords(desired_space
);
143 new_avail
= realloc(dap
->available
,
144 new_avail_nwords
* sizeof *new_avail
);
145 if (NULL
== new_avail
) {
148 memset((void *) &new_avail
[old_avail_nwords
],
150 (new_avail_nwords
- old_avail_nwords
) * sizeof *new_avail
);
151 dap
->available
= new_avail
;
153 dap
->ptr_array_space
= desired_space
;
155 dap
->ptr_array
[idx
] = ptr
;
156 ix
= BitsToIndex(idx
);
158 NaClLog(4, "Set(%d,%p) @ix %d: 0x%08x\n", idx
, ptr
, ix
, dap
->available
[ix
]);
161 dap
->available
[ix
] |= (1 << BitsToOffset(idx
));
163 dap
->available
[ix
] &= ~(1 << BitsToOffset(idx
));
164 if (ix
< dap
->avail_ix
) {
169 NaClLog(4, "After @ix %d: 0x%08x, avail_ix %d\n",
170 ix
, dap
->available
[ix
], dap
->avail_ix
);
172 if (dap
->num_entries
<= idx
) {
173 dap
->num_entries
= idx
+ 1;
178 int DynArrayFirstAvail(struct DynArray
*dap
)
184 last_ix
= BitsToAllocWords(dap
->ptr_array_space
);
187 for (ix
= 0; ix
< last_ix
; ++ix
) {
188 NaClLog(4, "ix %d: 0x%08x\n", ix
, dap
->available
[ix
]);
191 for (ix
= dap
->avail_ix
; ix
< last_ix
; ++ix
) {
192 if (0U != ~dap
->available
[ix
]) {
194 NaClLog(4, "found first not-all-ones ix %d\n", ix
);
201 avail_pos
= ffs(~dap
->available
[ix
]) - 1;
202 avail_pos
+= ix
<< kWordIndexShift
;
204 avail_pos
= dap
->ptr_array_space
;