On Wed, Mar 23, 2016 at 08:00:19AM +0100, Otto Moerbeek wrote:
> Hi,
>
> first diff that seems to work. Tested on amd64 and compile tested on
> sparc64.
>
> It is alo available at http://www.drijf.net/openbsd/malloc
>
> Form the README:
>
> The diff should be applied while in /usr/src/lib, it will patch
> both librthreads as as well as libc.
>
> THIS IS WORK IN PROGRESS. It contains multiple things that should
> be improved. To name a few things:
>
> - Curently fixed at 4 pools with a fixed thread -> pool mapping.
> - All pools are always initialized, even for single threaded programs, where
> only one pool is used.
> - Especially realloc gets quite a bit uglier.
> - I'm pondering storing the thread -> pool mapping in the thread
> struct instead of computing it each time from the tcb address.
>
> -Otto
>
Second diff. Only one person (Stefan Kempf, thanks!) gave feedback...
A race condition was fixed in the init code. But there remain race
problems in the init code. I will be working on that the coming time.
Please be aware that to make this code ready for commit, I need
feedback/tests/reviews. There's no way this code will end up in the tree
without those.
-Otto
Index: libc/include/thread_private.h
===================================================================
RCS file: /cvs/src/lib/libc/include/thread_private.h,v
retrieving revision 1.26
diff -u -p -r1.26 thread_private.h
--- libc/include/thread_private.h 7 Apr 2015 01:27:07 -0000 1.26
+++ libc/include/thread_private.h 28 Mar 2016 08:22:31 -0000
@@ -17,6 +17,8 @@
*/
extern int __isthreaded;
+#define _MALLOC_MUTEXES 4
+
/*
* Weak symbols are used in libc so that the thread library can
* efficiently wrap libc functions.
@@ -136,16 +138,16 @@ extern void *__THREAD_NAME(serv_mutex);
/*
* malloc lock/unlock prototypes and definitions
*/
-void _thread_malloc_lock(void);
-void _thread_malloc_unlock(void);
+void _thread_malloc_lock(int);
+void _thread_malloc_unlock(int);
-#define _MALLOC_LOCK() do { \
+#define _MALLOC_LOCK(n) do {
\
if (__isthreaded) \
- _thread_malloc_lock(); \
+ _thread_malloc_lock(n); \
} while (0)
-#define _MALLOC_UNLOCK() do { \
+#define _MALLOC_UNLOCK(n) do { \
if (__isthreaded) \
- _thread_malloc_unlock();\
+ _thread_malloc_unlock(n);\
} while (0)
void _thread_atexit_lock(void);
Index: libc/stdlib/malloc.c
===================================================================
RCS file: /cvs/src/lib/libc/stdlib/malloc.c,v
retrieving revision 1.185
diff -u -p -r1.185 malloc.c
--- libc/stdlib/malloc.c 17 Mar 2016 17:55:33 -0000 1.185
+++ libc/stdlib/malloc.c 28 Mar 2016 08:22:31 -0000
@@ -1,6 +1,6 @@
/* $OpenBSD: malloc.c,v 1.185 2016/03/17 17:55:33 mmcc Exp $ */
/*
- * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <[email protected]>
+ * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <[email protected]>
* Copyright (c) 2012 Matthew Dempsky <[email protected]>
* Copyright (c) 2008 Damien Miller <[email protected]>
* Copyright (c) 2000 Poul-Henning Kamp <[email protected]>
@@ -43,6 +43,7 @@
#endif
#include "thread_private.h"
+#include <machine/tcb.h>
#if defined(__sparc__) && !defined(__sparcv9__)
#define MALLOC_PAGESHIFT (13U)
@@ -95,10 +96,10 @@
#define _MALLOC_LEAVE(d) do { if (__isthreaded) { \
(d)->active--; \
- _MALLOC_UNLOCK(); } \
+ _MALLOC_UNLOCK(d->mutex); } \
} while (0)
#define _MALLOC_ENTER(d) do { if (__isthreaded) { \
- _MALLOC_LOCK(); \
+ _MALLOC_LOCK(d->mutex); \
(d)->active++; } \
} while (0)
@@ -129,6 +130,7 @@ struct dir_info {
void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1];
size_t rbytesused; /* random bytes used */
char *func; /* current function */
+ int mutex;
u_char rbytes[32]; /* random bytes */
u_short chunk_start;
#ifdef MALLOC_STATS
@@ -178,7 +180,7 @@ struct chunk_info {
};
struct malloc_readonly {
- struct dir_info *malloc_pool; /* Main bookkeeping information */
+ struct dir_info *malloc_pool[_MALLOC_MUTEXES]; /* Main bookkeeping
information */
int malloc_freenow; /* Free quickly - disable chunk rnd */
int malloc_freeunmap; /* mprotect free pages PROT_NONE? */
int malloc_hint; /* call madvice on free pages? */
@@ -202,14 +204,13 @@ static union {
u_char _pad[MALLOC_PAGESIZE];
} malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE)));
#define mopts malloc_readonly.mopts
-#define getpool() mopts.malloc_pool
char *malloc_options; /* compile-time options */
static u_char getrbyte(struct dir_info *d);
#ifdef MALLOC_STATS
-void malloc_dump(int);
+void malloc_dump(int, struct dir_info *);
PROTO_NORMAL(malloc_dump);
static void malloc_exit(void);
#define CALLER __builtin_return_address(0)
@@ -240,6 +241,18 @@ hash(void *p)
return sum;
}
+static inline
+struct dir_info *getpool(void)
+{
+ //return mopts.malloc_pool[0];
+ if (!__isthreaded)
+ return mopts.malloc_pool[0];
+ else
+ return mopts.malloc_pool[hash(TCB_GET()) &
+ (_MALLOC_MUTEXES - 1)];
+}
+
+
static void
wrterror(struct dir_info *d, char *msg, void *p)
{
@@ -247,7 +260,7 @@ wrterror(struct dir_info *d, char *msg,
struct iovec iov[7];
char pidbuf[20];
char buf[20];
- int saved_errno = errno;
+ int saved_errno = errno, i;
iov[0].iov_base = __progname;
iov[0].iov_len = strlen(__progname);
@@ -278,7 +291,8 @@ wrterror(struct dir_info *d, char *msg,
#ifdef MALLOC_STATS
if (mopts.malloc_stats)
- malloc_dump(STDERR_FILENO);
+ for (i = 0; i < _MALLOC_MUTEXES; i++)
+ malloc_dump(STDERR_FILENO, mopts.malloc_pool[i]);
#endif /* MALLOC_STATS */
errno = saved_errno;
@@ -565,16 +579,11 @@ omalloc_parseopt(char opt)
}
}
-/*
- * Initialize a dir_info, which should have been cleared by caller
- */
-static int
-omalloc_init(struct dir_info **dp)
+static void
+omalloc_init(void)
{
char *p, *q, b[64];
int i, j;
- size_t d_avail, regioninfo_size;
- struct dir_info *d;
/*
* Default options
@@ -637,6 +646,18 @@ omalloc_init(struct dir_info **dp)
arc4random_buf(&mopts.malloc_chunk_canary,
sizeof(mopts.malloc_chunk_canary));
+}
+
+/*
+ * Initialize a dir_info, which should have been cleared by caller
+ */
+static int
+omalloc_poolinit(struct dir_info **dp)
+{
+ void *p;
+ size_t d_avail, regioninfo_size;
+ struct dir_info *d;
+ int i, j;
/*
* Allocate dir_info with a guard page on either side. Also
@@ -644,7 +665,7 @@ omalloc_init(struct dir_info **dp)
* lies (subject to alignment by 1 << MALLOC_MINSHIFT)
*/
if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
- return -1;
+ return 1;
mprotect(p, MALLOC_PAGESIZE, PROT_NONE);
mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ,
MALLOC_PAGESIZE, PROT_NONE);
@@ -672,13 +693,6 @@ omalloc_init(struct dir_info **dp)
*dp = d;
- /*
- * Options have been set and will never be reset.
- * Prevent further tampering with them.
- */
- if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
- mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ);
-
return 0;
}
@@ -1174,20 +1188,41 @@ malloc_recurse(struct dir_info *d)
wrterror(d, "recursive call", NULL);
}
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
errno = EDEADLK;
}
static int
malloc_init(void)
{
- if (omalloc_init(&mopts.malloc_pool)) {
- _MALLOC_UNLOCK();
- if (mopts.malloc_xmalloc)
- wrterror(NULL, "out of memory", NULL);
- errno = ENOMEM;
- return -1;
+ int i;
+ struct dir_info *d;
+
+ _MALLOC_LOCK(0);
+ if (mopts.malloc_pool[0]) {
+ _MALLOC_UNLOCK(0);
+ return 0;
+ }
+ omalloc_init();
+ for (i = 0; i < _MALLOC_MUTEXES; i++) {
+ if (omalloc_poolinit(&d)) {
+ _MALLOC_UNLOCK(0);
+ if (mopts.malloc_xmalloc)
+ wrterror(NULL, "out of memory", NULL);
+ errno = ENOMEM;
+ return -1;
+ }
+ d->mutex = i;
+ mopts.malloc_pool[i] = d;
}
+
+ /*
+ * Options have been set and will never be reset.
+ * Prevent further tampering with them.
+ */
+ if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
+ mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ);
+ _MALLOC_UNLOCK(0);
return 0;
}
@@ -1198,13 +1233,13 @@ malloc(size_t size)
struct dir_info *d;
int saved_errno = errno;
- _MALLOC_LOCK();
d = getpool();
if (d == NULL) {
if (malloc_init() != 0)
return NULL;
d = getpool();
}
+ _MALLOC_LOCK(d->mutex);
d->func = "malloc():";
if (d->active++) {
@@ -1215,7 +1250,7 @@ malloc(size_t size)
size += mopts.malloc_canaries;
r = omalloc(d, size, 0, CALLER);
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) {
wrterror(d, "out of memory", NULL);
errno = ENOMEM;
@@ -1252,23 +1287,41 @@ validate_junk(struct dir_info *pool, voi
}
static void
-ofree(struct dir_info *pool, void *p)
+ofree(struct dir_info *argpool, void *p)
{
+ struct dir_info *pool;
struct region_info *r;
size_t sz;
+ int i;
+ pool = argpool;
r = find(pool, p);
if (r == NULL) {
- wrterror(pool, "bogus pointer (double free?)", p);
- return;
+ for (i = 0; i < _MALLOC_MUTEXES; i++) {
+ if (i == pool->mutex)
+ continue;
+ pool->active--;
+ _MALLOC_UNLOCK(pool->mutex);
+ pool = mopts.malloc_pool[i];
+ _MALLOC_LOCK(pool->mutex);
+ pool->active++;
+ r = find(pool, p);
+ if (r != NULL)
+ break;
+ }
+ if (r == NULL) {
+ wrterror(pool, "bogus pointer (double free?)", p);
+ goto done;
+ }
}
+
REALSIZE(sz, r);
if (sz > MALLOC_MAXCHUNK) {
if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE -
MALLOC_LEEWAY) {
if (r->p != p) {
wrterror(pool, "bogus pointer", p);
- return;
+ goto done;
}
} else {
#if notyetbecause_of_realloc
@@ -1306,13 +1359,13 @@ ofree(struct dir_info *pool, void *p)
memset(p, SOME_FREEJUNK, sz - mopts.malloc_canaries);
if (!mopts.malloc_freenow) {
if (find_chunknum(pool, r, p) == -1)
- return;
+ goto done;
i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK;
tmp = p;
p = pool->delayed_chunks[i];
if (tmp == p) {
wrterror(pool, "double free", p);
- return;
+ goto done;
}
if (mopts.malloc_junk)
validate_junk(pool, p);
@@ -1322,11 +1375,18 @@ ofree(struct dir_info *pool, void *p)
r = find(pool, p);
if (r == NULL) {
wrterror(pool, "bogus pointer (double free?)",
p);
- return;
+ goto done;
}
free_bytes(pool, r, p);
}
}
+done:
+ if (argpool != pool) {
+ pool->active--;
+ _MALLOC_UNLOCK(pool->mutex);
+ _MALLOC_LOCK(argpool->mutex);
+ argpool->active++;
+ }
}
void
@@ -1339,13 +1399,12 @@ free(void *ptr)
if (ptr == NULL)
return;
- _MALLOC_LOCK();
d = getpool();
if (d == NULL) {
- _MALLOC_UNLOCK();
wrterror(d, "free() called before allocation", NULL);
return;
}
+ _MALLOC_LOCK(d->mutex);
d->func = "free():";
if (d->active++) {
malloc_recurse(d);
@@ -1353,30 +1412,50 @@ free(void *ptr)
}
ofree(d, ptr);
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
errno = saved_errno;
}
/*DEF_STRONG(free);*/
static void *
-orealloc(struct dir_info *pool, void *p, size_t newsz, void *f)
+orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
{
+ struct dir_info *pool;
struct region_info *r;
size_t oldsz, goldsz, gnewsz;
- void *q;
+ void *q, *ret;
+ int i;
+
+ pool = argpool;
if (p == NULL)
return omalloc(pool, newsz, 0, f);
r = find(pool, p);
if (r == NULL) {
- wrterror(pool, "bogus pointer (double free?)", p);
- return NULL;
+ for (i = 0; i < _MALLOC_MUTEXES; i++) {
+ if (i == pool->mutex)
+ continue;
+ pool->active--;
+ _MALLOC_UNLOCK(pool->mutex);
+ pool = mopts.malloc_pool[i];
+ _MALLOC_LOCK(pool->mutex);
+ pool->active++;
+ r = find(pool, p);
+ if (r != NULL)
+ break;
+ }
+ if (r == NULL) {
+ wrterror(pool, "bogus pointer (double free?)", p);
+ ret = NULL;
+ goto done;
+ }
}
if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
errno = ENOMEM;
- return NULL;
+ ret = NULL;
+ goto done;
}
REALSIZE(oldsz, r);
@@ -1419,7 +1498,8 @@ gotit:
r->size = newsz;
STATS_SETF(r, f);
STATS_INC(pool->cheap_reallocs);
- return p;
+ ret = p;
+ goto done;
} else if (q != MAP_FAILED) {
if (munmap(q, needed))
wrterror(pool, "munmap", q);
@@ -1439,14 +1519,16 @@ gotit:
unmap(pool, (char *)p + rnewsz, roldsz - rnewsz);
r->size = gnewsz;
STATS_SETF(r, f);
- return p;
+ ret = p;
+ goto done;
} else {
if (newsz > oldsz && mopts.malloc_junk == 2)
memset((char *)p + newsz, SOME_JUNK,
rnewsz - mopts.malloc_guard - newsz);
r->size = gnewsz;
STATS_SETF(r, f);
- return p;
+ ret = p;
+ goto done;
}
}
if (newsz <= oldsz && newsz > oldsz / 2 && !mopts.malloc_realloc) {
@@ -1458,11 +1540,13 @@ gotit:
memset((char *)p + newsz, SOME_JUNK,
usable_oldsz - newsz);
}
STATS_SETF(r, f);
- return p;
+ ret = p;
} else if (newsz != oldsz || mopts.malloc_realloc) {
q = omalloc(pool, newsz, 0, f);
- if (q == NULL)
- return NULL;
+ if (q == NULL) {
+ ret = NULL;
+ goto done;
+ }
if (newsz != 0 && oldsz != 0) {
size_t copysz = oldsz < newsz ? oldsz : newsz;
if (copysz <= MALLOC_MAXCHUNK)
@@ -1470,11 +1554,19 @@ gotit:
memcpy(q, p, copysz);
}
ofree(pool, p);
- return q;
+ ret = q;
} else {
STATS_SETF(r, f);
- return p;
+ ret = p;
+ }
+done:
+ if (argpool != pool) {
+ pool->active--;
+ _MALLOC_UNLOCK(pool->mutex);
+ _MALLOC_LOCK(argpool->mutex);
+ argpool->active++;
}
+ return ret;
}
void *
@@ -1484,13 +1576,13 @@ realloc(void *ptr, size_t size)
void *r;
int saved_errno = errno;
- _MALLOC_LOCK();
d = getpool();
if (d == NULL) {
if (malloc_init() != 0)
return NULL;
d = getpool();
}
+ _MALLOC_LOCK(d->mutex);
d->func = "realloc():";
if (d->active++) {
malloc_recurse(d);
@@ -1501,7 +1593,7 @@ realloc(void *ptr, size_t size)
r = orealloc(d, ptr, size, CALLER);
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) {
wrterror(d, "out of memory", NULL);
errno = ENOMEM;
@@ -1526,17 +1618,17 @@ calloc(size_t nmemb, size_t size)
void *r;
int saved_errno = errno;
- _MALLOC_LOCK();
d = getpool();
if (d == NULL) {
if (malloc_init() != 0)
return NULL;
d = getpool();
}
+ _MALLOC_LOCK(d->mutex);
d->func = "calloc():";
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
if (mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
errno = ENOMEM;
@@ -1554,7 +1646,7 @@ calloc(size_t nmemb, size_t size)
r = omalloc(d, size, 1, CALLER);
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) {
wrterror(d, "out of memory", NULL);
errno = ENOMEM;
@@ -1668,13 +1760,13 @@ posix_memalign(void **memptr, size_t ali
if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *))
return EINVAL;
- _MALLOC_LOCK();
d = getpool();
if (d == NULL) {
if (malloc_init() != 0)
goto err;
d = getpool();
}
+ _MALLOC_LOCK(d->mutex);
d->func = "posix_memalign():";
if (d->active++) {
malloc_recurse(d);
@@ -1684,7 +1776,7 @@ posix_memalign(void **memptr, size_t ali
size += mopts.malloc_canaries;
r = omemalign(d, alignment, size, 0, CALLER);
d->active--;
- _MALLOC_UNLOCK();
+ _MALLOC_UNLOCK(d->mutex);
if (r == NULL) {
if (mopts.malloc_xmalloc) {
wrterror(d, "out of memory", NULL);
@@ -1923,9 +2015,8 @@ malloc_dump1(int fd, struct dir_info *d)
}
void
-malloc_dump(int fd)
+malloc_dump(int fd, struct dir_info *pool)
{
- struct dir_info *pool = getpool();
int i;
void *p;
struct region_info *r;
@@ -1956,11 +2047,12 @@ static void
malloc_exit(void)
{
static const char q[] = "malloc() warning: Couldn't dump stats\n";
- int save_errno = errno, fd;
+ int save_errno = errno, fd, i;
fd = open("malloc.out", O_RDWR|O_APPEND);
if (fd != -1) {
- malloc_dump(fd);
+ for (i = 0; i < _MALLOC_MUTEXES; i++)
+ malloc_dump(fd, mopts.malloc_pool[i]);
close(fd);
} else
write(STDERR_FILENO, q, sizeof(q) - 1);
Index: libc/thread/unithread_malloc_lock.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/unithread_malloc_lock.c,v
retrieving revision 1.9
diff -u -p -r1.9 unithread_malloc_lock.c
--- libc/thread/unithread_malloc_lock.c 7 Apr 2015 01:27:07 -0000 1.9
+++ libc/thread/unithread_malloc_lock.c 28 Mar 2016 08:22:31 -0000
@@ -28,13 +28,13 @@ WEAK_ALIAS(_thread_arc4_lock);
WEAK_ALIAS(_thread_arc4_unlock);
void
-WEAK_NAME(_thread_malloc_lock)(void)
+WEAK_NAME(_thread_malloc_lock)(int n)
{
return;
}
void
-WEAK_NAME(_thread_malloc_unlock)(void)
+WEAK_NAME(_thread_malloc_unlock)(int n)
{
return;
}
Index: librthread/rthread_fork.c
===================================================================
RCS file: /cvs/src/lib/librthread/rthread_fork.c,v
retrieving revision 1.15
diff -u -p -r1.15 rthread_fork.c
--- librthread/rthread_fork.c 27 Jan 2016 08:40:05 -0000 1.15
+++ librthread/rthread_fork.c 28 Mar 2016 08:22:31 -0000
@@ -55,6 +55,7 @@ _dofork(int is_vfork)
pthread_t me;
pid_t (*sys_fork)(void);
pid_t newid;
+ int i;
sys_fork = is_vfork ? &_thread_sys_vfork : &_thread_sys_fork;
@@ -76,7 +77,8 @@ _dofork(int is_vfork)
#endif
_thread_atexit_lock();
- _thread_malloc_lock();
+ for (i = 0; i < _MALLOC_MUTEXES; i++)
+ _thread_malloc_lock(i);
_thread_arc4_lock();
newid = sys_fork();
@@ -85,7 +87,8 @@ _dofork(int is_vfork)
if (newid == 0)
_thread_malloc_reinit();
else
- _thread_malloc_unlock();
+ for (i = 0; i < _MALLOC_MUTEXES; i++)
+ _thread_malloc_unlock(i);
_thread_atexit_unlock();
if (newid == 0) {
Index: librthread/rthread_libc.c
===================================================================
RCS file: /cvs/src/lib/librthread/rthread_libc.c,v
retrieving revision 1.13
diff -u -p -r1.13 rthread_libc.c
--- librthread/rthread_libc.c 27 Jan 2016 08:40:05 -0000 1.13
+++ librthread/rthread_libc.c 28 Mar 2016 08:22:31 -0000
@@ -152,35 +152,50 @@ _thread_mutex_destroy(void **mutex)
/*
* the malloc lock
*/
-static struct pthread_mutex malloc_lock = {
- _SPINLOCK_UNLOCKED,
- TAILQ_HEAD_INITIALIZER(malloc_lock.lockers),
- PTHREAD_MUTEX_DEFAULT,
- NULL,
- 0,
- -1
+#define MALLOC_LOCK_INITIALZER(n) { \
+ _SPINLOCK_UNLOCKED, \
+ TAILQ_HEAD_INITIALIZER(malloc_lock[n].lockers), \
+ PTHREAD_MUTEX_DEFAULT, \
+ NULL, \
+ 0, \
+ -1 } \
+
+static struct pthread_mutex malloc_lock[_MALLOC_MUTEXES] = {
+ MALLOC_LOCK_INITIALZER(0),
+ MALLOC_LOCK_INITIALZER(1),
+ MALLOC_LOCK_INITIALZER(2),
+ MALLOC_LOCK_INITIALZER(3)
+};
+static pthread_mutex_t malloc_mutex[_MALLOC_MUTEXES] = {
+ &malloc_lock[0],
+ &malloc_lock[1],
+ &malloc_lock[2],
+ &malloc_lock[3]
};
-static pthread_mutex_t malloc_mutex = &malloc_lock;
void
-_thread_malloc_lock(void)
+_thread_malloc_lock(int i)
{
- pthread_mutex_lock(&malloc_mutex);
+ pthread_mutex_lock(&malloc_mutex[i]);
}
void
-_thread_malloc_unlock(void)
+_thread_malloc_unlock(int i)
{
- pthread_mutex_unlock(&malloc_mutex);
+ pthread_mutex_unlock(&malloc_mutex[i]);
}
void
_thread_malloc_reinit(void)
{
- malloc_lock.lock = _SPINLOCK_UNLOCKED_ASSIGN;
- TAILQ_INIT(&malloc_lock.lockers);
- malloc_lock.owner = NULL;
- malloc_lock.count = 0;
+ int i;
+
+ for (i = 0; i < _MALLOC_MUTEXES; i++) {
+ malloc_lock[i].lock = _SPINLOCK_UNLOCKED_ASSIGN;
+ TAILQ_INIT(&malloc_lock[i].lockers);
+ malloc_lock[i].owner = NULL;
+ malloc_lock[i].count = 0;
+ }
}
/*