[Xenomai-git] Philippe Gerum : copperplate/heapobj-malloc: enforce hard limit on pool size
Module: xenomai-forge Branch: master Commit: 5d3fae825a8b92dca86f4cdc4b6c4ccabe19d1ce URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=5d3fae825a8b92dca86f4cdc4b6c4ccabe19d1ce Author: Philippe Gerum Date: Thu May 9 12:22:05 2013 +0200 copperplate/heapobj-malloc: enforce hard limit on pool size Applications may rely on hard limits when creating memory pools, to detect over-consumption. Since the global malloc heap is virtually illimited, we do allocation size accounting for each malloc-based heap and reject over budget requests. --- include/copperplate/heapobj.h| 55 - lib/copperplate/heapobj-malloc.c | 127 +- 2 files changed, 139 insertions(+), 43 deletions(-) diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h index 2dad005..39b6b06 100644 --- a/include/copperplate/heapobj.h +++ b/include/copperplate/heapobj.h @@ -140,22 +140,10 @@ static inline char *pvstrdup(const char *ptr) #include -static inline -void pvheapobj_destroy(struct heapobj *hobj) -{ -} - -static inline -int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) -{ - return 0; -} - -static inline -void *pvheapobj_alloc(struct heapobj *hobj, size_t size) +static inline void *pvmalloc(size_t size) { /* -* XXX: We don't want debug _nrt assertions to trigger when +* NOTE: We don't want debug _nrt assertions to trigger when * running over Cobalt if the user picked this allocator, so * we make sure to call the glibc directly, not the Cobalt * wrappers. @@ -163,44 +151,27 @@ void *pvheapobj_alloc(struct heapobj *hobj, size_t size) return __STD(malloc(size)); } -static inline -void pvheapobj_free(struct heapobj *hobj, void *ptr) +static inline void pvfree(void *ptr) { __STD(free(ptr)); } -static inline -size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) +static inline char *pvstrdup(const char *ptr) { - /* -* We will likely get hard validation here, i.e. crash or -* abort if the pointer is wrong. TLSF is a bit smarter, and -* pshared definitely does the right thing. -*/ - return malloc_usable_size(ptr); + return strdup(ptr); } -static inline -size_t pvheapobj_inquire(struct heapobj *hobj) -{ - struct mallinfo m = mallinfo(); - return m.uordblks; -} +void pvheapobj_destroy(struct heapobj *hobj); -static inline void *pvmalloc(size_t size) -{ - return __STD(malloc(size)); -} +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem); -static inline void pvfree(void *ptr) -{ - __STD(free(ptr)); -} +void *pvheapobj_alloc(struct heapobj *hobj, size_t size); -static inline char *pvstrdup(const char *ptr) -{ - return strdup(ptr); -} +void pvheapobj_free(struct heapobj *hobj, void *ptr); + +size_t pvheapobj_inquire(struct heapobj *hobj); + +size_t pvheapobj_validate(struct heapobj *hobj, void *ptr); #endif /* !CONFIG_XENO_TLSF */ diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 96814b9..14d624e 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -20,19 +20,51 @@ #include #include #include +#include +#include +#include "copperplate/lock.h" #include "copperplate/heapobj.h" #include "copperplate/debug.h" +#define MALLOC_MAGIC 0xabbfcddc + +struct pool_header { + pthread_mutex_t lock; + size_t used; +}; + +struct block_header { + unsigned int magic; + size_t size; +}; + int __heapobj_init_private(struct heapobj *hobj, const char *name, size_t size, void *mem) { + pthread_mutexattr_t mattr; + struct pool_header *ph; + /* * There is no local pool when working with malloc, we just * use the global process arena. This should not be an issue * since this mode is aimed at debugging, particularly to be * used along with Valgrind. +* +* However, we maintain a control header to track the amount +* of memory currently consumed in each heap. */ - hobj->pool = mem; /* Never used. */ + ph = malloc(sizeof(*ph)); + if (ph == NULL) + return __bt(-ENOMEM); + + __RT(pthread_mutexattr_init(&mattr)); + __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT)); + __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE)); + __RT(pthread_mutex_init(&ph->lock, &mattr)); + __RT(pthread_mutexattr_destroy(&mattr)); + ph->used = 0; + + hobj->pool = ph; hobj->size = size; if (name) snprintf(hobj->name, sizeof(hobj->name), "%s", name); @@ -48,6 +80,99 @@ int heapobj_init_array_private(struct heapobj *hobj, const char *name, return __bt(__heapobj_init_private(hobj, name, size * elems, NULL)); } +void pvheapobj_destroy(
[Xenomai-git] Philippe Gerum : copperplate/heapobj-malloc: enforce hard limit on pool size
Module: xenomai-forge Branch: next Commit: 5d3fae825a8b92dca86f4cdc4b6c4ccabe19d1ce URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=5d3fae825a8b92dca86f4cdc4b6c4ccabe19d1ce Author: Philippe Gerum Date: Thu May 9 12:22:05 2013 +0200 copperplate/heapobj-malloc: enforce hard limit on pool size Applications may rely on hard limits when creating memory pools, to detect over-consumption. Since the global malloc heap is virtually illimited, we do allocation size accounting for each malloc-based heap and reject over budget requests. --- include/copperplate/heapobj.h| 55 - lib/copperplate/heapobj-malloc.c | 127 +- 2 files changed, 139 insertions(+), 43 deletions(-) diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h index 2dad005..39b6b06 100644 --- a/include/copperplate/heapobj.h +++ b/include/copperplate/heapobj.h @@ -140,22 +140,10 @@ static inline char *pvstrdup(const char *ptr) #include -static inline -void pvheapobj_destroy(struct heapobj *hobj) -{ -} - -static inline -int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) -{ - return 0; -} - -static inline -void *pvheapobj_alloc(struct heapobj *hobj, size_t size) +static inline void *pvmalloc(size_t size) { /* -* XXX: We don't want debug _nrt assertions to trigger when +* NOTE: We don't want debug _nrt assertions to trigger when * running over Cobalt if the user picked this allocator, so * we make sure to call the glibc directly, not the Cobalt * wrappers. @@ -163,44 +151,27 @@ void *pvheapobj_alloc(struct heapobj *hobj, size_t size) return __STD(malloc(size)); } -static inline -void pvheapobj_free(struct heapobj *hobj, void *ptr) +static inline void pvfree(void *ptr) { __STD(free(ptr)); } -static inline -size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) +static inline char *pvstrdup(const char *ptr) { - /* -* We will likely get hard validation here, i.e. crash or -* abort if the pointer is wrong. TLSF is a bit smarter, and -* pshared definitely does the right thing. -*/ - return malloc_usable_size(ptr); + return strdup(ptr); } -static inline -size_t pvheapobj_inquire(struct heapobj *hobj) -{ - struct mallinfo m = mallinfo(); - return m.uordblks; -} +void pvheapobj_destroy(struct heapobj *hobj); -static inline void *pvmalloc(size_t size) -{ - return __STD(malloc(size)); -} +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem); -static inline void pvfree(void *ptr) -{ - __STD(free(ptr)); -} +void *pvheapobj_alloc(struct heapobj *hobj, size_t size); -static inline char *pvstrdup(const char *ptr) -{ - return strdup(ptr); -} +void pvheapobj_free(struct heapobj *hobj, void *ptr); + +size_t pvheapobj_inquire(struct heapobj *hobj); + +size_t pvheapobj_validate(struct heapobj *hobj, void *ptr); #endif /* !CONFIG_XENO_TLSF */ diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 96814b9..14d624e 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -20,19 +20,51 @@ #include #include #include +#include +#include +#include "copperplate/lock.h" #include "copperplate/heapobj.h" #include "copperplate/debug.h" +#define MALLOC_MAGIC 0xabbfcddc + +struct pool_header { + pthread_mutex_t lock; + size_t used; +}; + +struct block_header { + unsigned int magic; + size_t size; +}; + int __heapobj_init_private(struct heapobj *hobj, const char *name, size_t size, void *mem) { + pthread_mutexattr_t mattr; + struct pool_header *ph; + /* * There is no local pool when working with malloc, we just * use the global process arena. This should not be an issue * since this mode is aimed at debugging, particularly to be * used along with Valgrind. +* +* However, we maintain a control header to track the amount +* of memory currently consumed in each heap. */ - hobj->pool = mem; /* Never used. */ + ph = malloc(sizeof(*ph)); + if (ph == NULL) + return __bt(-ENOMEM); + + __RT(pthread_mutexattr_init(&mattr)); + __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT)); + __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE)); + __RT(pthread_mutex_init(&ph->lock, &mattr)); + __RT(pthread_mutexattr_destroy(&mattr)); + ph->used = 0; + + hobj->pool = ph; hobj->size = size; if (name) snprintf(hobj->name, sizeof(hobj->name), "%s", name); @@ -48,6 +80,99 @@ int heapobj_init_array_private(struct heapobj *hobj, const char *name, return __bt(__heapobj_init_private(hobj, name, size * elems, NULL)); } +void pvheapobj_destroy(st
[Xenomai-git] Philippe Gerum : copperplate/heapobj-malloc: enforce hard limit on pool size
Module: xenomai-forge Branch: next Commit: 900e0c3f84b8e8374e64b2d6932cce9328713d80 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=900e0c3f84b8e8374e64b2d6932cce9328713d80 Author: Philippe Gerum Date: Thu May 9 12:22:05 2013 +0200 copperplate/heapobj-malloc: enforce hard limit on pool size Applications may rely on hard limits when creating memory pools, to detect over-consumption. Since the global malloc heap is virtually illimited, we do allocation size accounting for each malloc-based heap and reject over budget requests. --- include/copperplate/heapobj.h| 55 - lib/copperplate/heapobj-malloc.c | 127 +- 2 files changed, 139 insertions(+), 43 deletions(-) diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h index 2dad005..39b6b06 100644 --- a/include/copperplate/heapobj.h +++ b/include/copperplate/heapobj.h @@ -140,22 +140,10 @@ static inline char *pvstrdup(const char *ptr) #include -static inline -void pvheapobj_destroy(struct heapobj *hobj) -{ -} - -static inline -int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) -{ - return 0; -} - -static inline -void *pvheapobj_alloc(struct heapobj *hobj, size_t size) +static inline void *pvmalloc(size_t size) { /* -* XXX: We don't want debug _nrt assertions to trigger when +* NOTE: We don't want debug _nrt assertions to trigger when * running over Cobalt if the user picked this allocator, so * we make sure to call the glibc directly, not the Cobalt * wrappers. @@ -163,44 +151,27 @@ void *pvheapobj_alloc(struct heapobj *hobj, size_t size) return __STD(malloc(size)); } -static inline -void pvheapobj_free(struct heapobj *hobj, void *ptr) +static inline void pvfree(void *ptr) { __STD(free(ptr)); } -static inline -size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) +static inline char *pvstrdup(const char *ptr) { - /* -* We will likely get hard validation here, i.e. crash or -* abort if the pointer is wrong. TLSF is a bit smarter, and -* pshared definitely does the right thing. -*/ - return malloc_usable_size(ptr); + return strdup(ptr); } -static inline -size_t pvheapobj_inquire(struct heapobj *hobj) -{ - struct mallinfo m = mallinfo(); - return m.uordblks; -} +void pvheapobj_destroy(struct heapobj *hobj); -static inline void *pvmalloc(size_t size) -{ - return __STD(malloc(size)); -} +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem); -static inline void pvfree(void *ptr) -{ - __STD(free(ptr)); -} +void *pvheapobj_alloc(struct heapobj *hobj, size_t size); -static inline char *pvstrdup(const char *ptr) -{ - return strdup(ptr); -} +void pvheapobj_free(struct heapobj *hobj, void *ptr); + +size_t pvheapobj_inquire(struct heapobj *hobj); + +size_t pvheapobj_validate(struct heapobj *hobj, void *ptr); #endif /* !CONFIG_XENO_TLSF */ diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 96814b9..14d624e 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -20,19 +20,51 @@ #include #include #include +#include +#include +#include "copperplate/lock.h" #include "copperplate/heapobj.h" #include "copperplate/debug.h" +#define MALLOC_MAGIC 0xabbfcddc + +struct pool_header { + pthread_mutex_t lock; + size_t used; +}; + +struct block_header { + unsigned int magic; + size_t size; +}; + int __heapobj_init_private(struct heapobj *hobj, const char *name, size_t size, void *mem) { + pthread_mutexattr_t mattr; + struct pool_header *ph; + /* * There is no local pool when working with malloc, we just * use the global process arena. This should not be an issue * since this mode is aimed at debugging, particularly to be * used along with Valgrind. +* +* However, we maintain a control header to track the amount +* of memory currently consumed in each heap. */ - hobj->pool = mem; /* Never used. */ + ph = malloc(sizeof(*ph)); + if (ph == NULL) + return __bt(-ENOMEM); + + __RT(pthread_mutexattr_init(&mattr)); + __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT)); + __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE)); + __RT(pthread_mutex_init(&ph->lock, &mattr)); + __RT(pthread_mutexattr_destroy(&mattr)); + ph->used = 0; + + hobj->pool = ph; hobj->size = size; if (name) snprintf(hobj->name, sizeof(hobj->name), "%s", name); @@ -48,6 +80,99 @@ int heapobj_init_array_private(struct heapobj *hobj, const char *name, return __bt(__heapobj_init_private(hobj, name, size * elems, NULL)); } +void pvheapobj_destroy(st
[Xenomai-git] Philippe Gerum : copperplate/heapobj-malloc: enforce hard limit on pool size
Module: xenomai-forge Branch: next Commit: 7cf44bdf70b963d41d39fa419f16b787267b777d URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=7cf44bdf70b963d41d39fa419f16b787267b777d Author: Philippe Gerum Date: Thu May 9 12:22:05 2013 +0200 copperplate/heapobj-malloc: enforce hard limit on pool size Applications may rely on hard limits when creating memory pools, to detect over-consumption. Since the global malloc heap is virtually illimited, we do allocation size accounting for each malloc-based heap and reject over budget requests. --- include/copperplate/heapobj.h| 52 ++-- lib/copperplate/heapobj-malloc.c | 98 +- 2 files changed, 113 insertions(+), 37 deletions(-) diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h index 2dad005..6eb874f 100644 --- a/include/copperplate/heapobj.h +++ b/include/copperplate/heapobj.h @@ -141,35 +141,6 @@ static inline char *pvstrdup(const char *ptr) #include static inline -void pvheapobj_destroy(struct heapobj *hobj) -{ -} - -static inline -int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) -{ - return 0; -} - -static inline -void *pvheapobj_alloc(struct heapobj *hobj, size_t size) -{ - /* -* XXX: We don't want debug _nrt assertions to trigger when -* running over Cobalt if the user picked this allocator, so -* we make sure to call the glibc directly, not the Cobalt -* wrappers. -*/ - return __STD(malloc(size)); -} - -static inline -void pvheapobj_free(struct heapobj *hobj, void *ptr) -{ - __STD(free(ptr)); -} - -static inline size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) { /* @@ -180,15 +151,14 @@ size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) return malloc_usable_size(ptr); } -static inline -size_t pvheapobj_inquire(struct heapobj *hobj) -{ - struct mallinfo m = mallinfo(); - return m.uordblks; -} - static inline void *pvmalloc(size_t size) { + /* +* NOTE: We don't want debug _nrt assertions to trigger when +* running over Cobalt if the user picked this allocator, so +* we make sure to call the glibc directly, not the Cobalt +* wrappers. +*/ return __STD(malloc(size)); } @@ -202,6 +172,16 @@ static inline char *pvstrdup(const char *ptr) return strdup(ptr); } +void pvheapobj_destroy(struct heapobj *hobj); + +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem); + +void *pvheapobj_alloc(struct heapobj *hobj, size_t size); + +void pvheapobj_free(struct heapobj *hobj, void *ptr); + +size_t pvheapobj_inquire(struct heapobj *hobj); + #endif /* !CONFIG_XENO_TLSF */ #ifdef CONFIG_XENO_PSHARED diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 96814b9..2e4e399 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -20,19 +20,44 @@ #include #include #include +#include +#include +#include "copperplate/lock.h" #include "copperplate/heapobj.h" #include "copperplate/debug.h" +struct malloc_heap { + pthread_mutex_t lock; + size_t used; +}; + int __heapobj_init_private(struct heapobj *hobj, const char *name, size_t size, void *mem) { + pthread_mutexattr_t mattr; + struct malloc_heap *mh; + /* * There is no local pool when working with malloc, we just * use the global process arena. This should not be an issue * since this mode is aimed at debugging, particularly to be * used along with Valgrind. +* +* However, we maintain a control header to track the amount +* of memory currently consumed in each heap. */ - hobj->pool = mem; /* Never used. */ + mh = malloc(sizeof(*mh)); + if (mh == NULL) + return __bt(-ENOMEM); + + __RT(pthread_mutexattr_init(&mattr)); + __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT)); + __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE)); + __RT(pthread_mutex_init(&mh->lock, &mattr)); + __RT(pthread_mutexattr_destroy(&mattr)); + mh->used = 0; + + hobj->pool = mh; hobj->size = size; if (name) snprintf(hobj->name, sizeof(hobj->name), "%s", name); @@ -48,6 +73,77 @@ int heapobj_init_array_private(struct heapobj *hobj, const char *name, return __bt(__heapobj_init_private(hobj, name, size * elems, NULL)); } +void pvheapobj_destroy(struct heapobj *hobj) +{ + struct malloc_heap *mh = hobj->pool; + + __RT(pthread_mutex_destroy(&mh->lock)); + __STD(free(mh)); +} + +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) +{ + struct malloc_heap *mh = hobj->pool; + + write_lock_nocancel(&mh->lock); + hobj->size += size; + write_unlock(&
[Xenomai-git] Philippe Gerum : copperplate/heapobj-malloc: enforce hard limit on pool size
Module: xenomai-forge Branch: next Commit: 4f454cdadfaa6ed4b2e73bd474c3151fd2aef940 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=4f454cdadfaa6ed4b2e73bd474c3151fd2aef940 Author: Philippe Gerum Date: Thu May 9 12:22:05 2013 +0200 copperplate/heapobj-malloc: enforce hard limit on pool size Applications may rely on hard limits when creating memory pools, to detect over-consumption. Since the global malloc heap is virtually illimited, we do allocation size accounting for each malloc-based heap and reject over budget requests. --- include/copperplate/heapobj.h| 52 ++-- lib/copperplate/heapobj-malloc.c | 99 +- 2 files changed, 114 insertions(+), 37 deletions(-) diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h index 2dad005..6eb874f 100644 --- a/include/copperplate/heapobj.h +++ b/include/copperplate/heapobj.h @@ -141,35 +141,6 @@ static inline char *pvstrdup(const char *ptr) #include static inline -void pvheapobj_destroy(struct heapobj *hobj) -{ -} - -static inline -int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) -{ - return 0; -} - -static inline -void *pvheapobj_alloc(struct heapobj *hobj, size_t size) -{ - /* -* XXX: We don't want debug _nrt assertions to trigger when -* running over Cobalt if the user picked this allocator, so -* we make sure to call the glibc directly, not the Cobalt -* wrappers. -*/ - return __STD(malloc(size)); -} - -static inline -void pvheapobj_free(struct heapobj *hobj, void *ptr) -{ - __STD(free(ptr)); -} - -static inline size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) { /* @@ -180,15 +151,14 @@ size_t pvheapobj_validate(struct heapobj *hobj, void *ptr) return malloc_usable_size(ptr); } -static inline -size_t pvheapobj_inquire(struct heapobj *hobj) -{ - struct mallinfo m = mallinfo(); - return m.uordblks; -} - static inline void *pvmalloc(size_t size) { + /* +* NOTE: We don't want debug _nrt assertions to trigger when +* running over Cobalt if the user picked this allocator, so +* we make sure to call the glibc directly, not the Cobalt +* wrappers. +*/ return __STD(malloc(size)); } @@ -202,6 +172,16 @@ static inline char *pvstrdup(const char *ptr) return strdup(ptr); } +void pvheapobj_destroy(struct heapobj *hobj); + +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem); + +void *pvheapobj_alloc(struct heapobj *hobj, size_t size); + +void pvheapobj_free(struct heapobj *hobj, void *ptr); + +size_t pvheapobj_inquire(struct heapobj *hobj); + #endif /* !CONFIG_XENO_TLSF */ #ifdef CONFIG_XENO_PSHARED diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 96814b9..ec44f89 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -20,19 +20,44 @@ #include #include #include +#include +#include +#include "copperplate/lock.h" #include "copperplate/heapobj.h" #include "copperplate/debug.h" +struct malloc_heap { + pthread_mutex_t lock; + size_t used; +}; + int __heapobj_init_private(struct heapobj *hobj, const char *name, size_t size, void *mem) { + pthread_mutexattr_t mattr; + struct malloc_heap *mh; + /* * There is no local pool when working with malloc, we just * use the global process arena. This should not be an issue * since this mode is aimed at debugging, particularly to be * used along with Valgrind. +* +* However, we maintain a control header to track the amount +* of memory currently consumed in each heap. */ - hobj->pool = mem; /* Never used. */ + mh = malloc(sizeof(*mh)); + if (mh == NULL) + return __bt(-ENOMEM); + + __RT(pthread_mutexattr_init(&mattr)); + __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT)); + __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE)); + __RT(pthread_mutex_init(&mh->lock, &mattr)); + __RT(pthread_mutexattr_destroy(&mattr)); + mh->used = 0; + + hobj->pool = mh; hobj->size = size; if (name) snprintf(hobj->name, sizeof(hobj->name), "%s", name); @@ -48,6 +73,78 @@ int heapobj_init_array_private(struct heapobj *hobj, const char *name, return __bt(__heapobj_init_private(hobj, name, size * elems, NULL)); } +void pvheapobj_destroy(struct heapobj *hobj) +{ + struct malloc_heap *mh = hobj->pool; + + __RT(pthread_mutex_destroy(&mh->lock)); + __STD(free(mh)); +} + +int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem) +{ + struct malloc_heap *mh = hobj->pool; + + write_lock_nocancel(&mh->lock); + hobj->size += size; + write_unlock(&