Ben Laurie wrote:
>Ben Hyde wrote:
>> Ben Laurie wrote:
>> >Ben Hyde wrote:
>> >> Is the critical region in palloc so narrow
>> >> because allocation in a given pool is never
>> >> done by more than a single thread?
>> >I haven't checked the code, but that seems like a rash assumption, if
>> >true.
>>
>> This untested, uncompiled rewrite illustrates my concern.
>
>Perhaps I need new glasses, but I can't actually see the difference
>between the two...
your glasses ok, my fingers not - ben h.
--- Before ---
API_EXPORT(void *) palloc(struct pool *a, int reqsize)
{
#ifdef ALLOC_USE_MALLOC
...
#else
/* Round up requested size to an even number of alignment units (core clicks)
*/
int nclicks = 1 + ((reqsize - 1) / CLICK_SZ);
int size = nclicks * CLICK_SZ;
/* First, see if we have space in the block most recently
* allocated to this pool
*/
union block_hdr *blok = a->last;
char *first_avail = blok->h.first_avail;
char *new_first_avail;
if (reqsize <= 0)
return NULL;
new_first_avail = first_avail + size;
if (new_first_avail <= blok->h.endp) {
debug_verify_filled(first_avail, blok->h.endp,
"Ouch! Someone trounced past the end of their allocation!\n");
blok->h.first_avail = new_first_avail;
return (void *) first_avail;
}
/* Nope --- get a new one that's guaranteed to be big enough */
block_alarms();
(void) acquire_mutex(alloc_mutex);
blok = new_block(size);
a->last->h.next = blok;
a->last = blok;
(void) release_mutex(alloc_mutex);
unblock_alarms();
first_avail = blok->h.first_avail;
blok->h.first_avail += size;
return (void *) first_avail;
#endif
}
--- After ---
API_EXPORT(void *) palloc(struct pool *a, int reqsize)
{
#ifdef ALLOC_USE_MALLOC
...
#else
int nclicks = 1 + ((reqsize - 1) / CLICK_SZ);
int size = nclicks * CLICK_SZ; /* Alignable */
char *result;
if (reqsize <= 0)
return NULL;
block_alarms();
(void)acquire_mutex(alloc_mutex);
{
union block_hdr *blok = a->last;
char *first_avail = blok->h.first_avail;
char *new_first_avail = first_avail + size;
if (new_first_avail <= blok->h.endp) {
debug_verify_filled(first_avail, blok->h.endp,
"Ouch! Someone trounced past the end of their allocation!\n");
blok->h.first_avail = new_first_avail;
result = first_avail;
} else {
blok = new_block(size);
a->last->h.next = blok;
a->last = blok;
result = blok->h.first_avail;
blok->h.first_avail += size;
}
}
(void)release_mutex(alloc_mutex);
unblock_alarms();
return (void *)result;
#endif
}
---
|