+ const struct bt_object *obj = ptr;
+
+ return obj->ref_count.count;
+}
+
+static inline
+void bt_object_release(void *ptr)
+{
+ struct bt_object *obj = ptr;
+
+ if (obj && obj->release && !bt_object_get_ref_count(obj)) {
+ obj->release(obj);
+ }
+}
+
+static inline
+void generic_release(struct bt_object *obj)
+{
+ if (obj->parent) {
+ /* The release function will be invoked by the parent. */
+ bt_put(obj->parent);
+ } else {
+ bt_object_release(obj);
+ }
+}
+
+static inline
+struct bt_object *bt_object_borrow_parent(void *ptr)
+{
+ struct bt_object *obj = ptr;
+
+ return obj ? obj->parent : NULL;
+}
+
+static inline
+struct bt_object *bt_object_get_parent(void *ptr)
+{
+ return bt_get(bt_object_borrow_parent(ptr));
+}
+
+static inline
+void bt_object_set_parent(void *child_ptr, void *parent)
+{
+ struct bt_object *child = child_ptr;
+
+ if (!child) {
+ return;
+ }
+
+ /*
+ * It is assumed that a "child" being "parented" is publicly reachable.
+ * Therefore, a reference to its parent must be taken. The reference
+ * to the parent will be released once the object's reference count
+ * falls to zero.
+ */
+ BT_PUT(child->parent);
+ child->parent = bt_get(parent);
+}
+
+static inline
+void bt_object_init(void *ptr, bt_object_release_func release)
+{
+ struct bt_object *obj = ptr;
+
+ obj->release = release;
+ obj->parent = NULL;
+ bt_ref_init(&obj->ref_count, generic_release);