Module: xenomai-3 Branch: next Commit: dc4ede78ce850aef4990602d90d4d72438db13f5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dc4ede78ce850aef4990602d90d4d72438db13f5
Author: Philippe Gerum <r...@xenomai.org> Date: Mon May 18 18:28:01 2015 +0200 copperplate/heapobj-malloc: fix locking Do not call malloc/free while potentially holding a RT mutex: Cobalt might send us a SIGDEBUG if we happen to switch to secondary mode there. In addition, malloc(3) is not a cancellation point, so there is no need for cleanup handlers. The caller should have entered a deferred cancellation section prior to calling us. --- lib/copperplate/heapobj-malloc.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c index 37d14f7..60894eb 100644 --- a/lib/copperplate/heapobj-malloc.c +++ b/lib/copperplate/heapobj-malloc.c @@ -110,29 +110,33 @@ void *pvheapobj_alloc(struct heapobj *hobj, size_t size) { struct pool_header *ph = hobj->pool; struct block_header *bh; - void *ptr = NULL; - push_cleanup_lock(&ph->lock); write_lock(&ph->lock); + ph->used += size; /* Enforce hard limit. */ - if (ph->used + size > hobj->size) - goto out; + if (ph->used > hobj->size) + goto fail; + + write_unlock(&ph->lock); + /* malloc(3) is not a cancellation point. */ ptr = __STD(malloc(size + sizeof(*bh))); - if (ptr == NULL) - goto out; + if (ptr == NULL) { + write_lock(&ph->lock); + goto fail; + } bh = ptr; bh->magic = MALLOC_MAGIC; bh->size = size; - ph->used += size; - ptr = bh + 1; -out: + + return bh + 1; +fail: + ph->used -= size; write_unlock(&ph->lock); - pop_cleanup_lock(&ph->lock); - return ptr; + return NULL; } void pvheapobj_free(struct heapobj *hobj, void *ptr) @@ -140,13 +144,11 @@ void pvheapobj_free(struct heapobj *hobj, void *ptr) struct block_header *bh = ptr - sizeof(*bh); struct pool_header *ph = hobj->pool; - push_cleanup_lock(&ph->lock); - write_lock(&ph->lock); assert(hobj->size >= bh->size); - ph->used -= bh->size; __STD(free(bh)); + write_lock(&ph->lock); + ph->used -= bh->size; write_unlock(&ph->lock); - pop_cleanup_lock(&ph->lock); } size_t pvheapobj_inquire(struct heapobj *hobj) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git