diff options
Diffstat (limited to 'contrib/bind9/lib/bind/isc')
| -rw-r--r-- | contrib/bind9/lib/bind/isc/ev_connects.c | 8 | ||||
| -rw-r--r-- | contrib/bind9/lib/bind/isc/ev_files.c | 25 | ||||
| -rw-r--r-- | contrib/bind9/lib/bind/isc/eventlib.c | 235 | ||||
| -rw-r--r-- | contrib/bind9/lib/bind/isc/eventlib_p.h | 63 | ||||
| -rw-r--r-- | contrib/bind9/lib/bind/isc/memcluster.c | 50 |
5 files changed, 339 insertions, 42 deletions
diff --git a/contrib/bind9/lib/bind/isc/ev_connects.c b/contrib/bind9/lib/bind/isc/ev_connects.c index 043e5f497ca6..4b0dd2222a0f 100644 --- a/contrib/bind9/lib/bind/isc/ev_connects.c +++ b/contrib/bind9/lib/bind/isc/ev_connects.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_connects.c,v 1.4.206.1 2004/03/09 08:33:40 marka Exp $"; +static const char rcsid[] = "$Id: ev_connects.c,v 1.4.206.2 2005/07/08 04:52:54 marka Exp $"; #endif /* Import. */ @@ -168,10 +168,10 @@ evCancelConn(evContext opaqueCtx, evConnID id) { return (-1); } else { #ifdef USE_FIONBIO_IOCTL - int on = 1; - OK(ioctl(this->fd, FIONBIO, (char *)&on)); + int off = 0; + OK(ioctl(this->fd, FIONBIO, (char *)&off)); #else - OK(fcntl(this->fd, F_SETFL, mode | PORT_NONBLOCK)); + OK(fcntl(this->fd, F_SETFL, mode & ~PORT_NONBLOCK)); #endif } } diff --git a/contrib/bind9/lib/bind/isc/ev_files.c b/contrib/bind9/lib/bind/isc/ev_files.c index 4d5eb55ad8d5..1f95ed04c999 100644 --- a/contrib/bind9/lib/bind/isc/ev_files.c +++ b/contrib/bind9/lib/bind/isc/ev_files.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_files.c,v 1.3.2.1.4.1 2004/03/09 08:33:42 marka Exp $"; +static const char rcsid[] = "$Id: ev_files.c,v 1.3.2.1.4.3 2005/07/28 07:43:19 marka Exp $"; #endif #include "port_before.h" @@ -58,8 +58,10 @@ evSelectFD(evContext opaqueCtx, ctx, fd, eventmask, func, uap); if (eventmask == 0 || (eventmask & ~EV_MASK_ALL) != 0) EV_ERR(EINVAL); +#ifndef USE_POLL if (fd > ctx->highestFD) EV_ERR(EINVAL); +#endif OK(mode = fcntl(fd, F_GETFL, NULL)); /* side effect: validate fd. */ /* @@ -68,6 +70,11 @@ evSelectFD(evContext opaqueCtx, * of our deselect()'s have to leave it in O_NONBLOCK. If not, then * all but our last deselect() has to leave it in O_NONBLOCK. */ +#ifdef USE_POLL + /* Make sure both ctx->pollfds[] and ctx->fdTable[] are large enough */ + if (fd >= ctx->maxnfds && evPollfdRealloc(ctx, 1, fd) != 0) + EV_ERR(ENOMEM); +#endif /* USE_POLL */ id = FindFD(ctx, fd, EV_MASK_ALL); if (id == NULL) { if (mode & PORT_NONBLOCK) @@ -143,13 +150,6 @@ evSelectFD(evContext opaqueCtx, if (opaqueID) opaqueID->opaque = id; - evPrintf(ctx, 5, - "evSelectFD(fd %d, mask 0x%x): new masks: 0x%lx 0x%lx 0x%lx\n", - fd, eventmask, - (u_long)ctx->rdNext.fds_bits[0], - (u_long)ctx->wrNext.fds_bits[0], - (u_long)ctx->exNext.fds_bits[0]); - return (0); } @@ -204,7 +204,7 @@ evDeselectFD(evContext opaqueCtx, evFileID opaqueID) { * and (b) the caller didn't ask us anything about O_NONBLOCK. */ #ifdef USE_FIONBIO_IOCTL - int off = 1; + int off = 0; (void) ioctl(del->fd, FIONBIO, (char *)&off); #else (void) fcntl(del->fd, F_SETFL, mode & ~PORT_NONBLOCK); @@ -259,13 +259,6 @@ evDeselectFD(evContext opaqueCtx, evFileID opaqueID) { if (del == ctx->fdNext) ctx->fdNext = del->next; - evPrintf(ctx, 5, - "evDeselectFD(fd %d, mask 0x%x): new masks: 0x%lx 0x%lx 0x%lx\n", - del->fd, eventmask, - (u_long)ctx->rdNext.fds_bits[0], - (u_long)ctx->wrNext.fds_bits[0], - (u_long)ctx->exNext.fds_bits[0]); - /* Couldn't free it before now since we were using fields out of it. */ FREE(del); diff --git a/contrib/bind9/lib/bind/isc/eventlib.c b/contrib/bind9/lib/bind/isc/eventlib.c index 06d791e0c112..77b14144b97b 100644 --- a/contrib/bind9/lib/bind/isc/eventlib.c +++ b/contrib/bind9/lib/bind/isc/eventlib.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: eventlib.c,v 1.2.2.1.4.4 2004/12/09 04:07:15 marka Exp $"; +static const char rcsid[] = "$Id: eventlib.c,v 1.2.2.1.4.5 2005/07/28 07:43:20 marka Exp $"; #endif #include "port_before.h" @@ -29,6 +29,9 @@ static const char rcsid[] = "$Id: eventlib.c,v 1.2.2.1.4.4 2004/12/09 04:07:15 m #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> +#ifdef SOLARIS2 +#include <limits.h> +#endif /* SOLARIS2 */ #include <errno.h> #include <signal.h> @@ -44,9 +47,13 @@ static const char rcsid[] = "$Id: eventlib.c,v 1.2.2.1.4.4 2004/12/09 04:07:15 m int __evOptMonoTime; +#ifdef USE_POLL +#define pselect Pselect +#endif /* USE_POLL */ + /* Forward. */ -#ifdef NEED_PSELECT +#if defined(NEED_PSELECT) || defined(USE_POLL) static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *); @@ -78,6 +85,18 @@ evCreate(evContext *opaqueCtx) { INIT_LIST(ctx->accepts); /* Files. */ +#ifdef USE_POLL + ctx->pollfds = NULL; + ctx->maxnfds = 0; + ctx->firstfd = 0; + emulMaskInit(ctx, rdLast, EV_READ, 1); + emulMaskInit(ctx, rdNext, EV_READ, 0); + emulMaskInit(ctx, wrLast, EV_WRITE, 1); + emulMaskInit(ctx, wrNext, EV_WRITE, 0); + emulMaskInit(ctx, exLast, EV_EXCEPT, 1); + emulMaskInit(ctx, exNext, EV_EXCEPT, 0); + emulMaskInit(ctx, nonblockBefore, EV_WASNONBLOCKING, 0); +#endif /* USE_POLL */ ctx->files = NULL; FD_ZERO(&ctx->rdNext); FD_ZERO(&ctx->wrNext); @@ -86,11 +105,16 @@ evCreate(evContext *opaqueCtx) { ctx->fdMax = -1; ctx->fdNext = NULL; ctx->fdCount = 0; /* Invalidate {rd,wr,ex}Last. */ +#ifndef USE_POLL ctx->highestFD = FD_SETSIZE - 1; + memset(ctx->fdTable, 0, sizeof ctx->fdTable); +#else + ctx->highestFD = INT_MAX / sizeof(struct pollfd); + ctx->fdTable = NULL; +#endif #ifdef EVENTLIB_TIME_CHECKS ctx->lastFdCount = 0; #endif - memset(ctx->fdTable, 0, sizeof ctx->fdTable); /* Streams. */ ctx->streams = NULL; @@ -284,34 +308,37 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) { } #endif do { +#ifndef USE_POLL /* XXX need to copy only the bits we are using. */ ctx->rdLast = ctx->rdNext; ctx->wrLast = ctx->wrNext; ctx->exLast = ctx->exNext; - +#else + /* + * The pollfd structure uses separate fields for + * the input and output events (corresponding to + * the ??Next and ??Last fd sets), so there's no + * need to copy one to the other. + */ +#endif /* USE_POLL */ if (m == Timer) { INSIST(tp == &t); t = evSubTime(nextTime, ctx->lastEventTime); } - evPrintf(ctx, 4, - "pselect(%d, 0x%lx, 0x%lx, 0x%lx, %ld.%09ld)\n", - ctx->fdMax+1, - (u_long)ctx->rdLast.fds_bits[0], - (u_long)ctx->wrLast.fds_bits[0], - (u_long)ctx->exLast.fds_bits[0], - tp ? (long)tp->tv_sec : -1L, - tp ? tp->tv_nsec : -1); - /* XXX should predict system's earliness and adjust. */ x = pselect(ctx->fdMax+1, &ctx->rdLast, &ctx->wrLast, &ctx->exLast, tp, NULL); pselect_errno = errno; +#ifndef USE_POLL evPrintf(ctx, 4, "select() returns %d (err: %s)\n", x, (x == -1) ? strerror(errno) : "none"); - +#else + evPrintf(ctx, 4, "poll() returns %d (err: %s)\n", + x, (x == -1) ? strerror(errno) : "none"); +#endif /* USE_POLL */ /* Anything but a poll can change the time. */ if (m != JustPoll) ctx->lastEventTime = evNowTime(); @@ -704,7 +731,7 @@ evGetOption(evContext *opaqueCtx, const char *option, int *value) { return (-1); } -#ifdef NEED_PSELECT +#if defined(NEED_PSELECT) || defined(USE_POLL) /* XXX needs to move to the porting library. */ static int pselect(int nfds, void *rfds, void *wfds, void *efds, @@ -714,15 +741,69 @@ pselect(int nfds, void *rfds, void *wfds, void *efds, struct timeval tv, *tvp; sigset_t sigs; int n; +#ifdef USE_POLL + int polltimeout = INFTIM; + evContext_p *ctx; + struct pollfd *fds; + nfds_t pnfds; + + UNUSED(nfds); +#endif /* USE_POLL */ if (tsp) { tvp = &tv; tv = evTimeVal(*tsp); +#ifdef USE_POLL + polltimeout = 1000 * tv.tv_sec + tv.tv_usec / 1000; +#endif /* USE_POLL */ } else tvp = NULL; if (sigmask) sigprocmask(SIG_SETMASK, sigmask, &sigs); +#ifndef USE_POLL n = select(nfds, rfds, wfds, efds, tvp); +#else + /* + * rfds, wfds, and efds should all be from the same evContext_p, + * so any of them will do. If they're all NULL, the caller is + * presumably calling us to block. + */ + if (rfds != NULL) + ctx = ((__evEmulMask *)rfds)->ctx; + else if (wfds != NULL) + ctx = ((__evEmulMask *)wfds)->ctx; + else if (efds != NULL) + ctx = ((__evEmulMask *)efds)->ctx; + else + ctx = NULL; + if (ctx != NULL && ctx->fdMax != -1) { + fds = &(ctx->pollfds[ctx->firstfd]); + pnfds = ctx->fdMax - ctx->firstfd + 1; + } else { + fds = NULL; + pnfds = 0; + } + n = poll(fds, pnfds, polltimeout); + /* + * pselect() should return the total number of events on the file + * desriptors, not just the count of fd:s with activity. Hence, + * traverse the pollfds array and count the events. + */ + if (n > 0) { + int i, e; + for (e = 0, i = ctx->firstfd; i <= ctx->fdMax; i++) { + if (ctx->pollfds[i].fd < 0) + continue; + if (FD_ISSET(i, &ctx->rdLast)) + e++; + if (FD_ISSET(i, &ctx->wrLast)) + e++; + if (FD_ISSET(i, &ctx->exLast)) + e++; + } + n = e; + } +#endif /* USE_POLL */ if (sigmask) sigprocmask(SIG_SETMASK, &sigs, NULL); if (tsp) @@ -730,3 +811,127 @@ pselect(int nfds, void *rfds, void *wfds, void *efds, return (n); } #endif + +#ifdef USE_POLL +int +evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd) { + + int i, maxnfds; + void *pollfds, *fdTable; + + if (fd < ctx->maxnfds) + return (0); + + /* Don't allow ridiculously small values for pollfd_chunk_size */ + if (pollfd_chunk_size < 20) + pollfd_chunk_size = 20; + + maxnfds = (1 + (fd/pollfd_chunk_size)) * pollfd_chunk_size; + + pollfds = realloc(ctx->pollfds, maxnfds * sizeof(*ctx->pollfds)); + if (pollfds != NULL) + ctx->pollfds = pollfds; + fdTable = realloc(ctx->fdTable, maxnfds * sizeof(*ctx->fdTable)); + if (fdTable != NULL) + ctx->fdTable = fdTable; + + if (pollfds == NULL || fdTable == NULL) { + evPrintf(ctx, 2, "pollfd() realloc (%ld) failed\n", + (long)maxnfds*sizeof(struct pollfd)); + return (-1); + } + + for (i = ctx->maxnfds; i < maxnfds; i++) { + ctx->pollfds[i].fd = -1; + ctx->pollfds[i].events = 0; + ctx->fdTable[i] = 0; + } + + ctx->maxnfds = maxnfds; + + return (0); +} + +/* Find the appropriate 'events' or 'revents' field in the pollfds array */ +short * +__fd_eventfield(int fd, __evEmulMask *maskp) { + + evContext_p *ctx = (evContext_p *)maskp->ctx; + + if (!maskp->result || maskp->type == EV_WASNONBLOCKING) + return (&(ctx->pollfds[fd].events)); + else + return (&(ctx->pollfds[fd].revents)); +} + +/* Translate to poll(2) event */ +short +__poll_event(__evEmulMask *maskp) { + + switch ((maskp)->type) { + case EV_READ: + return (POLLRDNORM); + case EV_WRITE: + return (POLLWRNORM); + case EV_EXCEPT: + return (POLLRDBAND | POLLPRI | POLLWRBAND); + case EV_WASNONBLOCKING: + return (POLLHUP); + default: + return (0); + } +} + +/* + * Clear the events corresponding to the specified mask. If this leaves + * the events mask empty (apart from the POLLHUP bit), set the fd field + * to -1 so that poll(2) will ignore this fd. + */ +void +__fd_clr(int fd, __evEmulMask *maskp) { + + evContext_p *ctx = maskp->ctx; + + *__fd_eventfield(fd, maskp) &= ~__poll_event(maskp); + if ((ctx->pollfds[fd].events & ~POLLHUP) == 0) { + ctx->pollfds[fd].fd = -1; + if (fd == ctx->fdMax) + while (ctx->fdMax > ctx->firstfd && + ctx->pollfds[ctx->fdMax].fd < 0) + ctx->fdMax--; + if (fd == ctx->firstfd) + while (ctx->firstfd <= ctx->fdMax && + ctx->pollfds[ctx->firstfd].fd < 0) + ctx->firstfd++; + /* + * Do we have a empty set of descriptors? + */ + if (ctx->firstfd > ctx->fdMax) { + ctx->fdMax = -1; + ctx->firstfd = 0; + } + } +} + +/* + * Set the events bit(s) corresponding to the specified mask. If the events + * field has any other bits than POLLHUP set, also set the fd field so that + * poll(2) will watch this fd. + */ +void +__fd_set(int fd, __evEmulMask *maskp) { + + evContext_p *ctx = maskp->ctx; + + *__fd_eventfield(fd, maskp) |= __poll_event(maskp); + if ((ctx->pollfds[fd].events & ~POLLHUP) != 0) { + ctx->pollfds[fd].fd = fd; + if (fd < ctx->firstfd || ctx->fdMax == -1) + ctx->firstfd = fd; + if (fd > ctx->fdMax) + ctx->fdMax = fd; + } +} +#endif /* USE_POLL */ + +/*! \file */ diff --git a/contrib/bind9/lib/bind/isc/eventlib_p.h b/contrib/bind9/lib/bind/isc/eventlib_p.h index 8c58c7fd6ef4..b95741d7aff3 100644 --- a/contrib/bind9/lib/bind/isc/eventlib_p.h +++ b/contrib/bind9/lib/bind/isc/eventlib_p.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -18,7 +18,7 @@ /* eventlib_p.h - private interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib_p.h,v 1.3.2.1.4.2 2004/12/05 22:38:43 marka Exp $ + * $Id: eventlib_p.h,v 1.3.2.1.4.3 2005/07/28 07:43:20 marka Exp $ */ #ifndef _EVENTLIB_P_H @@ -63,6 +63,13 @@ #define FILL(p) #endif +#ifdef USE_POLL +#ifdef HAVE_STROPTS_H +#include <stropts.h> +#endif +#include <poll.h> +#endif /* USE_POLL */ + typedef struct evConn { evConnFunc func; void * uap; @@ -166,6 +173,40 @@ typedef struct evEvent_p { } u; } evEvent_p; +#ifdef USE_POLL +typedef struct { + void *ctx; /* pointer to the evContext_p */ + uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ + uint32_t result; /* 1 => revents, 0 => events */ +} __evEmulMask; + +#define emulMaskInit(ctx, field, ev, lastnext) \ + ctx->field.ctx = ctx; \ + ctx->field.type = ev; \ + ctx->field.result = lastnext; + +extern short *__fd_eventfield(int fd, __evEmulMask *maskp); +extern short __poll_event(__evEmulMask *maskp); +extern void __fd_clr(int fd, __evEmulMask *maskp); +extern void __fd_set(int fd, __evEmulMask *maskp); + +#undef FD_ZERO +#define FD_ZERO(maskp) + +#undef FD_SET +#define FD_SET(fd, maskp) \ + __fd_set(fd, maskp) + +#undef FD_CLR +#define FD_CLR(fd, maskp) \ + __fd_clr(fd, maskp) + +#undef FD_ISSET +#define FD_ISSET(fd, maskp) \ + ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) + +#endif /* USE_POLL */ + typedef struct { /* Global. */ const evEvent_p *cur; @@ -177,12 +218,26 @@ typedef struct { LIST(evAccept) accepts; /* Files. */ evFile *files, *fdNext; +#ifndef USE_POLL fd_set rdLast, rdNext; fd_set wrLast, wrNext; fd_set exLast, exNext; fd_set nonblockBefore; int fdMax, fdCount, highestFD; evFile *fdTable[FD_SETSIZE]; +#else + struct pollfd *pollfds; /* Allocated as needed */ + evFile **fdTable; /* Ditto */ + int maxnfds; /* # elements in above */ + int firstfd; /* First active fd */ + int fdMax; /* Last active fd */ + int fdCount; /* # fd:s with I/O */ + int highestFD; /* max fd allowed by OS */ + __evEmulMask rdLast, rdNext; + __evEmulMask wrLast, wrNext; + __evEmulMask exLast, exNext; + __evEmulMask nonblockBefore; +#endif /* USE_POLL */ #ifdef EVENTLIB_TIME_CHECKS struct timespec lastSelectTime; int lastFdCount; @@ -203,6 +258,10 @@ typedef struct { void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); +#ifdef USE_POLL +extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); +#endif /* USE_POLL */ + /* ev_timers.c */ #define evCreateTimers __evCreateTimers heap_context evCreateTimers(const evContext_p *); diff --git a/contrib/bind9/lib/bind/isc/memcluster.c b/contrib/bind9/lib/bind/isc/memcluster.c index 0632ec7d7016..c5b7202817c5 100644 --- a/contrib/bind9/lib/bind/isc/memcluster.c +++ b/contrib/bind9/lib/bind/isc/memcluster.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1997,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -24,7 +24,7 @@ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: memcluster.c,v 1.3.206.4 2004/09/16 00:57:34 marka Exp $"; +static const char rcsid[] = "$Id: memcluster.c,v 1.3.206.7 2005/10/11 00:48:15 marka Exp $"; #endif /* not lint */ #include "port_before.h" @@ -90,12 +90,28 @@ struct stats { u_long freefrags; }; +#ifdef DO_PTHREADS +#include <pthread.h> +static pthread_mutex_t memlock = PTHREAD_MUTEX_INITIALIZER; +#define MEMLOCK (void)pthread_mutex_lock(&memlock) +#define MEMUNLOCK (void)pthread_mutex_unlock(&memlock) +#else +/* + * Catch bad lock usage in non threaded build. + */ +static unsigned int memlock = 0; +#define MEMLOCK do { INSIST(memlock == 0); memlock = 1; } while (0) +#define MEMUNLOCK do { INSIST(memlock == 1); memlock = 0; } while (0) +#endif /* DO_PTHEADS */ + /* Private data. */ static size_t max_size; static size_t mem_target; +#ifndef MEMCLUSTER_BIG_MALLOC static size_t mem_target_half; static size_t mem_target_fudge; +#endif static memcluster_element ** freelists; #ifdef MEMCLUSTER_RECORD static memcluster_element ** activelists; @@ -132,8 +148,10 @@ meminit(size_t init_max_size, size_t target_size) { mem_target = DEF_MEM_TARGET; else mem_target = target_size; +#ifndef MEMCLUSTER_BIG_MALLOC mem_target_half = mem_target / 2; mem_target_fudge = mem_target + mem_target / 4; +#endif freelists = malloc(max_size * sizeof (memcluster_element *)); stats = malloc((max_size+1) * sizeof (struct stats)); if (freelists == NULL || stats == NULL) { @@ -173,14 +191,20 @@ __memget_record(size_t size, const char *file, int line) { #endif void *ret; + MEMLOCK; + #if !defined(MEMCLUSTER_RECORD) UNUSED(file); UNUSED(line); #endif - if (freelists == NULL) - if (meminit(0, 0) == -1) + if (freelists == NULL) { + if (meminit(0, 0) == -1) { + MEMUNLOCK; return (NULL); + } + } if (size == 0U) { + MEMUNLOCK; errno = EINVAL; return (NULL); } @@ -191,6 +215,7 @@ __memget_record(size_t size, const char *file, int line) { #if defined(DEBUGGING_MEMCLUSTER) e = malloc(new_size); if (e == NULL) { + MEMUNLOCK; errno = ENOMEM; return (NULL); } @@ -202,11 +227,13 @@ __memget_record(size_t size, const char *file, int line) { e->next = activelists[max_size]; activelists[max_size] = e; #endif + MEMUNLOCK; e->fencepost = FRONT_FENCEPOST; p = (char *)e + sizeof *e + size; memcpy(p, &fp, sizeof fp); return ((char *)e + sizeof *e); #else + MEMUNLOCK; return (malloc(size)); #endif } @@ -226,6 +253,7 @@ __memget_record(size_t size, const char *file, int line) { if (basic_blocks == NULL) { new = malloc(NUM_BASIC_BLOCKS * mem_target); if (new == NULL) { + MEMUNLOCK; errno = ENOMEM; return (NULL); } @@ -253,6 +281,7 @@ __memget_record(size_t size, const char *file, int line) { total_size = mem_target; new = malloc(total_size); if (new == NULL) { + MEMUNLOCK; errno = ENOMEM; return (NULL); } @@ -318,6 +347,7 @@ __memget_record(size_t size, const char *file, int line) { stats[size].gets++; stats[size].totalgets++; stats[new_size].freefrags--; + MEMUNLOCK; #if defined(DEBUGGING_MEMCLUSTER) return ((char *)e + sizeof *e); #else @@ -347,6 +377,8 @@ __memput_record(void *mem, size_t size, const char *file, int line) { char *p; #endif + MEMLOCK; + #if !defined (MEMCLUSTER_RECORD) UNUSED(file); UNUSED(line); @@ -355,6 +387,7 @@ __memput_record(void *mem, size_t size, const char *file, int line) { REQUIRE(freelists != NULL); if (size == 0U) { + MEMUNLOCK; errno = EINVAL; return; } @@ -398,6 +431,7 @@ __memput_record(void *mem, size_t size, const char *file, int line) { INSIST(stats[max_size].gets != 0U); stats[max_size].gets--; + MEMUNLOCK; return; } @@ -436,6 +470,7 @@ __memput_record(void *mem, size_t size, const char *file, int line) { INSIST(stats[size].gets != 0U); stats[size].gets--; stats[new_size].freefrags++; + MEMUNLOCK; } void * @@ -464,8 +499,12 @@ memstats(FILE *out) { memcluster_element *e; #endif - if (freelists == NULL) + MEMLOCK; + + if (freelists == NULL) { + MEMUNLOCK; return; + } for (i = 1; i <= max_size; i++) { const struct stats *s = &stats[i]; @@ -492,6 +531,7 @@ memstats(FILE *out) { } } #endif + MEMUNLOCK; } int |
