static prop_bt *find_prop_bt(prop_bt *const bt, const char *name, uint8_t namelen, bool alloc_if_needed) { prop_bt* current = bt; while (true) { if (!current) { return NULL; } const int ret = cmp_prop_name(name, namelen, current->name, current->namelen); if (ret == 0) { return current; } if (ret < 0) { if (current->left) { current = reinterpret_cast<prop_bt*>(to_prop_obj(current->left)); } else { if (!alloc_if_needed) { return NULL; } // Note that there isn't a race condition here. "clients" never // reach this code-path since It's only the (single threaded) server // that allocates new nodes. Though "bt->left" is volatile, it can't // have changed since the last value was last read. uint32_t new_offset = 0; prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset); if (new_bt) { current->left = new_offset; } return new_bt; } } else { if (current->right) { current = reinterpret_cast<prop_bt*>(to_prop_obj(current->right)); } else { if (!alloc_if_needed) { return NULL; } uint32_t new_offset; prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset); if (new_bt) { current->right = new_offset; } return new_bt; } } } }
prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name, uint8_t namelen, bool alloc_if_needed) { prop_bt* current = bt; while (true) { if (!current) { return NULL; } const int ret = cmp_prop_name(name, namelen, current->name, current->namelen); if (ret == 0) { return current; } if (ret < 0) { uint_least32_t left_offset = atomic_load_explicit(¤t->left, memory_order_relaxed); if (left_offset != 0) { current = to_prop_bt(¤t->left); } else { if (!alloc_if_needed) { return NULL; } uint_least32_t new_offset; prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset); if (new_bt) { atomic_store_explicit(¤t->left, new_offset, memory_order_release); } return new_bt; } } else { uint_least32_t right_offset = atomic_load_explicit(¤t->right, memory_order_relaxed); if (right_offset != 0) { current = to_prop_bt(¤t->right); } else { if (!alloc_if_needed) { return NULL; } uint_least32_t new_offset; prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset); if (new_bt) { atomic_store_explicit(¤t->right, new_offset, memory_order_release); } return new_bt; } } } }