about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <mwrap-perl@80x24.org>2022-12-19 11:19:21 +0000
committerEric Wong <mwrap-perl@80x24.org>2022-12-19 21:56:37 +0000
commita8f2885140239ccfa1294b1e9d6f4d5c92616568 (patch)
tree9e86bcab85f2e2dbe3efbcf4174103a35067f0ee
parentc904bb39b348e702c3c9c371621053eb00db3d0d (diff)
downloadmwrap-a8f2885140239ccfa1294b1e9d6f4d5c92616568.tar.gz
We can actually handle all RCU locking/unlocking inside
alloc_insert_rcu to simplify callers.
-rw-r--r--mwrap_core.h60
1 files changed, 22 insertions, 38 deletions
diff --git a/mwrap_core.h b/mwrap_core.h
index 3161243..b014f5d 100644
--- a/mwrap_core.h
+++ b/mwrap_core.h
@@ -319,11 +319,6 @@ again:
         return l;
 }
 
-static void update_stats_rcu_unlock(const struct src_loc *l)
-{
-        if (caa_likely(l)) rcu_read_unlock();
-}
-
 static const COP *mwp_curcop(void)
 {
 #if MWRAP_PERL
@@ -506,17 +501,20 @@ void free(void *p)
 }
 
 static void
-alloc_insert_rcu(struct src_loc *l, struct alloc_hdr *h, size_t size,
-                void *real, size_t generation)
+alloc_insert_rcu(struct src_loc *sl, struct alloc_hdr *h, size_t size,
+                void *real)
 {
         h->size = size;
         h->real = real;
+        size_t gen = 0;
+        struct src_loc *l = update_stats_rcu_lock(&gen, size, sl);
         h->as.live.loc = l;
-        h->as.live.gen = generation;
+        h->as.live.gen = gen;
         if (l) {
                 pthread_mutex_t *mtx = src_loc_mutex_lock(l);
                 cds_list_add_rcu(&h->anode, &l->allocs);
                 CHECK(int, 0, pthread_mutex_unlock(mtx));
+                rcu_read_unlock();
         }
 }
 
@@ -564,10 +562,7 @@ mwrap_memalign(void **pp, size_t alignment, size_t size, struct src_loc *sl)
                 if (!ptr_is_aligned(p, alignment))
                         p = ptr_align(p, alignment);
                 struct alloc_hdr *h = ptr2hdr(p);
-                size_t gen = 0;
-                struct src_loc *l = update_stats_rcu_lock(&gen, size, sl);
-                alloc_insert_rcu(l, h, size, real, gen);
-                update_stats_rcu_unlock(l);
+                alloc_insert_rcu(sl, h, size, real);
                 *pp = p;
         }
 
@@ -649,15 +644,11 @@ void *malloc(size_t size)
 
         void *p = real_malloc(asize);
         if (p) {
-                size_t gen = 0;
                 SRC_LOC_BT(bt);
                 struct alloc_hdr *h = p;
-                struct src_loc *l = update_stats_rcu_lock(&gen, size, &bt.sl);
-                alloc_insert_rcu(l, h, size, h, gen);
-                update_stats_rcu_unlock(l);
-                p = hdr2ptr(h);
+                alloc_insert_rcu(&bt.sl, h, size, h);
+                return hdr2ptr(h);
         }
-        if (p) return p;
 enomem:
         errno = ENOMEM;
         return 0;
@@ -673,12 +664,9 @@ void *calloc(size_t nmemb, size_t size)
                 goto enomem;
         void *p = real_malloc(asize);
         if (p) {
-                size_t gen = 0;
                 struct alloc_hdr *h = p;
                 SRC_LOC_BT(bt);
-                struct src_loc *l = update_stats_rcu_lock(&gen, size, &bt.sl);
-                alloc_insert_rcu(l, h, size, h, gen);
-                update_stats_rcu_unlock(l);
+                alloc_insert_rcu(&bt.sl, h, size, h);
                 return memset(hdr2ptr(h), 0, size);
         }
 enomem:
@@ -694,28 +682,24 @@ void *realloc(void *ptr, size_t size)
                 free(ptr);
                 return 0;
         }
-        if (__builtin_add_overflow(size, sizeof(struct alloc_hdr), &asize)) {
-                errno = ENOMEM;
-                return 0;
-        }
+        if (__builtin_add_overflow(size, sizeof(struct alloc_hdr), &asize))
+                goto enomem;
         void *p = real_malloc(asize);
         if (p) {
-                size_t gen = 0;
                 struct alloc_hdr *h = p;
                 SRC_LOC_BT(bt);
-                struct src_loc *l = update_stats_rcu_lock(&gen, size, &bt.sl);
-                alloc_insert_rcu(l, h, size, h, gen);
-                update_stats_rcu_unlock(l);
+                alloc_insert_rcu(&bt.sl, h, size, h);
                 p = hdr2ptr(h);
+                if (ptr) {
+                        struct alloc_hdr *old = ptr2hdr(ptr);
+                        memcpy(p, ptr, old->size < size ? old->size : size);
+                        free(ptr);
+                }
+                return p;
         }
-
-        if (ptr && p) {
-                struct alloc_hdr *old = ptr2hdr(ptr);
-                memcpy(p, ptr, old->size < size ? old->size : size);
-                free(ptr);
-        }
-        if (caa_unlikely(!p)) errno = ENOMEM;
-        return p;
+enomem:
+        errno = ENOMEM;
+        return 0;
 }
 
 struct dump_arg {