On Mon, Mar 28, 2016 at 03:40:21AM -0600, Abel Abraham Camarillo Ojeda wrote:

> On Mon, Mar 28, 2016 at 3:27 AM, Otto Moerbeek <[email protected]> wrote:
> > 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.
> >
> 
> Hi Otto,
> 
> anything specific to test or general desktop-browser-use testing is enough?
> 
> thanks

No specifics, just watch out for malloc related bugs. It's
both important that non-threaded programs and non-threaded programs
show no new bugs.


        -Otto

> 
> 
> >         -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;
> > +       }
> >  }
> >
> >  /*
> >

Reply via email to