Module: xenomai-3
Branch: master
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

Reply via email to