|
Lines 1-5
Link Here
|
| 1 |
/* Cache memory handling. |
1 |
/* Cache memory handling. |
| 2 |
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. |
2 |
Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc. |
| 3 |
This file is part of the GNU C Library. |
3 |
This file is part of the GNU C Library. |
| 4 |
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. |
4 |
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. |
| 5 |
|
5 |
|
|
Lines 24-29
Link Here
|
| 24 |
#include <inttypes.h> |
24 |
#include <inttypes.h> |
| 25 |
#include <libintl.h> |
25 |
#include <libintl.h> |
| 26 |
#include <limits.h> |
26 |
#include <limits.h> |
|
|
27 |
#include <obstack.h> |
| 27 |
#include <stdlib.h> |
28 |
#include <stdlib.h> |
| 28 |
#include <string.h> |
29 |
#include <string.h> |
| 29 |
#include <unistd.h> |
30 |
#include <unistd.h> |
|
Lines 79-84
static void
Link Here
|
| 79 |
markrange (BITMAP_T *mark, ref_t start, size_t len) |
80 |
markrange (BITMAP_T *mark, ref_t start, size_t len) |
| 80 |
{ |
81 |
{ |
| 81 |
/* Adjust parameters for block alignment. */ |
82 |
/* Adjust parameters for block alignment. */ |
|
|
83 |
assert ((start & BLOCK_ALIGN_M1) == 0); |
| 82 |
start /= BLOCK_ALIGN; |
84 |
start /= BLOCK_ALIGN; |
| 83 |
len = (len + BLOCK_ALIGN_M1) / BLOCK_ALIGN; |
85 |
len = (len + BLOCK_ALIGN_M1) / BLOCK_ALIGN; |
| 84 |
|
86 |
|
|
Lines 93-99
markrange (BITMAP_T *mark, ref_t start, size_t len)
Link Here
|
| 93 |
return; |
95 |
return; |
| 94 |
} |
96 |
} |
| 95 |
|
97 |
|
| 96 |
mark[elem++] |= 0xff << (start % BITS); |
98 |
mark[elem++] |= ALLBITS << (start % BITS); |
| 97 |
len -= BITS - (start % BITS); |
99 |
len -= BITS - (start % BITS); |
| 98 |
} |
100 |
} |
| 99 |
|
101 |
|
|
Lines 130-143
gc (struct database_dyn *db)
Link Here
|
| 130 |
size_t stack_used = sizeof (bool) * db->head->module; |
132 |
size_t stack_used = sizeof (bool) * db->head->module; |
| 131 |
if (__builtin_expect (stack_used > MAX_STACK_USE, 0)) |
133 |
if (__builtin_expect (stack_used > MAX_STACK_USE, 0)) |
| 132 |
stack_used = 0; |
134 |
stack_used = 0; |
| 133 |
size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1) |
135 |
size_t nmark = (db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS; |
| 134 |
/ BITS) * sizeof (BITMAP_T); |
136 |
size_t memory_needed = nmark * sizeof (BITMAP_T); |
| 135 |
if (memory_needed <= MAX_STACK_USE) |
137 |
if (stack_used + memory_needed <= MAX_STACK_USE) |
| 136 |
{ |
138 |
{ |
| 137 |
mark = (BITMAP_T *) alloca (memory_needed); |
139 |
mark = (BITMAP_T *) alloca (memory_needed); |
| 138 |
mark_use_malloc = false; |
140 |
mark_use_malloc = false; |
| 139 |
memset (mark, '\0', memory_needed); |
141 |
memset (mark, '\0', memory_needed); |
| 140 |
stack_used = memory_needed; |
142 |
stack_used += memory_needed; |
| 141 |
} |
143 |
} |
| 142 |
else |
144 |
else |
| 143 |
{ |
145 |
{ |
|
Lines 156-161
gc (struct database_dyn *db)
Link Here
|
| 156 |
he = alloca (db->head->nentries * sizeof (struct hashentry *)); |
158 |
he = alloca (db->head->nentries * sizeof (struct hashentry *)); |
| 157 |
he_data = alloca (db->head->nentries * sizeof (struct hashentry *)); |
159 |
he_data = alloca (db->head->nentries * sizeof (struct hashentry *)); |
| 158 |
he_use_malloc = false; |
160 |
he_use_malloc = false; |
|
|
161 |
stack_used += memory_needed; |
| 159 |
} |
162 |
} |
| 160 |
else |
163 |
else |
| 161 |
{ |
164 |
{ |
|
Lines 197-202
gc (struct database_dyn *db)
Link Here
|
| 197 |
} |
200 |
} |
| 198 |
assert (cnt == db->head->nentries); |
201 |
assert (cnt == db->head->nentries); |
| 199 |
|
202 |
|
|
|
203 |
/* Go through the list of in-flight memory blocks. */ |
| 204 |
struct mem_in_flight *mrunp = mem_in_flight_list; |
| 205 |
while (mrunp != NULL) |
| 206 |
{ |
| 207 |
/* NB: There can be no race between this test and another thread |
| 208 |
setting the field to the index we are looking for because |
| 209 |
this would require the other thread to also have the memlock |
| 210 |
for the database. |
| 211 |
|
| 212 |
NB2: we do not have to look at latter blocks (higher indices) if |
| 213 |
earlier blocks are not in flight. They are always allocated in |
| 214 |
sequence. */ |
| 215 |
for (enum in_flight idx = IDX_result_data; |
| 216 |
idx < IDX_last && mrunp->block[idx].dbidx == db - dbs; ++idx) |
| 217 |
{ |
| 218 |
assert (mrunp->block[idx].blockoff >= 0); |
| 219 |
assert (mrunp->block[idx].blocklen < db->memsize); |
| 220 |
assert (mrunp->block[idx].blockoff |
| 221 |
+ mrunp->block[0].blocklen <= db->memsize); |
| 222 |
markrange (mark, mrunp->block[idx].blockoff, |
| 223 |
mrunp->block[idx].blocklen); |
| 224 |
} |
| 225 |
|
| 226 |
mrunp = mrunp->next; |
| 227 |
} |
| 228 |
|
| 200 |
/* Sort the entries by the addresses of the referenced data. All |
229 |
/* Sort the entries by the addresses of the referenced data. All |
| 201 |
the entries pointing to the same DATAHEAD object will have the |
230 |
the entries pointing to the same DATAHEAD object will have the |
| 202 |
same key. Stability of the sorting is unimportant. */ |
231 |
same key. Stability of the sorting is unimportant. */ |
|
Lines 206-213
gc (struct database_dyn *db)
Link Here
|
| 206 |
/* Sort the entries by their address. */ |
235 |
/* Sort the entries by their address. */ |
| 207 |
qsort (he, cnt, sizeof (struct hashentry *), sort_he); |
236 |
qsort (he, cnt, sizeof (struct hashentry *), sort_he); |
| 208 |
|
237 |
|
|
|
238 |
#define obstack_chunk_alloc xmalloc |
| 239 |
#define obstack_chunk_free free |
| 240 |
struct obstack ob; |
| 241 |
obstack_init (&ob); |
| 242 |
|
| 209 |
/* Determine the highest used address. */ |
243 |
/* Determine the highest used address. */ |
| 210 |
size_t high = sizeof (mark); |
244 |
size_t high = nmark; |
| 211 |
while (high > 0 && mark[high - 1] == 0) |
245 |
while (high > 0 && mark[high - 1] == 0) |
| 212 |
--high; |
246 |
--high; |
| 213 |
|
247 |
|
|
Lines 338-345
gc (struct database_dyn *db)
Link Here
|
| 338 |
displacement. */ |
372 |
displacement. */ |
| 339 |
ref_t disp = off_alloc - off_free; |
373 |
ref_t disp = off_alloc - off_free; |
| 340 |
|
374 |
|
| 341 |
struct moveinfo *new_move |
375 |
struct moveinfo *new_move; |
| 342 |
= (struct moveinfo *) alloca (sizeof (*new_move)); |
376 |
if (stack_used + sizeof (*new_move) <= MAX_STACK_USE) |
|
|
377 |
{ |
| 378 |
new_move = alloca (sizeof (*new_move)); |
| 379 |
stack_used += sizeof (*new_move); |
| 380 |
} |
| 381 |
else |
| 382 |
new_move = obstack_alloc (&ob, sizeof (*new_move)); |
| 343 |
new_move->from = db->data + off_alloc; |
383 |
new_move->from = db->data + off_alloc; |
| 344 |
new_move->to = db->data + off_free; |
384 |
new_move->to = db->data + off_free; |
| 345 |
new_move->size = off_allocend - off_alloc; |
385 |
new_move->size = off_allocend - off_alloc; |
|
Lines 499-509
gc (struct database_dyn *db)
Link Here
|
| 499 |
free (he); |
539 |
free (he); |
| 500 |
if (mark_use_malloc) |
540 |
if (mark_use_malloc) |
| 501 |
free (mark); |
541 |
free (mark); |
|
|
542 |
|
| 543 |
obstack_free (&ob, NULL); |
| 502 |
} |
544 |
} |
| 503 |
|
545 |
|
| 504 |
|
546 |
|
| 505 |
void * |
547 |
void * |
| 506 |
mempool_alloc (struct database_dyn *db, size_t len) |
548 |
mempool_alloc (struct database_dyn *db, size_t len, enum in_flight idx) |
| 507 |
{ |
549 |
{ |
| 508 |
/* Make sure LEN is a multiple of our maximum alignment so we can |
550 |
/* Make sure LEN is a multiple of our maximum alignment so we can |
| 509 |
keep track of used memory is multiples of this alignment value. */ |
551 |
keep track of used memory is multiples of this alignment value. */ |
|
Lines 564-572
mempool_alloc (struct database_dyn *db, size_t len)
Link Here
|
| 564 |
} |
606 |
} |
| 565 |
else |
607 |
else |
| 566 |
{ |
608 |
{ |
|
|
609 |
/* Remember that we have allocated this memory. */ |
| 610 |
assert (idx >= 0 && idx < IDX_last); |
| 611 |
mem_in_flight.block[idx].dbidx = db - dbs; |
| 612 |
mem_in_flight.block[idx].blocklen = len; |
| 613 |
mem_in_flight.block[idx].blockoff = db->head->first_free; |
| 614 |
|
| 567 |
db->head->first_free += len; |
615 |
db->head->first_free += len; |
| 568 |
|
616 |
|
| 569 |
db->last_alloc_failed = false; |
617 |
db->last_alloc_failed = false; |
|
|
618 |
|
| 570 |
} |
619 |
} |
| 571 |
|
620 |
|
| 572 |
pthread_mutex_unlock (&db->memlock); |
621 |
pthread_mutex_unlock (&db->memlock); |