diff options
author | Maria Matejka <mq@ucw.cz> | 2022-08-03 17:37:16 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-08-03 17:37:16 +0200 |
commit | 70e01358a08b59ba70fc62affa31d9d2ebd96d07 (patch) | |
tree | 66b9ed89b37d798895c0dff40a2b7b70bbd6ca05 /lib/route.h | |
parent | 5a96b9b12496082b9d6165f51597403546ed617d (diff) | |
parent | 038fcf1c8b7716415235384de5dc47d07dc45b85 (diff) |
Merge commit '038fcf1c' into thread-next
It was necessary to update the code to match removal of rta, as well as
existence of cached nested attribute lists.
Diffstat (limited to 'lib/route.h')
-rw-r--r-- | lib/route.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/route.h b/lib/route.h index 97e2e053..f5456396 100644 --- a/lib/route.h +++ b/lib/route.h @@ -257,7 +257,7 @@ typedef struct ea_list { struct ea_storage { struct ea_storage *next_hash; /* Next in hash chain */ struct ea_storage **pprev_hash; /* Previous in hash chain */ - u32 uc; /* Use count */ + _Atomic u32 uc; /* Use count */ u32 hash_key; /* List hash */ ea_list l[0]; /* The list itself */ }; @@ -526,12 +526,15 @@ static inline struct ea_storage *ea_get_storage(ea_list *r) return SKIP_BACK(struct ea_storage, l[0], r); } -static inline ea_list *ea_clone(ea_list *r) { ea_get_storage(r)->uc++; return r; } +static inline ea_list *ea_clone(ea_list *r) { + ASSERT_DIE(0 < atomic_fetch_add_explicit(&ea_get_storage(r)->uc, 1, memory_order_acq_rel)); + return r; +} void ea__free(struct ea_storage *r); static inline void ea_free(ea_list *l) { if (!l) return; struct ea_storage *r = ea_get_storage(l); - if (!--r->uc) ea__free(r); + if (1 == atomic_fetch_sub_explicit(&r->uc, 1, memory_order_acq_rel)) ea__free(r); } void ea_dump(ea_list *); |