diff --git a/src/kernel/libroot/posix/malloc/Jamfile b/src/kernel/libroot/posix/malloc/Jamfile index 8ef2235f8b..6b81e24476 100644 --- a/src/kernel/libroot/posix/malloc/Jamfile +++ b/src/kernel/libroot/posix/malloc/Jamfile @@ -1,12 +1,10 @@ SubDir OBOS_TOP src kernel libroot posix malloc ; KernelMergeObject posix_malloc.o : - <$(SOURCE_GRIST)>arch-specific.cpp - <$(SOURCE_GRIST)>heap.cpp - <$(SOURCE_GRIST)>processheap.cpp - <$(SOURCE_GRIST)>superblock.cpp - <$(SOURCE_GRIST)>threadheap.cpp - <$(SOURCE_GRIST)>wrapper.cpp - : - -DNEWOS=1 + arch-specific.cpp + heap.cpp + processheap.cpp + superblock.cpp + threadheap.cpp + wrapper.cpp ; diff --git a/src/kernel/libroot/posix/malloc/arch-specific.cpp b/src/kernel/libroot/posix/malloc/arch-specific.cpp index 4608df54a9..3768827395 100644 --- a/src/kernel/libroot/posix/malloc/arch-specific.cpp +++ b/src/kernel/libroot/posix/malloc/arch-specific.cpp @@ -20,6 +20,7 @@ //#include #include "arch-specific.h" +#include "heap.h" // How many iterations we spin waiting for a lock. enum { SPIN_LIMIT = 100 }; @@ -29,51 +30,9 @@ enum { UNLOCKED = 0, LOCKED = 1 }; extern "C" { -#ifdef NEWOS - #include -#include -#include +#include -sem_id create_sem(int32 count, const char *name); -status_t delete_sem(sem_id id); -status_t acquire_sem(sem_id id); -status_t release_sem(sem_id id); - -int hoardGetThreadID (void) -{ - return find_thread(NULL); -} - - -void hoardLockInit (hoardLockType &lock) -{ - lock.ben = 0; - lock.sem = create_sem(1, "a hoard lock"); -} - - -void hoardLock (hoardLockType &lock) -{ - if((atomic_add(&(lock.ben), 1)) >= 1) acquire_sem(lock.sem); -} - - -void hoardUnlock (hoardLockType &lock) -{ - if((atomic_add(&(lock.ben), -1)) > 1) release_sem(lock.sem); -} - -int hoardGetPageSize (void) -{ - return 4096; -} - -int hoardGetNumProcessors (void) -{ - // XXX return the real number of procs here - return 1; -} static area_id heap_region = -1; static addr_t brk; @@ -89,561 +48,123 @@ __heap_init() return 0; } -class heap_init_hack_t -{ +class heap_init_hack_t { public: - heap_init_hack_t(void) { + heap_init_hack_t(void) + { __heap_init(); } } heap_init_hack; -void * hoardSbrk (long size) + +void +hoardCreateThread(hoardThreadType &thread, + void *(*function)(void *), void *arg) +{ + thread = spawn_thread((int32 (*)(void*))function, "some thread", + B_NORMAL_PRIORITY, arg); + if (thread >= B_OK) + resume_thread(thread); + else + debugger("spawn_thread() failed!"); +} + + +void +hoardJoinThread(hoardThreadType &thread) +{ + wait_for_thread(thread, NULL); +} + + +void +hoardSetConcurrency(int) +{ +} + + +int +hoardGetThreadID(void) +{ + return find_thread(NULL); +} + + +void +hoardLockInit(hoardLockType &lock, const char *name) +{ + lock.ben = 0; + lock.sem = create_sem(0, name); +} + + +void +hoardLock(hoardLockType &lock) +{ + if (atomic_add(&(lock.ben), 1) >= 1) + acquire_sem(lock.sem); +} + + +void +hoardUnlock(hoardLockType &lock) +{ + if (atomic_add(&(lock.ben), -1) > 1) + release_sem(lock.sem); +} + + +int +hoardGetPageSize(void) +{ + return B_PAGE_SIZE; +} + + +int +hoardGetNumProcessors(void) +{ + system_info info; + if (get_system_info(&info) != B_OK) + return 1; + + return info.cpu_count; +} + + +void * +hoardSbrk(long size) { void *ret = (void *)brk; - brk += size; + brk += size + hoardHeap::ALIGNMENT - 1; return ret; + +// return sbrk(size + hoardHeap::ALIGNMENT - 1); } -void hoardUnsbrk (void * ptr, long size) + +void +hoardUnsbrk(void * ptr, long size) { - // NOT CURRENTLY IMPLEMENTED! -} - -void hoardYield (void) -{ -} - -#elif defined(WIN32) - -unsigned long hoardInterlockedExchange (unsigned long * oldval, - unsigned long newval) -{ - return InterlockedExchange (reinterpret_cast(oldval), newval); -} - -void hoardCreateThread (hoardThreadType& t, - void *(*function) (void *), - void * arg) -{ - t = CreateThread (0, 0, (LPTHREAD_START_ROUTINE) function, (LPVOID) arg, 0, 0); -} - -void hoardJoinThread (hoardThreadType& t) -{ - WaitForSingleObject (t, INFINITE); -} - -void hoardSetConcurrency (int) -{ -} - -int hoardGetThreadID (void) { - // Threads from Windows 2000 are 4 apart, - // so we shift them over to get an appropriate thread id. - int tid = GetCurrentThreadId() >> 2; - return tid; -} - -void hoardLockInit (hoardLockType& mutex) { - InterlockedExchange (&mutex, 0); -} - -void hoardLock (hoardLockType& mutex) { - // A yielding lock (with an initial spin). - int i; - while (1) { - i = 0; - while (i < SPIN_LIMIT) { - - if (mutex != LOCKED) - if (InterlockedExchange (&mutex, LOCKED) == UNLOCKED) { - // We got the lock. - return; - } - i++; - } - // Yield to other threads. - Sleep (0); - } -} - -void hoardYield (void) { - Sleep (0); -} - -void hoardUnlock (hoardLockType& mutex) { - InterlockedExchange (&mutex, UNLOCKED); -} - -void * hoardSbrk (long size) -{ - - void * ptr = HeapAlloc (GetProcessHeap(), 0, size); - - return (void *) ptr; + // NOT CURRENTLY IMPLEMENTED! } -void hoardUnsbrk (void * ptr, long size) -{ - - HeapFree (GetProcessHeap(), 0, ptr); - -} - - -int hoardGetPageSize (void) -{ - SYSTEM_INFO infoReturn[1]; - GetSystemInfo (infoReturn); - return (int) (infoReturn -> dwPageSize); -} - - -int hoardGetNumProcessors (void) -{ - static int numProcessors = 0; - if (numProcessors == 0) { - SYSTEM_INFO infoReturn[1]; - GetSystemInfo (infoReturn); - numProcessors = (int) (infoReturn -> dwNumberOfProcessors); - } - return numProcessors; -} - -#elif defined(__BEOS__) - -#include -#include - -void hoardCreateThread (hoardThreadType &t, - void *( *function)( void *), - void *arg) -{ - t = spawn_thread((int32 (*)(void*))function, "some thread", - B_NORMAL_PRIORITY, arg); - if (t >= B_OK) resume_thread(t); - else debugger("spawn_thread() failed!"); -} - - -void hoardJoinThread (hoardThreadType &t) -{ - status_t dummy; - wait_for_thread(t, &dummy); -} - - -void hoardSetConcurrency (int) +void +hoardYield(void) { } -int hoardGetThreadID (void) +unsigned long +hoardInterlockedExchange(unsigned long *oldval, + unsigned long newval) { - return find_thread(0); + // This *should* be made atomic. It's never used in the BeOS + // version, so this is included strictly for completeness. + unsigned long o = *oldval; + *oldval = newval; + return o; } - -void hoardLockInit (hoardLockType &lock) -{ - lock.ben = 0; - lock.sem = create_sem(0, "a hoard lock"); -} - - -void hoardLock (hoardLockType &lock) -{ - if((atomic_add(&(lock.ben), 1)) >= 1) acquire_sem(lock.sem); -} - - -void hoardUnlock (hoardLockType &lock) -{ - if((atomic_add(&(lock.ben), -1)) > 1) release_sem(lock.sem); -} - -int hoardGetPageSize (void) -{ - return B_PAGE_SIZE; -} - -int hoardGetNumProcessors (void) -{ - system_info si; - status_t result = get_system_info(&si); - assert (result == B_OK); - return si.cpu_count; -} - - -void * hoardSbrk (long size) -{ - return sbrk(size + hoardHeap::ALIGNMENT - 1); -} - - -void hoardUnsbrk (void * ptr, long size) -{ - // NOT CURRENTLY IMPLEMENTED! -} - -void hoardYield (void) -{ -} - -unsigned long hoardInterlockedExchange (unsigned long * oldval, - unsigned long newval) -{ - // This *should* be made atomic. It's never used in the BeOS - // version, so this is included strictly for completeness. - unsigned long o = *oldval; - *oldval = newval; - return o; -} - - -#else // UNIX - - -#if USE_SPROC -#include -#include -#include -#include -#endif - - -void hoardCreateThread (hoardThreadType& t, - void *(*function) (void *), - void * arg) -{ -#if USE_SPROC - typedef void (*sprocFunction) (void *); - t = sproc ((sprocFunction) function, PR_SADDR, arg); -#else - pthread_attr_t attr; - pthread_attr_init (&attr); -#if defined(_AIX) - // Bound (kernel-level) threads. - pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); -#endif - pthread_create (&t, &attr, function, arg); -#endif -} - -void hoardJoinThread (hoardThreadType& t) -{ -#if USE_SPROC - waitpid (t, 0, 0); -#else - pthread_join (t, NULL); -#endif -} - -#if defined(__linux) -// This extern declaration is required for Linux. -extern "C" void pthread_setconcurrency (int n); -#endif - -void hoardSetConcurrency (int n) -{ -#if USE_SPROC - usconfig (CONF_INITUSERS, n); -#elif defined(__SVR4) // Solaris - thr_setconcurrency (n); -#else - pthread_setconcurrency (n); -#endif -} - - -#if defined(__SVR4) // Solaris - -// Solaris's two-level threads model gives us an edge here; -// we can hash on the LWP's id. This helps us in two ways: -// (1) there are likely to be far fewer LWP's than threads, -// (2) if there's a one-to-one correspondence between LWP's -// and the number of processors (usually the case), then -// the number of heaps used will be the same as the number -// of processors (the optimal case). -// Here we rely on an undocumented call in libthread.so, which -// turns out to be MUCH cheaper than the documented _lwp_self(). Go figure. - -extern "C" unsigned int lwp_self(void); -#endif - -int hoardGetThreadID (void) { -#if USE_SPROC - // This hairiness has the same effect as calling getpid(), - // but it's MUCH faster since it avoids making a system call - // and just accesses the sproc-local data directly. - int pid = (int) PRDA->sys_prda.prda_sys.t_pid; - return pid; -#else -#if defined(__linux) - // Consecutive thread id's in Linux are 1024 apart; - // dividing off the 1024 gives us an appropriate thread id. - return (int) pthread_self() >> 10; // (>> 10 = / 1024) -#endif -#if defined(__AIX) - // Consecutive thread id's in AIX are 257 apart; - // dividing off the 257 gives us an appropriate thread id. - return (int) pthread_self() / 257; -#endif -#if defined(__SVR4) - return (int) lwp_self(); -#endif - return (int) pthread_self(); -#endif -} - - -// If we are using either Intel or SPARC, -// we use our own lock implementation -// (spin then yield). This is much cheaper than -// the ordinary mutex, at least on Linux and Solaris. - -#if USER_LOCKS && (defined(i386) || defined(sparc) || defined(__sgi) || defined(ppc)) - -#include - -#if defined(__sgi) -#include -#endif - - -// Atomically: -// retval = *oldval; -// *oldval = newval; -// return retval; - -#if defined(sparc) && !defined(__GNUC__) -extern "C" unsigned long InterlockedExchange (unsigned long * oldval, - unsigned long newval); -#else -unsigned long InterlockedExchange (unsigned long * oldval, - unsigned long newval) -{ -#if defined(sparc) - asm volatile ("swap [%1],%0" - :"=r" (newval) - :"r" (oldval), "0" (newval) - : "memory"); - -#endif -#if defined(i386) - asm volatile ("xchgl %0, %1" - : "=r" (newval) - : "m" (*oldval), "0" (newval) - : "memory"); -#endif -#if defined(__sgi) - newval = test_and_set (oldval, newval); -#endif -#if defined(ppc) - int ret; - asm volatile ("sync;" - "0: lwarx %0,0,%1 ;" - " xor. %0,%3,%0;" - " bne 1f;" - " stwcx. %2,0,%1;" - " bne- 0b;" - "1: sync" - : "=&r"(ret) - : "r"(oldval), "r"(newval), "r"(*oldval) - : "cr0", "memory"); -#endif - return newval; -} -#endif - -unsigned long hoardInterlockedExchange (unsigned long * oldval, - unsigned long newval) -{ - return InterlockedExchange (oldval, newval); -} - -void hoardLockInit (hoardLockType& mutex) { - InterlockedExchange (&mutex, UNLOCKED); -} - -#include - -void hoardLock (hoardLockType& mutex) { - // A yielding lock (with an initial spin). - int i; - while (1) { - i = 0; - while (i < SPIN_LIMIT) { - if (InterlockedExchange (&mutex, LOCKED) == UNLOCKED) { - // We got the lock. - return; - } - i++; - } - // The lock is still being held by someone else. - // Give up our quantum. - sched_yield (); - } -} - -void hoardUnlock (hoardLockType& mutex) { - InterlockedExchange (&mutex, UNLOCKED); -} - -#else - -// use non-user-level locks. - -#endif // USER_LOCKS - -void hoardYield (void) -{ - sched_yield (); -} - -#if 1 // !(defined(__sgi)) -#include -#include -#include -#include -#include -#endif - - -void * hoardSbrk (long size) { - // Use mmap for everything but SGI. - // Apparently sproc's and mmap's don't cooperate. -#if 0 // defined(__sgi) - // Protect calls to sbrk() with a lock. -#if USER_LOCKS - static hoardLockType sbrkLock = 0; -#else - static hoardLockType sbrkLock = PTHREAD_MUTEX_INITIALIZER; -#endif - - hoardLock (sbrkLock); - // The "sizeof(double)" should equal hoardHeap::ALIGNMENT. - // This is a workaround (compiler error in g++). - void * moreMemory = sbrk (size + sizeof(double) - 1); - hoardUnlock (sbrkLock); - return moreMemory; -#else - -#if defined(linux) -#if USER_LOCKS - static hoardLockType sbrkLock = 0; -#else - static hoardLockType sbrkLock = PTHREAD_MUTEX_INITIALIZER; -#endif -#endif - // Use mmap to get memory from the backing store. - static int fd = ::open ("/dev/zero", O_RDWR); -#if defined(linux) - hoardLock (sbrkLock); - - // Map starting at this address to maximize the amount of memory - // available to Hoard. Thanks to Jim Nance for this tip. - char * ptr = (char *) mmap ((void *) 0x10000000, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); -#else - char * ptr = (char *) mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); -#endif - - char * retPtr; - if (ptr == (char *) MAP_FAILED) { - retPtr = NULL; - } else { - retPtr = ptr; - } -#if defined(linux) - hoardUnlock (sbrkLock); -#endif - return retPtr; -#endif -} - - -void hoardUnsbrk (void * ptr, long size) -{ -#if defined(linux) -#if USER_LOCKS - static hoardLockType sbrkLock = 0; -#else - static hoardLockType sbrkLock = PTHREAD_MUTEX_INITIALIZER; -#endif -#endif -#if defined(linux) - hoardLock (sbrkLock); -#endif - int result = munmap ((char *) ptr, size); - assert (result == 0); -#if defined(linux) - hoardUnlock (sbrkLock); -#endif -} - - -int hoardGetPageSize (void) -{ - return (int) sysconf(_SC_PAGESIZE); -} - - -#if defined(linux) -#include -#include -#include -#include -#endif - -#if defined(__sgi) -#include -#include -#include -#endif - -int hoardGetNumProcessors (void) -{ -#if !(defined(linux)) -#if defined(__sgi) - static int np = (int) sysmp(MP_NAPROCS); - return np; -#else - static int np = (int) sysconf(_SC_NPROCESSORS_ONLN); - return np; -#endif -#else - static int numProcessors = 0; - - if (numProcessors == 0) { - // Ugly workaround. Linux's sysconf indirectly calls malloc() (at - // least on multiprocessors). So we just read the info from the - // proc file ourselves and count the occurrences of the word - // "processor". - - // We only parse the first 32K of the CPU file. By my estimates, - // that should be more than enough for at least 64 processors. - enum { MAX_PROCFILE_SIZE = 32768 }; - char line[MAX_PROCFILE_SIZE]; - int fd = open ("/proc/cpuinfo", O_RDONLY); - assert (fd); - read(fd, line, MAX_PROCFILE_SIZE); - char * str = line; - while (str) { - str = strstr(str, "processor"); - if (str) { - numProcessors++; - str++; - } - } - close (fd); - assert (numProcessors > 0); - } - return numProcessors; -#endif -} - -#endif // UNIX - } diff --git a/src/kernel/libroot/posix/malloc/arch-specific.h b/src/kernel/libroot/posix/malloc/arch-specific.h index e0340abe42..9933e725c7 100644 --- a/src/kernel/libroot/posix/malloc/arch-specific.h +++ b/src/kernel/libroot/posix/malloc/arch-specific.h @@ -22,92 +22,24 @@ #include "config.h" -#if defined(NEWOS) - -#include +#include #include -#else - -// Wrap architecture-specific functions. - -#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) - -// Windows - -#ifndef WIN32 -#define WIN32 1 -#endif -#include -#include -typedef LONG hoardLockType; -typedef HANDLE hoardThreadType; - -#elif defined(__BEOS__) - -// BeOS - -#include - - -#elif USE_SPROC - -// SGI's SPROC library - -#include -#include - -#else - -// Generic UNIX - -#if defined(__SVR4) // Solaris -#include -#endif - -#include -#include - -#endif -#endif - -#if defined(NEWOS) typedef struct { - int32 ben; - sem_id sem; + int32 ben; + sem_id sem; } hoardLockType; -typedef thread_id hoardThreadType; -inline void * operator new(size_t, void *_P) - {return (_P); } -#else +inline void * +operator new(size_t, void *_P) +{ + return _P; +} -#ifndef WIN32 -#if defined(__BEOS__) -typedef struct { - int32 ben; - sem_id sem; -} hoardLockType; -#elif USER_LOCKS && (defined(i386) || defined(sparc) || defined(__sgi)) -typedef unsigned long hoardLockType; -#else -typedef pthread_mutex_t hoardLockType; -#endif - -#if USE_SPROC -typedef pid_t hoardThreadType; -#elif defined(__BEOS__) -typedef thread_id hoardThreadType; -#else -typedef pthread_t hoardThreadType; -#endif - -#endif -#endif +typedef thread_id hoardThreadType; extern "C" { - ///// Thread-related wrappers. void hoardCreateThread (hoardThreadType& t, @@ -123,27 +55,9 @@ extern "C" { ///// Lock-related wrappers. -#if !defined(WIN32) && !defined(__BEOS__) && !USER_LOCKS - - // Define the lock operations inline to save a little overhead. - - inline void hoardLockInit (hoardLockType& lock) { - pthread_mutex_init (&lock, NULL); - } - - inline void hoardLock (hoardLockType& lock) { - pthread_mutex_lock (&lock); - } - - inline void hoardUnlock (hoardLockType& lock) { - pthread_mutex_unlock (&lock); - } -#else - void hoardLockInit (hoardLockType& lock); - void hoardLock (hoardLockType& lock); - void hoardUnlock (hoardLockType& lock); - -#endif + void hoardLockInit(hoardLockType& lock, const char *name); + void hoardLock(hoardLockType& lock); + void hoardUnlock(hoardLockType& lock); ///// Memory-related wrapper. @@ -160,4 +74,3 @@ extern "C" { } #endif // _ARCH_SPECIFIC_H_ - diff --git a/src/kernel/libroot/posix/malloc/heap.cpp b/src/kernel/libroot/posix/malloc/heap.cpp index d99f8f3f32..1c9cfa0306 100644 --- a/src/kernel/libroot/posix/malloc/heap.cpp +++ b/src/kernel/libroot/posix/malloc/heap.cpp @@ -23,7 +23,7 @@ #include "processheap.h" #include "superblock.h" -static const char version[] = "The Hoard memory allocator, version 2.0 (http://www.hoard.org). Copyright (C) 1998, 1999, 2000 The University of Texas at Austin. $Id: heap.cpp,v 1.1 2002/10/05 17:13:30 axeld Exp $"; +static const char version[] = "The Hoard memory allocator, version 2.0 (http://www.hoard.org). Copyright (C) 1998, 1999, 2000 The University of Texas at Austin. $Id: heap.cpp,v 1.2 2005/02/10 18:47:16 axeld Exp $"; // NB: Use maketable.cpp to update this // if SIZE_CLASSES, ALIGNMENT, SIZE_CLASS_BASE, MAX_EMPTY_SUPERBLOCKS, @@ -61,7 +61,7 @@ hoardHeap::hoardHeap (void) #endif { // Initialize the per-heap lock. - hoardLockInit (_lock); + hoardLockInit(_lock, "hoard heap"); for (int i = 0; i < SUPERBLOCK_FULLNESS_GROUP; i++) { for (int j = 0; j < SIZE_CLASSES; j++) { // Initialize all superblocks lists to empty. diff --git a/src/kernel/libroot/posix/malloc/heap.h b/src/kernel/libroot/posix/malloc/heap.h index 5d43fa0b15..5f783f1fdb 100644 --- a/src/kernel/libroot/posix/malloc/heap.h +++ b/src/kernel/libroot/posix/malloc/heap.h @@ -17,27 +17,14 @@ // ////////////////////////////////////////////////////////////////////////////// -/* - heap.h - ------------------------------------------------------------------------ - hoardHeap, the base class for threadHeap and processHeap. - ------------------------------------------------------------------------ - @(#) $Id: heap.h,v 1.1 2002/10/05 17:13:30 axeld Exp $ - ------------------------------------------------------------------------ - Emery Berger | - Department of Computer Sciences | - University of Texas at Austin | - ======================================================================== -*/ - +/* hoardHeap, the base class for threadHeap and processHeap. */ #ifndef _HEAP_H_ #define _HEAP_H_ -#include "config.h" +#include -//include -//#include +#include "config.h" #include "arch-specific.h" #include "superblock.h" @@ -74,7 +61,7 @@ public: // number of threads -- Hoard imposes no such limit.) This must be // a power of two! NB: This number is twice the maximum number of // PROCESSORS supported by Hoard. - enum { MAX_HEAPS = 128 }; + enum { MAX_HEAPS = B_MAX_CPU_COUNT }; // ANDing with this rounds to MAX_HEAPS. enum { MAX_HEAPS_MASK = MAX_HEAPS - 1 }; @@ -93,7 +80,7 @@ public: #elif MAX_INTERNAL_FRAGMENTATION == 10 enum { SIZE_CLASSES = 32 }; #else -#error "Undefined size class base." +# error "Undefined size class base." #endif // Every object is aligned so that it can always hold a double. @@ -203,7 +190,7 @@ private: // For sanity checking. const unsigned long _magic; #else - #define _magic HEAP_MAGIC +# define _magic HEAP_MAGIC #endif // Heap statistics. diff --git a/src/kernel/libroot/posix/malloc/processheap.cpp b/src/kernel/libroot/posix/malloc/processheap.cpp index 61ee8224aa..b0c1343bfa 100644 --- a/src/kernel/libroot/posix/malloc/processheap.cpp +++ b/src/kernel/libroot/posix/malloc/processheap.cpp @@ -62,9 +62,9 @@ processHeap::processHeap (void) } #endif #if HEAP_FRAG_STATS - hoardLockInit (_statsLock); + hoardLockInit(_statsLock, "hoard stats"); #endif - hoardLockInit (_bufferLock); + hoardLockInit(_bufferLock, "hoard buffer"); } diff --git a/src/kernel/libroot/posix/malloc/processheap.h b/src/kernel/libroot/posix/malloc/processheap.h index d39d57e34d..04beb840af 100644 --- a/src/kernel/libroot/posix/malloc/processheap.h +++ b/src/kernel/libroot/posix/malloc/processheap.h @@ -17,18 +17,7 @@ // ////////////////////////////////////////////////////////////////////////////// -/* - processheap.h - ------------------------------------------------------------------------ - We use one processHeap for the whole program. - ------------------------------------------------------------------------ - @(#) $Id: processheap.h,v 1.1 2002/10/05 17:13:30 axeld Exp $ - ------------------------------------------------------------------------ - Emery Berger | - Department of Computer Sciences | - University of Texas at Austin | - ======================================================================== -*/ +/* We use one processHeap for the whole program. */ #ifndef _PROCESSHEAP_H_ #define _PROCESSHEAP_H_ diff --git a/src/kernel/libroot/posix/malloc/superblock.cpp b/src/kernel/libroot/posix/malloc/superblock.cpp index 0065c352e7..7af9db805c 100644 --- a/src/kernel/libroot/posix/malloc/superblock.cpp +++ b/src/kernel/libroot/posix/malloc/superblock.cpp @@ -22,7 +22,7 @@ The superblock class controls a number of blocks (which are allocatable units of memory). ------------------------------------------------------------------------ - @(#) $Id: superblock.cpp,v 1.1 2002/10/05 17:13:30 axeld Exp $ + @(#) $Id: superblock.cpp,v 1.2 2005/02/10 18:47:16 axeld Exp $ ------------------------------------------------------------------------ Emery Berger | Department of Computer Sciences | @@ -84,7 +84,7 @@ superblock::superblock (int numBlocks, // The number of blocks in the sb. computeFullness(); assert ((unsigned long) b <= hoardHeap::align (sizeof(superblock) + blksize * _numBlocks) + (unsigned long) this); - hoardLockInit (_upLock); + hoardLockInit(_upLock, "hoard superblock"); } superblock * superblock::makeSuperblock (int sizeclass, diff --git a/src/kernel/libroot/posix/malloc/wrapper.cpp b/src/kernel/libroot/posix/malloc/wrapper.cpp index 9fcadbec80..e9d52c9d71 100644 --- a/src/kernel/libroot/posix/malloc/wrapper.cpp +++ b/src/kernel/libroot/posix/malloc/wrapper.cpp @@ -17,40 +17,25 @@ // ////////////////////////////////////////////////////////////////////////////// -/* - wrapper.cpp - ------------------------------------------------------------------------ - Implementations of malloc(), free(), etc. in terms of hoard. - This lets us link in hoard in place of the stock malloc - (useful to test fragmentation). - ------------------------------------------------------------------------ - @(#) $Id: wrapper.cpp,v 1.1 2002/10/05 17:13:30 axeld Exp $ - ------------------------------------------------------------------------ - Emery Berger | - Department of Computer Sciences | - University of Texas at Austin | - ======================================================================== -*/ +/* Implementations of malloc(), free(), etc. in terms of hoard. + * This lets us link in hoard in place of the stock malloc + * (useful to test fragmentation). + */ #include #include "config.h" - -#if USE_PRIVATE_HEAPS -#include "privateheap.h" -#define HEAPTYPE privateHeap -#else #include "threadheap.h" -#define HEAPTYPE threadHeap -#endif - #include "processheap.h" #include "arch-specific.h" -inline static processHeap * getAllocator (void) { - static char * buf = (char *) hoardSbrk (sizeof(processHeap)); - static processHeap * theAllocator = new (buf) processHeap; - return theAllocator; +inline static processHeap * +getAllocator(void) +{ + static char *buffer = (char *)hoardSbrk(sizeof(processHeap)); + static processHeap *theAllocator = new (buffer) processHeap; + + return theAllocator; } #define HOARD_MALLOC(x) malloc(x) @@ -97,173 +82,86 @@ void operator delete[] (void * ptr) } -extern "C" void * HOARD_MALLOC (size_t sz) +extern "C" void * +malloc(size_t size) { - static processHeap * pHeap = getAllocator(); - void * addr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (sz); - return addr; + static processHeap *pHeap = getAllocator(); + + void *addr = pHeap->getHeap(pHeap->getHeapIndex()).malloc(size); + return addr; } -extern "C" void * HOARD_CALLOC (size_t nelem, size_t elsize) + +extern "C" void * +calloc(size_t nelem, size_t elsize) { - static processHeap * pHeap = getAllocator(); - void * ptr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (nelem * elsize); - // Zero out the malloc'd block. - memset (ptr, 0, nelem * elsize); - return ptr; + static processHeap *pHeap = getAllocator(); + void *ptr = pHeap->getHeap(pHeap->getHeapIndex()).malloc(nelem * elsize); + + // Zero out the malloc'd block. + memset(ptr, 0, nelem * elsize); + return ptr; } -extern "C" void HOARD_FREE (void * ptr) + +extern "C" void +free(void *ptr) { - static processHeap * pHeap = getAllocator(); -#if USE_PRIVATE_HEAPS - pHeap->getHeap(pHeap->getHeapIndex()).free(ptr); -#else - pHeap->free (ptr); -#endif + static processHeap *pHeap = getAllocator(); + pHeap->free(ptr); } -extern "C" void * HOARD_MEMALIGN (size_t alignment, size_t size) +extern "C" void * +memalign(size_t alignment, size_t size) { - static processHeap * pHeap = getAllocator(); - void * addr = pHeap->getHeap(pHeap->getHeapIndex()).memalign (alignment, size); - return addr; + static processHeap *pHeap = getAllocator(); + void *addr = pHeap->getHeap(pHeap->getHeapIndex()).memalign (alignment, size); + + return addr; } -extern "C" void * HOARD_VALLOC (size_t size) +extern "C" void * +valloc(size_t size) { - return HOARD_MEMALIGN (hoardGetPageSize(), size); + return memalign(hoardGetPageSize(), size); } -extern "C" void * HOARD_REALLOC (void * ptr, size_t sz) +extern "C" void * +realloc(void *ptr, size_t sz) { - if (ptr == NULL) { - return HOARD_MALLOC (sz); - } - if (sz == 0) { - HOARD_FREE (ptr); - return NULL; - } + if (ptr == NULL) + return HOARD_MALLOC (sz); - // If the existing object can hold the new size, - // just return it. + if (sz == 0) { + free(ptr); + return NULL; + } - size_t objSize = HEAPTYPE::objectSize (ptr); + // If the existing object can hold the new size, + // just return it. - if (objSize >= sz) { - return ptr; - } + size_t objSize = threadHeap::objectSize(ptr); + if (objSize >= sz) + return ptr; - // Allocate a new block of size sz. + // Allocate a new block of size sz. - void * buf = HOARD_MALLOC (sz); + void *buffer = malloc(sz); - // Copy the contents of the original object - // up to the size of the new block. + // Copy the contents of the original object + // up to the size of the new block. - size_t minSize = (objSize < sz) ? objSize : sz; - memcpy (buf, ptr, minSize); + size_t minSize = (objSize < sz) ? objSize : sz; + memcpy(buffer, ptr, minSize); - // Free the old block. + // Free the old block. - HOARD_FREE (ptr); + free(ptr); - // Return a pointer to the new one. - - return buf; + // Return a pointer to the new one. + return buffer; } - -#ifdef WIN32 - -// Replace the CRT debugging allocation routines, just to be on the safe side. -// This is not a complete solution, but should avoid inadvertent mixing of allocations. - -extern "C" void * _malloc_dbg (size_t sz, int, const char *, int) { - return HOARD_MALLOC (sz); -} - -void * operator new( - unsigned int cb, - int nBlockUse, - const char * szFileName, - int nLine - ) -{ - return HOARD_MALLOC (cb); -} - -extern "C" void * _calloc_dbg (size_t num, size_t size, int, const char *, int) { - return HOARD_CALLOC (num, size); -} - -extern "C" void * _realloc_dbg (void * ptr, size_t newSize, int, const char *, int) { - return HOARD_REALLOC (ptr, newSize); -} - -extern "C" void _free_dbg (void * ptr, int) { - HOARD_FREE (ptr); -} - -extern "C" size_t _msize_dbg (void * ptr) { - // Find the block and superblock corresponding to this ptr. - - block * b = (block *) ptr - 1; - assert (b->isValid()); - - // Check to see if this block came from a memalign() call. - if (((unsigned long) b->getNext() & 1) == 1) { - // It did. Set the block to the actual block header. - b = (block *) ((unsigned long) b->getNext() & ~1); - assert (b->isValid()); - } - - superblock * sb = b->getSuperblock(); - assert (sb); - assert (sb->isValid()); - - const int sizeclass = sb->getBlockSizeClass(); - return hoardHeap::sizeFromClass (sizeclass); -} - -extern "C" size_t _msize (void * ptr) { - // Find the block and superblock corresponding to this ptr. - - block * b = (block *) ptr - 1; - assert (b->isValid()); - - // Check to see if this block came from a memalign() call. - if (((unsigned long) b->getNext() & 1) == 1) { - // It did. Set the block to the actual block header. - b = (block *) ((unsigned long) b->getNext() & ~1); - assert (b->isValid()); - } - - superblock * sb = b->getSuperblock(); - assert (sb); - assert (sb->isValid()); - - const int sizeclass = sb->getBlockSizeClass(); - return hoardHeap::sizeFromClass (sizeclass); -} - -extern "C" void * _nh_malloc_base (size_t sz, int) { - return HOARD_MALLOC (sz); -} - -extern "C" void * _nh_malloc_dbg (size_t sz, size_t, int, int, const char *, int) { - return HOARD_MALLOC (sz); -} - -#endif // WIN32 - - -#if 0 -extern "C" void malloc_stats (void) -{ - TheWrapper.TheAllocator()->stats(); -} -#endif