* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifndef __UK_STORE_H__
#define __UK_STORE_H__
#if CONFIG_LIBUKSTORE
#include <string.h>
+#include <uk/alloc.h>
#include <uk/config.h>
#include <uk/assert.h>
-#include <uk/list.h>
#include <uk/arch/atomic.h>
-#include <uk/alloc.h>
#include <uk/libid.h>
#endif /* CONFIG_LIBUKSTORE */
+#include <uk/arch/limits.h>
#include <uk/arch/types.h>
#include <uk/essentials.h>
+#include <uk/list.h>
#ifdef __cplusplus
extern "C" {
.id = eid, \
.name = STRINGIFY(entry), \
.type = (UK_STORE_ENTRY_TYPE(e_type)), \
- .get.e_type = (e_get), \
- .set.e_type = (e_set), \
+ .get.e_type = (e_get), \
+ .set.e_type = (e_set), \
.flags = UK_STORE_ENTRY_FLAG_STATIC \
}
_UK_STORE_STATIC_ENTRY(id, entry, STRINGIFY(__LIBNAME__), \
e_type, e_get, e_set)
-#else /* !CONFIG_LIBUKSTORE */
+#else /* CONFIG_LIBUKSTORE */
/* Library-specific information generated at compile-time */
#include <uk/bits/store_libs.h>
+struct uk_store_object {
+ /* List for the dynamic objects only */
+ struct uk_list_head object_head;
+
+ /* List for the entries in the object */
+ struct uk_list_head entry_head;
+
+ /* Allocator to be used in allocations */
+ struct uk_alloc *a;
+
+ /* Parent library id */
+ __u16 libid;
+
+ /* Object unique id */
+ __u64 id;
+
+ /* The object name */
+ char *name;
+
+ /* The object's refcount */
+ __atomic refcount;
+
+ /* User data */
+ void *cookie;
+} __align8;
+
/**
- * Checks if an entry is static
- *
- * @param entry the entry to check
- * @return the condition result
+ * Payload to pass to uk_store events.
*/
-#define UK_STORE_ENTRY_ISSTATIC(entry) \
- ((entry)->flags & UK_STORE_ENTRY_FLAG_STATIC)
-
+struct uk_store_event_data {
+ __u16 library_id;
+ __u64 object_id;
+};
/* Do not call directly */
#define __UK_STORE_STATIC_ENTRY(eid, entry, lib_str, e_type, e_get, e_set)\
static const struct uk_store_entry \
.id = eid, \
.name = STRINGIFY(entry), \
.type = (UK_STORE_ENTRY_TYPE(e_type)), \
- .get.e_type = (e_get), \
- .set.e_type = (e_set), \
+ .get.e_type = (e_get), \
+ .set.e_type = (e_set), \
.flags = UK_STORE_ENTRY_FLAG_STATIC \
}
#define _UK_STORE_STATIC_ENTRY(id, entry, lib_str, e_type, e_get, e_set)\
__UK_STORE_STATIC_ENTRY(id, entry, lib_str, e_type, e_get, e_set)
+
+/**
+ * Helper to create entry array elements for uk_store_create_object()
+ *
+ * @_id entry id
+ * @_name entry name (without quotes)
+ * @_type entry type, e.g s8, u16, charp
+ * @get getter function
+ * @set setter function
+ */
+#define UK_STORE_ENTRY(_id, _name, _type, _get, _set) \
+( \
+ &(struct uk_store_entry) { \
+ .id = _id, \
+ .name = STRINGIFY(_name), \
+ .type = UK_STORE_ENTRY_TYPE(_type), \
+ .get._type = _get, \
+ .set._type = _set, \
+ } \
+)
+
/**
* Adds an entry to the entry section of a library.
*
_UK_STORE_STATIC_ENTRY(id, entry, STRINGIFY(__LIBNAME__), \
e_type, e_get, e_set)
-const struct uk_store_entry *
-_uk_store_get_static_entry(__u16 library_id, __u64 entry_id);
-
/**
- * Searches for an entry in an object in a library. Increases the refcount.
+ * Creates an object
+ *
+ * Allocates memory and initializes a new uk_store object.
*
- * @param library_id the id of the library to search in
- * @param object_id the id of the object to search (NULL for static entries)
- * @param entry_id the id of the entry to search for
- * @return the found entry or NULL
+ * @param a allocator instance to allocate this object from
+ * @param id the id of the new object
+ * @param name the name of the new object
+ * @param entries NULL terminated array of struct uk_store_entry describing
+ * the entries of this object. These can be defined with the
+ * UK_STORE_ENTRY helper. You should define the superset of
+ * entries, including ones disabled by default. At runtime,
+ * disabled entries are indicated by the return code of
+ * get_value()
+ * @param cookie caller defined data. This is passed to the getter function
+ * @return pointer to the allocated object, errptr otherwise
*/
-static inline const struct uk_store_entry *
-uk_store_get_entry(__u16 library_id, __u64 object_id __unused,
- __u64 entry_id)
-{
- return _uk_store_get_static_entry(library_id, entry_id);
-}
+struct uk_store_object *
+uk_store_obj_alloc(struct uk_alloc *a, __u64 id, const char *name,
+ const struct uk_store_entry *entries[], void *cookie);
/**
- * Decreases the refcount. When it reaches 0, the memory is freed
+ * Associates an object to the caller library
*
* Guard this with `#if CONFIG_LIBUKSTORE`
*
- * @param entry the entry to release
+ * @param object the object to add to the caller library
+ * @return 0 on success and < 0 on failure
*/
-#define uk_store_release_entry(entry) \
- _uk_store_release_entry((entry))
-
-void
-_uk_store_release_entry(const struct uk_store_entry *entry);
+#define uk_store_obj_add(obj) \
+ _uk_store_obj_add(uk_libid_self(), (obj))
int
-_uk_store_get_u8(const struct uk_store_entry *e, __u8 *out);
-int
-_uk_store_get_s8(const struct uk_store_entry *e, __s8 *out);
-int
-_uk_store_get_u16(const struct uk_store_entry *e, __u16 *out);
-int
-_uk_store_get_s16(const struct uk_store_entry *e, __s16 *out);
-int
-_uk_store_get_u32(const struct uk_store_entry *e, __u32 *out);
-int
-_uk_store_get_s32(const struct uk_store_entry *e, __s32 *out);
-int
-_uk_store_get_u64(const struct uk_store_entry *e, __u64 *out);
-int
-_uk_store_get_s64(const struct uk_store_entry *e, __s64 *out);
-int
-_uk_store_get_uptr(const struct uk_store_entry *e, __uptr *out);
-int
-_uk_store_get_charp(const struct uk_store_entry *e, char **out);
+_uk_store_obj_add(__u16 library_id, struct uk_store_object *object);
+
+/**
+ * Acquires an object
+ *
+ * Increments the object's refcount and returns the object.
+ * Evern call must be paired with a call to uk_store_release_object()
+ * to decrement the refcount.
+ *
+ * @param library_id owner library id as returned by uklibid
+ * @param object_id object id
+ * @return pointer to object
+ */
+struct uk_store_object *
+uk_store_obj_acquire(__u16 library_id, __u64 object_id);
+
+/**
+ * Releases an object
+ *
+ * Decrements the object's refcount.
+ *
+ * @param object object to release
+ */
+void uk_store_obj_release(struct uk_store_object *object);
+
+/**
+ * Looks up a static entry of a library.
+ *
+ * @param libid owner library
+ * @param entry_id the id of the entry to look up
+ * @return the matched entry or NULL
+ */
+const struct uk_store_entry *
+uk_store_static_entry_get(__u16 library_id, __u64 entry_id);
+
+/**
+ * Looks up an entry in an object of a library.
+ *
+ * @param object target object
+ * @param entry_id the id of the entry to look up
+ * @return the matched entry or NULL
+ */
+const struct uk_store_entry *
+uk_store_obj_entry_get(struct uk_store_object *object_id, __u64 entry_id);
/**
* Calls the getter to get it's value.
#define uk_store_get_value(entry, outtype, out) \
_uk_store_get_ ## outtype((entry), (out))
-/**
- * Calls the ncharp getter to get it's value.
- * The caller must provide a buffer with enough space to store the result.
- * The max length of the result is given by maxlen.
- *
- * @param e the entry to call the getter from
- * @param out space to store the result of the call
- * @param maxlen the maximum length of the result
- * @return 0 or error on fail
- */
-int
-uk_store_get_ncharp(const struct uk_store_entry *e, char *out, __sz maxlen);
-
-int
-_uk_store_set_u8(const struct uk_store_entry *e, __u8 val);
-int
-_uk_store_set_s8(const struct uk_store_entry *e, __s8 val);
-int
-_uk_store_set_u16(const struct uk_store_entry *e, __u16 val);
-int
-_uk_store_set_s16(const struct uk_store_entry *e, __s16 val);
-int
-_uk_store_set_u32(const struct uk_store_entry *e, __u32 val);
-int
-_uk_store_set_s32(const struct uk_store_entry *e, __s32 val);
-int
-_uk_store_set_u64(const struct uk_store_entry *e, __u64 val);
-int
-_uk_store_set_s64(const struct uk_store_entry *e, __s64 val);
-int
-_uk_store_set_uptr(const struct uk_store_entry *e, __uptr val);
-int
-_uk_store_set_charp(const struct uk_store_entry *e, const char *val);
+int _uk_store_get_u8(const struct uk_store_entry *e, __u8 *out);
+int _uk_store_get_s8(const struct uk_store_entry *e, __s8 *out);
+int _uk_store_get_u16(const struct uk_store_entry *e, __u16 *out);
+int _uk_store_get_s16(const struct uk_store_entry *e, __s16 *out);
+int _uk_store_get_u32(const struct uk_store_entry *e, __u32 *out);
+int _uk_store_get_s32(const struct uk_store_entry *e, __s32 *out);
+int _uk_store_get_u64(const struct uk_store_entry *e, __u64 *out);
+int _uk_store_get_s64(const struct uk_store_entry *e, __s64 *out);
+int _uk_store_get_uptr(const struct uk_store_entry *e, __uptr *out);
+int _uk_store_get_charp(const struct uk_store_entry *e, char **out);
+int _uk_store_get_ncharp(const struct uk_store_entry *e, char *out, __sz maxlen);
/**
* Calls the setter to set a new value.
#define uk_store_set_value(entry, intype, in) \
_uk_store_set_ ## intype((entry), (in))
+int _uk_store_set_u8(const struct uk_store_entry *e, __u8 val);
+int _uk_store_set_s8(const struct uk_store_entry *e, __s8 val);
+int _uk_store_set_u16(const struct uk_store_entry *e, __u16 val);
+int _uk_store_set_s16(const struct uk_store_entry *e, __s16 val);
+int _uk_store_set_u32(const struct uk_store_entry *e, __u32 val);
+int _uk_store_set_s32(const struct uk_store_entry *e, __s32 val);
+int _uk_store_set_u64(const struct uk_store_entry *e, __u64 val);
+int _uk_store_set_s64(const struct uk_store_entry *e, __s64 val);
+int _uk_store_set_uptr(const struct uk_store_entry *e, __uptr val);
+int _uk_store_set_charp(const struct uk_store_entry *e, const char *val);
+
#endif /* CONFIG_LIBUKSTORE */
#ifdef __cplusplus
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <uk/arch/limits.h>
#include <uk/arch/types.h>
+#include <uk/errptr.h>
+#include <uk/event.h>
+#include <uk/refcount.h>
+#include <uk/spinlock.h>
#include <uk/store.h>
#define _U8_STRLEN (3 + 1) /* 3 digits plus terminating '\0' */
#define _S64_STRLEN (1 + _U64_STRLEN)
#define _UPTR_STRLEN (2 + 16 + 1) /* 64bit in hex with leading `0x` prefix */
+#define UK_STORE_ENTRY_ISSTATIC(entry) \
+ ((entry)->flags & UK_STORE_ENTRY_FLAG_STATIC)
+
+#define OBJECT_ENTRY(e) \
+ (__containerof(e, struct uk_store_object_entry, entry))
+
+#define OBJECT(e) \
+ (OBJECT_ENTRY(e)->object)
+
+struct uk_store_object_entry {
+ struct uk_store_entry entry;
+ struct uk_store_object *object;
+ struct uk_list_head list_head;
+} __align8;
+
+/* The starting point of all dynamic objects for each library */
+static struct uk_list_head dynamic_heads[__UKLIBID_COUNT__] = { NULL, };
+static __spinlock dynamic_heads_lock = UK_SPINLOCK_INITIALIZER();
+
#include <uk/bits/store_array.h>
-/**
- * Releases an entry (decreases the refcount and sets the reference to NULL)
- * If the refcount is 0 (it was also released by the creator), it is removed
- * from the list and memory is freed
- *
- * @param p_entry pointer to the entry to release
- */
-void
-_uk_store_release_entry(const struct uk_store_entry *p_entry)
+#define _UK_STORE_DYNAMIC_CREATE_TYPED(gen_type) \
+ const struct uk_store_entry * \
+ _uk_store_create_dynamic_entry_ ## gen_type( \
+ struct uk_store_object *object, \
+ __u64 entry_id, \
+ const char *name, \
+ uk_store_get_ ## gen_type ## _func_t get, \
+ uk_store_set_ ## gen_type ## _func_t set) \
+ { \
+ struct uk_store_object_entry *new_object_entry; \
+ \
+ UK_ASSERT(object || name || object->a); \
+ \
+ new_object_entry = object->a->malloc(object->a, \
+ sizeof(*new_object_entry)); \
+ if (!new_object_entry) \
+ return ERR2PTR(ENOMEM); \
+ \
+ new_object_entry->entry.name = object->a->malloc( \
+ object->a, sizeof(*name) * (strlen(name) + 1)); \
+ if (!new_object_entry->entry.name) { \
+ object->a->free(object->a, new_object_entry); \
+ return ERR2PTR(ENOMEM); \
+ } \
+ strcpy(new_object_entry->entry.name, name); \
+ new_object_entry->entry.id = entry_id; \
+ new_object_entry->entry.type = \
+ UK_STORE_ENTRY_TYPE(gen_type); \
+ new_object_entry->entry.get.gen_type = get; \
+ new_object_entry->entry.set.gen_type = set; \
+ new_object_entry->entry.flags = 0; \
+ new_object_entry->object = object; \
+ \
+ uk_list_add(&(new_object_entry)->list_head, \
+ &(object)->entry_head); \
+ \
+ return &new_object_entry->entry; \
+ }
+
+/* Generate a function creator for each type */
+_UK_STORE_DYNAMIC_CREATE_TYPED(u8);
+_UK_STORE_DYNAMIC_CREATE_TYPED(s8);
+_UK_STORE_DYNAMIC_CREATE_TYPED(u16);
+_UK_STORE_DYNAMIC_CREATE_TYPED(s16);
+_UK_STORE_DYNAMIC_CREATE_TYPED(u32);
+_UK_STORE_DYNAMIC_CREATE_TYPED(s32);
+_UK_STORE_DYNAMIC_CREATE_TYPED(u64);
+_UK_STORE_DYNAMIC_CREATE_TYPED(s64);
+_UK_STORE_DYNAMIC_CREATE_TYPED(uptr);
+_UK_STORE_DYNAMIC_CREATE_TYPED(charp);
+
+/* Capital types used internally */
+#define S8 __do_not_expand__
+#define U8 __do_not_expand__
+#define S16 __do_not_expand__
+#define U16 __do_not_expand__
+#define S32 __do_not_expand__
+#define U32 __do_not_expand__
+#define S64 __do_not_expand__
+#define U64 __do_not_expand__
+#define PTR __do_not_expand__
+
+static void free_entry(const struct uk_store_entry *entry)
{
- if (UK_STORE_ENTRY_ISSTATIC(p_entry))
+ struct uk_alloc *a = OBJECT(entry)->a;
+
+ if (UK_STORE_ENTRY_ISSTATIC(entry))
return;
+
+ a->free(a, entry->name);
+ a->free(a, OBJECT_ENTRY(entry));
}
-const struct uk_store_entry *
-_uk_store_get_static_entry(__u16 libid, __u64 entry_id)
+static void release_entry(const struct uk_store_entry *entry)
+{
+ struct uk_store_object_entry *obj_entry;
+
+ if (UK_STORE_ENTRY_ISSTATIC(entry))
+ return;
+
+ obj_entry = OBJECT_ENTRY(entry);
+
+ uk_list_del(&obj_entry->list_head);
+
+ free_entry(entry);
+}
+
+static void free_object(struct uk_store_object *object)
+{
+ struct uk_store_object_entry *iter, *sec;
+ const struct uk_store_entry *entry;
+
+ object->a->free(object->a, object->name);
+
+ uk_list_for_each_entry_safe(iter, sec,
+ &object->entry_head, list_head) {
+ uk_list_del(&iter->list_head);
+ iter->object = NULL;
+ entry = &iter->entry;
+ release_entry(entry);
+ }
+}
+
+static struct uk_store_object *get_obj_by_id(unsigned int lib_id, __u64 obj_id)
+{
+ struct uk_store_object *obj = NULL;
+
+ uk_list_for_each_entry(obj, &dynamic_heads[lib_id], object_head)
+ if (obj->id == obj_id)
+ break;
+
+ return obj;
+}
+
+struct uk_store_object *
+uk_store_obj_alloc(struct uk_alloc *a, __u64 id, const char *name,
+ const struct uk_store_entry *entries[], void *cookie)
+{
+ struct uk_store_object *new_object;
+ const struct uk_store_entry *e;
+
+ UK_ASSERT(name);
+ UK_ASSERT(entries);
+
+ new_object = a->malloc(a, sizeof(*new_object));
+ if (!new_object)
+ return ERR2PTR(ENOMEM);
+
+ new_object->name = a->malloc(a, sizeof(*name) * (strlen(name) + 1));
+ if (!new_object->name) {
+ a->free(a, new_object);
+ return ERR2PTR(ENOMEM);
+ }
+
+ strcpy(new_object->name, name);
+
+ new_object->a = a;
+ new_object->id = id;
+ new_object->cookie = cookie;
+
+ uk_refcount_init(&new_object->refcount, 1);
+
+ UK_INIT_LIST_HEAD(&new_object->object_head);
+ UK_INIT_LIST_HEAD(&new_object->entry_head);
+
+ for (__sz i = 0; entries[i]; i++) {
+ e = entries[i];
+ switch (e->type) {
+ case UK_STORE_ENTRY_TYPE(s8):
+ _uk_store_create_dynamic_entry_s8(new_object,
+ e->id,
+ e->name,
+ e->get.s8,
+ e->set.s8);
+ break;
+ case UK_STORE_ENTRY_TYPE(u8):
+ _uk_store_create_dynamic_entry_u8(new_object,
+ e->id,
+ e->name,
+ e->get.u8,
+ e->set.u8);
+ break;
+ case UK_STORE_ENTRY_TYPE(s16):
+ _uk_store_create_dynamic_entry_s16(new_object,
+ e->id,
+ e->name,
+ e->get.s16,
+ e->set.s16);
+ break;
+ case UK_STORE_ENTRY_TYPE(u16):
+ _uk_store_create_dynamic_entry_u16(new_object,
+ e->id,
+ e->name,
+ e->get.u16,
+ e->set.u16);
+ break;
+ case UK_STORE_ENTRY_TYPE(s32):
+ _uk_store_create_dynamic_entry_s32(new_object,
+ e->id,
+ e->name,
+ e->get.s32,
+ e->set.s32);
+ break;
+ case UK_STORE_ENTRY_TYPE(u32):
+ _uk_store_create_dynamic_entry_u32(new_object,
+ e->id,
+ e->name,
+ e->get.u32,
+ e->set.u32);
+ break;
+ case UK_STORE_ENTRY_TYPE(s64):
+ _uk_store_create_dynamic_entry_s64(new_object,
+ e->id,
+ e->name,
+ e->get.s64,
+ e->set.s64);
+ break;
+ case UK_STORE_ENTRY_TYPE(u64):
+ _uk_store_create_dynamic_entry_u64(new_object,
+ e->id,
+ e->name,
+ e->get.u64,
+ e->set.u64);
+ break;
+
+ case UK_STORE_ENTRY_TYPE(uptr):
+ _uk_store_create_dynamic_entry_uptr(new_object,
+ e->id,
+ e->name,
+ e->get.uptr,
+ e->set.uptr);
+ break;
+ case UK_STORE_ENTRY_TYPE(charp):
+ _uk_store_create_dynamic_entry_charp(new_object,
+ e->id,
+ e->name,
+ e->get.charp,
+ e->set.charp);
+ break;
+ default:
+ return ERR2PTR(EINVAL);
+ };
+ }
+
+ return new_object;
+}
+
+int _uk_store_obj_add(__u16 library_id, struct uk_store_object *object)
+{
+ struct uk_store_event_data event_data;
+
+ UK_ASSERT(object);
+
+ if (!dynamic_heads[library_id].next)
+ UK_INIT_LIST_HEAD(&dynamic_heads[library_id]);
+
+ object->libid = library_id;
+ uk_list_add(&object->object_head, &dynamic_heads[library_id]);
+
+ /* Notify consumers */
+ event_data = (struct uk_store_event_data) {
+ .library_id = object->libid,
+ .object_id = object->id
+ };
+
+ uk_raise_event(UKSTORE_EVENT_CREATE_OBJECT, &event_data);
+
+ return 0;
+}
+
+struct uk_store_object *uk_store_obj_acquire(__u16 library_id, __u64 object_id)
+{
+ struct uk_store_object *obj = NULL;
+
+ if (!dynamic_heads[library_id].next)
+ return NULL;
+
+ uk_spin_lock(&dynamic_heads_lock);
+
+ obj = get_obj_by_id(library_id, object_id);
+ if (unlikely(!obj))
+ goto out;
+
+ uk_refcount_acquire(&obj->refcount);
+out:
+ uk_spin_unlock(&dynamic_heads_lock);
+
+ return obj;
+}
+
+void uk_store_obj_release(struct uk_store_object *object)
+{
+ int res;
+
+ UK_ASSERT(object);
+
+ if (!dynamic_heads[object->libid].next)
+ return;
+
+ uk_spin_lock(&dynamic_heads_lock);
+
+ res = uk_refcount_release_if_not_last(&object->refcount);
+ if (!res) {
+ uk_list_del(&(object->object_head));
+ free_object(object);
+ }
+ uk_spin_unlock(&dynamic_heads_lock);
+}
+
+const struct uk_store_entry *uk_store_static_entry_get(__u16 libid,
+ __u64 entry_id)
{
struct uk_store_entry *entry = static_entries[2 * libid];
struct uk_store_entry *stop = static_entries[2 * libid + 1];
return NULL;
}
-/* Capital types used internally */
-#define S8 __do_not_expand__
-#define U8 __do_not_expand__
-#define S16 __do_not_expand__
-#define U16 __do_not_expand__
-#define S32 __do_not_expand__
-#define U32 __do_not_expand__
-#define S64 __do_not_expand__
-#define U64 __do_not_expand__
-#define PTR __do_not_expand__
+const struct uk_store_entry *
+uk_store_obj_entry_get(struct uk_store_object *object, __u64 entry_id)
+{
+ struct uk_store_object_entry *res = NULL;
+
+ UK_ASSERT(object);
+
+ uk_list_for_each_entry(res, &object->entry_head, list_head)
+ if (res->entry.id == entry_id)
+ break;
+
+ if (res)
+ return &res->entry;
+
+ return NULL;
+}
/**
* Case defines used internally for shortening code
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTUS(e, s8, S8, val, u8, cookie);
SETCASE_UPCAST(e, u8, U8, val, u8, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_UPCAST(e, s8, S8, val, s8, cookie);
SETCASE_UPCASTSU(e, u8, U8, val, s8, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTUS(e, s8, S8, val, u16, cookie);
SETCASE_DOWNCASTUU(e, u8, U8, val, u16, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTSS(e, s8, S8, val, s16, cookie);
SETCASE_DOWNCASTSU(e, u8, U8, val, s16, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTUS(e, s8, S8, val, u32, cookie);
SETCASE_DOWNCASTUU(e, u8, U8, val, u32, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTSS(e, s8, S8, val, s32, cookie);
SETCASE_DOWNCASTSU(e, u8, U8, val, s32, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTUS(e, s8, S8, val, u64, cookie);
SETCASE_DOWNCASTUU(e, u8, U8, val, u64, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTSS(e, s8, S8, val, s64, cookie);
SETCASE_DOWNCASTSU(e, u8, U8, val, s64, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
SETCASE_DOWNCASTUS(e, s8, S8, val, uptr, cookie);
SETCASE_DOWNCASTUU(e, u8, U8, val, uptr, cookie);
if (unlikely(e->set.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
switch (e->type) {
case UK_STORE_ENTRY_TYPE(u8): {
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, U8, out, u8, cookie);
GETCASE_UPCASTSU(e, s8, U8, out, u8, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_DOWNCASTUS(e, u8, S8, out, s8, cookie);
GETCASE_UPCAST(e, s8, S8, out, s8, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, U16, out, u16, cookie);
GETCASE_UPCASTSU(e, s8, U16, out, u16, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, S16, out, s16, cookie);
GETCASE_UPCAST(e, s8, S16, out, s16, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, U32, out, u32, cookie);
GETCASE_UPCASTSU(e, s8, U32, out, u32, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, S32, out, s32, cookie);
GETCASE_UPCAST(e, s8, S32, out, s32, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, U64, out, u64, cookie);
GETCASE_UPCASTSU(e, s8, U64, out, u64, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, S64, out, s64, cookie);
GETCASE_UPCAST(e, s8, S64, out, s64, cookie);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
GETCASE_UPCAST(e, u8, PTR, out, uptr, cookie);
GETCASE_UPCASTSU(e, s8, PTR, out, uptr, cookie);
int ret;
char *str;
void *cookie = NULL;
+ struct uk_alloc *a = OBJECT(e)->a;
UK_ASSERT(e);
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
case UK_STORE_ENTRY_TYPE(u8): {
__u8 val;
- str = calloc(_U8_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_U8_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _U8_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(s8): {
__s8 val;
- str = calloc(_S8_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_S8_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _S8_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(u16): {
__u16 val;
- str = calloc(_U16_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_U16_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _U16_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(s16): {
__s16 val;
- str = calloc(_S16_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_S16_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _S16_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(u32): {
__u32 val;
- str = calloc(_U32_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_U32_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _U32_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(s32): {
__s32 val;
- str = calloc(_S32_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_S32_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _S32_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(u64): {
__u64 val;
- str = calloc(_U64_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_U64_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _U64_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(s64): {
__s64 val;
- str = calloc(_S64_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_S64_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _S64_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
case UK_STORE_ENTRY_TYPE(uptr): {
__uptr val;
- str = calloc(_UPTR_STRLEN, sizeof(char));
+ if (UK_STORE_ENTRY_ISSTATIC(e))
+ str = calloc(_UPTR_STRLEN, sizeof(char));
+ else
+ str = a->calloc(a, _UPTR_STRLEN, sizeof(char));
+
if (unlikely(!str))
return -ENOMEM;
int
-uk_store_get_ncharp(const struct uk_store_entry *e, char *out, __sz maxlen)
+_uk_store_get_ncharp(const struct uk_store_entry *e, char *out, __sz maxlen)
{
int ret;
void *cookie = NULL;
if (unlikely(e->get.u8 == NULL))
return -EIO;
+ if (!UK_STORE_ENTRY_ISSTATIC(e))
+ cookie = OBJECT(e)->cookie;
+
switch (e->type) {
case UK_STORE_ENTRY_TYPE(u8): {
__u8 val;
return -EINVAL;
}
}
+
+UK_EVENT(UKSTORE_EVENT_CREATE_OBJECT);
+UK_EVENT(UKSTORE_EVENT_RELEASE_OBJECT);