diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-12-13 23:32:37 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2004-12-13 23:32:37 +0000 |
commit | f9626feb2d8a692e27d1c020beba198ec52a705a (patch) | |
tree | 80e2799fe980f5c79a6bce099548081def04da41 /malloc | |
parent | e797f2e35cbf7edf2c7de7f79442bda550917f07 (diff) | |
download | glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.tar.gz glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.tar.xz glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.zip |
Updated to fedora-glibc-20041213T2323 cvs/fedora-glibc-2_3_3-91
Diffstat (limited to 'malloc')
-rw-r--r-- | malloc/arena.c | 33 | ||||
-rw-r--r-- | malloc/malloc.c | 45 |
2 files changed, 49 insertions, 29 deletions
diff --git a/malloc/arena.c b/malloc/arena.c index 024e191b9e..026f2c7822 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -782,9 +782,12 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; } /* Check the global, circularly linked list for available arenas. */ + bool retried = false; repeat: do { if(!mutex_trylock(&a->mutex)) { + if (retried) + (void)mutex_unlock(&list_lock); THREAD_STAT(++(a->stat_lock_loop)); tsd_setspecific(arena_key, (Void_t *)a); return a; @@ -796,29 +799,33 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; happen during `atfork', or for example on systems where thread creation makes it temporarily impossible to obtain _any_ locks. */ - if(mutex_trylock(&list_lock)) { + if(!retried && mutex_trylock(&list_lock)) { + /* We will block to not run in a busy loop. */ + (void)mutex_lock(&list_lock); + + /* Since we blocked there might be an arena available now. */ + retried = true; a = a_tsd; goto repeat; } - (void)mutex_unlock(&list_lock); /* Nothing immediately available, so generate a new arena. */ a = _int_new_arena(size); - if(!a) - return 0; + if(a) + { + tsd_setspecific(arena_key, (Void_t *)a); + mutex_init(&a->mutex); + mutex_lock(&a->mutex); /* remember result */ - tsd_setspecific(arena_key, (Void_t *)a); - mutex_init(&a->mutex); - mutex_lock(&a->mutex); /* remember result */ + /* Add the new arena to the global list. */ + a->next = main_arena.next; + atomic_write_barrier (); + main_arena.next = a; - /* Add the new arena to the global list. */ - (void)mutex_lock(&list_lock); - a->next = main_arena.next; - atomic_write_barrier (); - main_arena.next = a; + THREAD_STAT(++(a->stat_lock_loop)); + } (void)mutex_unlock(&list_lock); - THREAD_STAT(++(a->stat_lock_loop)); return a; } diff --git a/malloc/malloc.c b/malloc/malloc.c index cf1b935ffd..e3ccbde7b5 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -4256,7 +4256,7 @@ _int_free(mstate av, Void_t* mem) || __builtin_expect (chunksize (chunk_at_offset (p, size)) >= av->system_mem, 0)) { - errstr = "invalid next size (fast)"; + errstr = "free(): invalid next size (fast)"; goto errout; } @@ -4306,7 +4306,7 @@ _int_free(mstate av, Void_t* mem) if (__builtin_expect (nextchunk->size <= 2 * SIZE_SZ, 0) || __builtin_expect (nextsize >= av->system_mem, 0)) { - errstr = "invalid next size (normal)"; + errstr = "free(): invalid next size (normal)"; goto errout; } @@ -4550,27 +4550,42 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes) INTERNAL_SIZE_T* s; /* copy source */ INTERNAL_SIZE_T* d; /* copy destination */ + const char *errstr = NULL; -#if REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - if (oldmem != 0) - _int_free(av, oldmem); - return 0; - } -#endif - - /* realloc of null is supposed to be same as malloc */ - if (oldmem == 0) return _int_malloc(av, bytes); checked_request2size(bytes, nb); oldp = mem2chunk(oldmem); oldsize = chunksize(oldp); + /* Simple tests for old block integrity. */ + if (__builtin_expect ((uintptr_t) oldp & MALLOC_ALIGN_MASK, 0)) + { + errstr = "realloc(): invalid pointer"; + errout: + malloc_printerr (check_action, errstr, oldmem); + return NULL; + } + if (__builtin_expect (oldp->size <= 2 * SIZE_SZ, 0) + || __builtin_expect (oldsize >= av->system_mem, 0)) + { + errstr = "realloc(): invalid size"; + goto errout; + } + check_inuse_chunk(av, oldp); if (!chunk_is_mmapped(oldp)) { + next = chunk_at_offset(oldp, oldsize); + INTERNAL_SIZE_T nextsize = chunksize(next); + if (__builtin_expect (next->size <= 2 * SIZE_SZ, 0) + || __builtin_expect (nextsize >= av->system_mem, 0)) + { + errstr = "realloc(): invalid next size"; + goto errout; + } + if ((unsigned long)(oldsize) >= (unsigned long)(nb)) { /* already big enough; split below */ newp = oldp; @@ -4578,11 +4593,9 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes) } else { - next = chunk_at_offset(oldp, oldsize); - /* Try to expand forward into top */ if (next == av->top && - (unsigned long)(newsize = oldsize + chunksize(next)) >= + (unsigned long)(newsize = oldsize + nextsize) >= (unsigned long)(nb + MINSIZE)) { set_head_size(oldp, nb | (av != &main_arena ? NON_MAIN_ARENA : 0)); av->top = chunk_at_offset(oldp, nb); @@ -4594,7 +4607,7 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes) /* Try to expand forward into next chunk; split off remainder below */ else if (next != av->top && !inuse(next) && - (unsigned long)(newsize = oldsize + chunksize(next)) >= + (unsigned long)(newsize = oldsize + nextsize) >= (unsigned long)(nb)) { newp = oldp; unlink(next, bck, fwd); |