Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 6809 invoked by uid 6000); 10 Dec 1997 07:42:44 -0000 Received: (qmail 6803 invoked by uid 24); 10 Dec 1997 07:42:43 -0000 Received: (qmail 25304 invoked from network); 9 Dec 1997 16:45:54 -0000 Received: from gensym.com (192.156.185.2) by taz.hyperreal.org with SMTP; 9 Dec 1997 16:45:54 -0000 Received: by gensym.com (4.1/SMI-4.1) id AA18183; Tue, 9 Dec 97 11:45:08 EST Received: from unknown(1.0.2.6) by ftp.gensym.com via smap (V1.3) id sma018181; Tue Dec 9 11:44:52 1997 Received: from thailand.gensym by gensym1.gensym.com (4.1/SMI-4.1) id AA10929; Tue, 9 Dec 97 10:29:25 EST Date: Tue, 9 Dec 97 10:29:25 EST From: bhyde@gensym.com (Ben Hyde) Message-Id: <9712091529.AA10929@gensym1.gensym.com> Received: by thailand.gensym (4.1/SMI-4.1) id AA27984; Tue, 9 Dec 97 11:44:51 EST To: new-httpd@apache.org Subject: Re: mutex in palloc References: <348C5A0A.E75B3C8@algroup.co.uk> <199712041647.LAA19381@siam.gensym> Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org 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. --- 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; char *result; if (reqsize <= 0) return NULL; block_alarms(); (void)acquire_mutex(alloc_mutex); { /* 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 = 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 { /* Nope --- get a new one that's guaranteed to be big enough */ 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 } --- 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; /* Align size */ 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 }