diff options
author | Richard Braun <rbraun@sceen.net> | 2017-01-26 23:17:52 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-01-26 23:17:52 +0100 |
commit | 29c9d176f0ac8854ec29dc1c586bd53ddc3d7553 (patch) | |
tree | f4799382a67be8d868ba28969c0d1ee13a2c2838 /kern/rdxtree.c | |
parent | 7f32abc5bb79a3aa920b9468d4c6f391c497b2ad (diff) |
kern/{llsync,rdxtree}: don't use llsync until it's ready
Diffstat (limited to 'kern/rdxtree.c')
-rw-r--r-- | kern/rdxtree.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/kern/rdxtree.c b/kern/rdxtree.c index 4bce0569..90676e04 100644 --- a/kern/rdxtree.c +++ b/kern/rdxtree.c @@ -160,12 +160,8 @@ rdxtree_node_create(struct rdxtree_node **nodep, unsigned short height) } static void -rdxtree_node_destroy(struct work *work) +rdxtree_node_destroy(struct rdxtree_node *node) { - struct rdxtree_node *node; - - node = structof(work, struct rdxtree_node, work); - /* See rdxtree_shrink() */ if (node->nr_entries != 0) { assert(node->nr_entries == 1); @@ -179,11 +175,30 @@ rdxtree_node_destroy(struct work *work) } static void +rdxtree_node_destroy_deferred(struct work *work) +{ + struct rdxtree_node *node; + + node = structof(work, struct rdxtree_node, work); + rdxtree_node_destroy(node); +} + +static void rdxtree_node_schedule_destruction(struct rdxtree_node *node) { assert(node->parent == NULL); - work_init(&node->work, rdxtree_node_destroy); + work_init(&node->work, rdxtree_node_destroy_deferred); + + /* + * This assumes that llsync is initialized before scheduling is started + * so that there can be no read-side reference when destroying the node. + */ + if (!llsync_ready()) { + rdxtree_node_destroy(node); + return; + } + llsync_defer(&node->work); } |