diff --git a/kmpp/base/inc/kmpp_obj.h b/kmpp/base/inc/kmpp_obj.h index ba6ed3ba..f0d7f6eb 100644 --- a/kmpp/base/inc/kmpp_obj.h +++ b/kmpp/base/inc/kmpp_obj.h @@ -122,6 +122,8 @@ rk_s32 kmpp_obj_get_shm_obj(KmppObj obj, const char *name, KmppObj *val); /* update flag check function */ rk_s32 kmpp_obj_test(KmppObj obj, const char *name); rk_s32 kmpp_obj_tbl_test(KmppObj obj, KmppEntry *tbl); +rk_s32 kmpp_obj_update(KmppObj dst, KmppObj src); +rk_s32 kmpp_obj_update_entry(void *entry, KmppObj src); /* run a callback function */ rk_s32 kmpp_obj_run(KmppObj obj, const char *name); @@ -133,6 +135,8 @@ rk_s32 kmpp_obj_kdump_f(KmppObj obj, const char *caller); #define kmpp_obj_udump(obj) kmpp_obj_udump_f(obj, __FUNCTION__) #define kmpp_obj_kdump(obj) kmpp_obj_kdump_f(obj, __FUNCTION__) +const char *strof_elem_type(ElemType type); + #ifdef __cplusplus } #endif diff --git a/kmpp/base/kmpp_obj.c b/kmpp/base/kmpp_obj.c index 95a51d1e..6f742b02 100644 --- a/kmpp/base/kmpp_obj.c +++ b/kmpp/base/kmpp_obj.c @@ -60,18 +60,18 @@ #define ENTRY_TO_shm_PTR(tbl, entry) ((void *)ENTRY_TO_PTR(tbl, entry)) /* 32bit unsigned long pointer */ -#define ELEM_FLAG_U32_POS(offset) (((offset) & (~31)) / 8) -#define ELEM_FLAG_BIT_POS(offset) ((offset) & 31) -#define ENTRY_TO_FLAG_PTR(tbl, entry) ((rk_ul *)((rk_u8 *)entry + ELEM_FLAG_U32_POS(tbl->tbl.flag_offset))) +#define ELEM_FLAG_U32_POS(offset) (((offset) & (~31)) / 8) +#define ELEM_FLAG_BIT_POS(offset) ((offset) & 31) +#define ENTRY_TO_FLAG_PTR(e, entry) ((rk_ul *)((rk_u8 *)entry + ELEM_FLAG_U32_POS(e->tbl.flag_offset))) -#define ENTRY_SET_FLAG(tbl, entry) \ - *ENTRY_TO_FLAG_PTR(tbl, entry) |= 1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset)) +#define ENTRY_SET_FLAG(e, entry) \ + *ENTRY_TO_FLAG_PTR(e, entry) |= 1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset)) -#define ENTRY_CLR_FLAG(tbl, entry) \ - *ENTRY_TO_FLAG_PTR(tbl, entry) &= ~(1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset))) +#define ENTRY_CLR_FLAG(e, entry) \ + *ENTRY_TO_FLAG_PTR(e, entry) &= ~(1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset))) -#define ENTRY_TEST_FLAG(tbl, entry) \ - (*ENTRY_TO_FLAG_PTR(tbl, entry) & 1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset))) ? 1 : 0 +#define ENTRY_TEST_FLAG(e, entry) \ + (*ENTRY_TO_FLAG_PTR(e, entry) & 1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset))) ? 1 : 0 /* kernel object share memory get / put ioctl data */ typedef struct KmppObjIocArg_t { @@ -155,13 +155,14 @@ static KmppObjs *objs = NULL; #define get_objs_f() get_objs(__FUNCTION__) -const char *strof_entry_type(EntryType type) +const char *strof_elem_type(ElemType type) { static const char *ELEM_TYPE_names[] = { [ELEM_TYPE_s32] = "s32", [ELEM_TYPE_u32] = "u32", [ELEM_TYPE_s64] = "s64", [ELEM_TYPE_u64] = "u64", + [ELEM_TYPE_ptr] = "ptr", [ELEM_TYPE_st] = "struct", [ELEM_TYPE_shm] = "shm_ptr", [ELEM_TYPE_kobj] = "kobj", @@ -999,6 +1000,12 @@ rk_s32 kmpp_obj_check(KmppObj obj, const char *caller) return rk_nok; } + if (!impl->entry || !impl->def->trie) { + mpp_loge_f("from %s failed for entry %p and def trie %p\n", caller, + impl->entry, impl->def->trie); + return rk_nok; + } + return rk_ok; } @@ -1328,6 +1335,71 @@ rk_s32 kmpp_obj_tbl_test(KmppObj obj, KmppEntry *tbl) return (impl && tbl) ? ENTRY_TEST_FLAG(tbl, impl->entry) : 0; } +rk_s32 kmpp_obj_update(KmppObj dst, KmppObj src) +{ + KmppObjImpl *dst_impl = (KmppObjImpl *)dst; + KmppObjImpl *src_impl = (KmppObjImpl *)src; + MppTrie trie = NULL; + MppTrieInfo *info = NULL; + + if (kmpp_obj_check_f(src) || kmpp_obj_check_f(dst) || src_impl->def != dst_impl->def) { + mpp_loge_f("obj %p update to %p failed invalid param\n", src, dst); + return rk_nok; + } + + trie = src_impl->def->trie; + + info = mpp_trie_get_info_first(trie); + do { + KmppEntry *e; + + if (mpp_trie_info_is_self(info)) + continue; + + e = (KmppEntry *)mpp_trie_info_ctx(info); + if (ENTRY_TEST_FLAG(e, src_impl->entry)) { + rk_s32 offset = e->tbl.elem_offset; + rk_s32 size = e->tbl.elem_size; + + memcpy(dst_impl->entry + offset, src_impl->entry + offset, size); + } + } while ((info = mpp_trie_get_info_next(trie, info))); + + return rk_ok; +} + +rk_s32 kmpp_obj_update_entry(void *entry, KmppObj src) +{ + KmppObjImpl *src_impl = (KmppObjImpl *)src; + MppTrie trie = NULL; + MppTrieInfo *info = NULL; + + if (kmpp_obj_check_f(src) || !entry) { + mpp_loge_f("obj %p update to entry %p failed invalid param\n", src, entry); + return rk_nok; + } + + trie = src_impl->def->trie; + + info = mpp_trie_get_info_first(trie); + do { + KmppEntry *e; + + if (mpp_trie_info_is_self(info)) + continue; + + e = (KmppEntry *)mpp_trie_info_ctx(info); + if (ENTRY_TEST_FLAG(e, src_impl->entry)) { + rk_s32 offset = e->tbl.elem_offset; + rk_s32 size = e->tbl.elem_size; + + memcpy(entry + offset, src_impl->entry + offset, size); + } + } while ((info = mpp_trie_get_info_next(trie, info))); + + return rk_ok; +} + static rk_s32 kmpp_obj_impl_run(rk_s32 (*run)(void *ctx), void *ctx) { return run(ctx);