]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Fix atomic reference counter TODO
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 16 May 2019 18:40:45 +0000 (13:40 -0500)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 16 May 2019 18:40:45 +0000 (13:40 -0500)
I couldn't find a viable way to multithreadedly manage deltas
without reference counters, and sig_atomic_t doesn't look portable
to me. So I decided to use C11 atomic types.

Upgrades the language standard from gnu99 to gnu11.

src/Makefile.am
src/abbreviations.txt
src/rtr/db/delta.c
src/rtr/db/delta.h
src/rtr/db/roa_table.c
src/rtr/db/vrps.c

index a41a1bfacc1474bfd1efc80cd35049826fd89c9b..40a8d9b141be95d14571bca6d5505384b59b6501 100644 (file)
@@ -96,7 +96,7 @@ fort_SOURCES += slurm/slurm_parser.c slurm/slurm_parser.h
 fort_CFLAGS  = -Wall
 # Feel free to temporarily remove this one if you're not using gcc 7.3.0.
 #fort_CFLAGS += $(GCC_WARNS)
-fort_CFLAGS += -std=gnu99 -O0 -g $(CFLAGS_DEBUG)
+fort_CFLAGS += -std=gnu11 -O0 -g $(CFLAGS_DEBUG)
 fort_LDFLAGS = $(LDFLAGS_DEBUG)
 fort_LDADD   = ${JANSSON_LIBS}
 
index 92263bc129285e462bde85981e078f48597fe7c2..6cab74cd7f54d12c3776e38d8b29c874b473990c 100644 (file)
@@ -20,6 +20,8 @@ msg: message
 pdu: Protocol Data Unit (RFC 6810)
 pr: print
 ptr: pointer
+refget: reference get (+1 to reference counter)
+refput: reference put (-1 to reference counter)
 str: string
 tmp: temporal
 uint: unsigned int
index 3bcc1c5dca677608422847a0e4d7be80c5e715bf..7ffe07901a5117d89cde4cc9cebd2c264e248d96 100644 (file)
@@ -1,5 +1,6 @@
 #include "rtr/db/delta.h"
 
+#include <stdatomic.h>
 #include "data_structure/array_list.h"
 
 struct delta_v4 {
@@ -27,8 +28,7 @@ struct deltas {
                struct deltas_v6 removes;
        } v6;
 
-       /* TODO (now) atomic */
-       unsigned int references;
+       atomic_uint references;
 };
 
 int
@@ -44,23 +44,26 @@ deltas_create(struct deltas **_result)
        deltas_v4_init(&result->v4.removes);
        deltas_v6_init(&result->v6.adds);
        deltas_v6_init(&result->v6.removes);
-       result->references = 1;
+       atomic_init(&result->references, 1);
 
        *_result = result;
        return 0;
 }
 
 void
-deltas_get(struct deltas *deltas)
+deltas_refget(struct deltas *deltas)
 {
-       deltas->references++;
+       atomic_fetch_add(&deltas->references, 1);
 }
 
 void
-deltas_put(struct deltas *deltas)
+deltas_refput(struct deltas *deltas)
 {
-       deltas->references--;
-       if (deltas->references == 0) {
+       /*
+        * Reminder: atomic_fetch_sub() returns the previous value, not the
+        * resulting one.
+        */
+       if (atomic_fetch_sub(&deltas->references, 1) == 1) {
                deltas_v4_cleanup(&deltas->v4.adds, NULL);
                deltas_v4_cleanup(&deltas->v4.removes, NULL);
                deltas_v6_cleanup(&deltas->v6.adds, NULL);
index 1d2a0701791f12a6a3468547f69927d41b865c7e..a3d66ae63fd4332b001bbee47ffa5bb581ab018b 100644 (file)
@@ -7,8 +7,8 @@
 struct deltas;
 
 int deltas_create(struct deltas **);
-void deltas_get(struct deltas *);
-void deltas_put(struct deltas *);
+void deltas_refget(struct deltas *);
+void deltas_refput(struct deltas *);
 
 int deltas_add_roa_v4(struct deltas *, uint32_t, struct v4_address *, int);
 int deltas_add_roa_v6(struct deltas *, uint32_t, struct v6_address *, int);
index bf4c012dcd30260f235350b8a42f3f7580396ddd..5e7df96b08ed91128b2bda7869d6791930e6bbf9 100644 (file)
@@ -269,6 +269,6 @@ compute_deltas(struct roa_table *old, struct roa_table *new,
        return 0;
 
 fail:
-       deltas_put(deltas);
+       deltas_refput(deltas);
        return error;
 }
index 7a290b627faa663ba95382bd264ab752cf1d4843..b32296c2e04092bed9f316f6af6a3d18a0afe3f1 100644 (file)
@@ -48,7 +48,7 @@ static pthread_rwlock_t lock;
 void
 deltagroup_cleanup(struct delta_group *group)
 {
-       deltas_put(group->deltas);
+       deltas_refput(group->deltas);
 }
 
 int
@@ -173,7 +173,7 @@ resize_deltas_db(struct deltas_db *db, struct delta_group *start)
        memcpy(tmp, start, db->len * sizeof(struct delta_group));
        /* Release memory allocated */
        for (ptr = db->array; ptr < start; ptr++)
-               deltas_put(ptr->deltas);
+               deltas_refput(ptr->deltas);
        free(db->array);
        db->array = tmp;
 }
@@ -187,12 +187,12 @@ vrps_purge(void)
 
        min_serial = clients_get_min_serial();
 
-       /** Assume is ordered by serial, so get the new initial pointer */
+       /* Assume is ordered by serial, so get the new initial pointer */
        ARRAYLIST_FOREACH(&state.deltas, group, i)
                if (group->serial >= min_serial)
                        break;
 
-       /** Is the first element or reached end, nothing to purge */
+       /* Is the first element or reached end, nothing to purge */
        if (group == state.deltas.array ||
            (group - state.deltas.array) == state.deltas.len)
                return;
@@ -251,7 +251,7 @@ vrps_update(bool *changed)
                 */
                old_base = state.base;
 
-               /** Remove unnecessary deltas */
+               /* Remove unnecessary deltas */
                vrps_purge();
 
        } else {
@@ -287,7 +287,7 @@ vrps_update(bool *changed)
        return 0;
 
 revert_deltas:
-       deltas_put(deltas);
+       deltas_refput(deltas);
 revert_base:
        roa_table_destroy(new_base);
        return error;
@@ -369,7 +369,7 @@ vrps_get_deltas_from(serial_t from, serial_t *to, struct deltas_db *result)
                        return error;
                }
 
-               deltas_get(group->deltas);
+               deltas_refget(group->deltas);
                *to = group->serial;
        }