mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-09 02:50:06 +08:00
[mpp_buffer]: Use hashtable to search buffer group
When there are a lot of buffer groups created the search speed will be slow. We should use hashtable to speed up. Change-Id: I9ceeaa5a72eedf81597eeb83b34d417c74ceae04 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#define __MPP_BUFFER_IMPL_H__
|
#define __MPP_BUFFER_IMPL_H__
|
||||||
|
|
||||||
#include "mpp_list.h"
|
#include "mpp_list.h"
|
||||||
|
#include "mpp_hash.h"
|
||||||
#include "mpp_common.h"
|
#include "mpp_common.h"
|
||||||
#include "mpp_allocator.h"
|
#include "mpp_allocator.h"
|
||||||
|
|
||||||
@@ -91,6 +92,8 @@ struct MppBufferGroupImpl_t {
|
|||||||
// buffer force clear mode flag
|
// buffer force clear mode flag
|
||||||
RK_U32 clear_on_exit;
|
RK_U32 clear_on_exit;
|
||||||
RK_U32 dump_on_exit;
|
RK_U32 dump_on_exit;
|
||||||
|
// is_misc: 0 - normal group 1 - misc group
|
||||||
|
RK_U32 is_misc;
|
||||||
// is_orphan: 0 - normal group 1 - orphan group
|
// is_orphan: 0 - normal group 1 - orphan group
|
||||||
RK_U32 is_orphan;
|
RK_U32 is_orphan;
|
||||||
RK_U32 is_finalizing;
|
RK_U32 is_finalizing;
|
||||||
@@ -103,6 +106,7 @@ struct MppBufferGroupImpl_t {
|
|||||||
|
|
||||||
// link to the other MppBufferGroupImpl
|
// link to the other MppBufferGroupImpl
|
||||||
struct list_head list_group;
|
struct list_head list_group;
|
||||||
|
struct hlist_node hlist;
|
||||||
|
|
||||||
// link to list_status in MppBufferImpl
|
// link to list_status in MppBufferImpl
|
||||||
struct list_head list_used;
|
struct list_head list_used;
|
||||||
@@ -155,7 +159,7 @@ MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p,
|
|||||||
MppBufCallback callback, void *arg);
|
MppBufCallback callback, void *arg);
|
||||||
// mpp_buffer_group helper function
|
// mpp_buffer_group helper function
|
||||||
void mpp_buffer_group_dump(MppBufferGroupImpl *p);
|
void mpp_buffer_group_dump(MppBufferGroupImpl *p);
|
||||||
void mpp_buffer_service_dump();
|
void mpp_buffer_service_dump(const char *info);
|
||||||
MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type);
|
MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -21,9 +21,12 @@
|
|||||||
#include "mpp_log.h"
|
#include "mpp_log.h"
|
||||||
#include "mpp_mem.h"
|
#include "mpp_mem.h"
|
||||||
#include "mpp_env.h"
|
#include "mpp_env.h"
|
||||||
|
#include "mpp_hash.h"
|
||||||
|
|
||||||
#include "mpp_buffer_impl.h"
|
#include "mpp_buffer_impl.h"
|
||||||
|
|
||||||
|
#define MAX_GROUP_BIT 8
|
||||||
|
#define MAX_MISC_GROUP_BIT 3
|
||||||
#define BUFFER_OPS_MAX_COUNT 1024
|
#define BUFFER_OPS_MAX_COUNT 1024
|
||||||
|
|
||||||
#define SEARCH_GROUP_BY_ID(id) ((MppBufferService::get_instance())->get_group_by_id(id))
|
#define SEARCH_GROUP_BY_ID(id) ((MppBufferService::get_instance())->get_group_by_id(id))
|
||||||
@@ -81,10 +84,11 @@ private:
|
|||||||
RK_U32 total_max;
|
RK_U32 total_max;
|
||||||
|
|
||||||
// misc group for internal / externl buffer with different type
|
// misc group for internal / externl buffer with different type
|
||||||
MppBufferGroupImpl *misc[MPP_BUFFER_MODE_BUTT][MPP_BUFFER_TYPE_BUTT];
|
RK_U32 misc[MPP_BUFFER_MODE_BUTT][MPP_BUFFER_TYPE_BUTT];
|
||||||
RK_U32 misc_count;
|
RK_U32 misc_count;
|
||||||
|
|
||||||
struct list_head mListGroup;
|
struct list_head mListGroup;
|
||||||
|
DECLARE_HASHTABLE(mHashGroup, MAX_GROUP_BIT);
|
||||||
|
|
||||||
// list for used buffer which do not have group
|
// list for used buffer which do not have group
|
||||||
struct list_head mListOrphan;
|
struct list_head mListOrphan;
|
||||||
@@ -102,11 +106,10 @@ public:
|
|||||||
MppBufferGroupImpl *get_group(const char *tag, const char *caller,
|
MppBufferGroupImpl *get_group(const char *tag, const char *caller,
|
||||||
MppBufferMode mode, MppBufferType type,
|
MppBufferMode mode, MppBufferType type,
|
||||||
RK_U32 is_misc);
|
RK_U32 is_misc);
|
||||||
MppBufferGroupImpl *get_misc(MppBufferMode mode, MppBufferType type);
|
RK_U32 get_misc(MppBufferMode mode, MppBufferType type);
|
||||||
void set_misc(MppBufferMode mode, MppBufferType type, MppBufferGroupImpl *val);
|
|
||||||
void put_group(MppBufferGroupImpl *group);
|
void put_group(MppBufferGroupImpl *group);
|
||||||
MppBufferGroupImpl *get_group_by_id(RK_U32 id);
|
MppBufferGroupImpl *get_group_by_id(RK_U32 id);
|
||||||
void dump_misc_group();
|
void dump(const char *info);
|
||||||
RK_U32 is_finalizing();
|
RK_U32 is_finalizing();
|
||||||
void inc_total(RK_U32 size);
|
void inc_total(RK_U32 size);
|
||||||
void dec_total(RK_U32 size);
|
void dec_total(RK_U32 size);
|
||||||
@@ -197,6 +200,7 @@ static void buffer_group_dump_log(MppBufferGroupImpl *group)
|
|||||||
ops2str[log->ops]);
|
ops2str[log->ops]);
|
||||||
}
|
}
|
||||||
mpp_free(log);
|
mpp_free(log);
|
||||||
|
group->log_count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,7 +406,7 @@ MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller)
|
|||||||
if (0 == buffer->ref_count) {
|
if (0 == buffer->ref_count) {
|
||||||
buffer->used = 0;
|
buffer->used = 0;
|
||||||
list_del_init(&buffer->list_status);
|
list_del_init(&buffer->list_status);
|
||||||
if (group == MppBufferService::get_instance()->get_misc(group->mode, group->type)) {
|
if (group->is_misc) {
|
||||||
deinit_buffer_no_lock(buffer, caller);
|
deinit_buffer_no_lock(buffer, caller);
|
||||||
} else {
|
} else {
|
||||||
if (buffer->discard) {
|
if (buffer->discard) {
|
||||||
@@ -587,10 +591,11 @@ void mpp_buffer_group_dump(MppBufferGroupImpl *group, const char *caller)
|
|||||||
buffer_group_dump_log(group);
|
buffer_group_dump_log(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_buffer_service_dump()
|
void mpp_buffer_service_dump(const char *info)
|
||||||
{
|
{
|
||||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||||
MppBufferService::get_instance()->dump_misc_group();
|
|
||||||
|
MppBufferService::get_instance()->dump(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MppBufferService::inc_total(RK_U32 size)
|
void MppBufferService::inc_total(RK_U32 size)
|
||||||
@@ -619,9 +624,20 @@ RK_U32 mpp_buffer_total_max()
|
|||||||
|
|
||||||
MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type)
|
MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type)
|
||||||
{
|
{
|
||||||
|
MppBufferGroupImpl *misc;
|
||||||
|
RK_U32 id;
|
||||||
|
|
||||||
|
type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
|
||||||
|
if (type == MPP_BUFFER_TYPE_NORMAL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
|
||||||
|
mpp_assert(type < MPP_BUFFER_TYPE_BUTT);
|
||||||
|
|
||||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||||
MppBufferGroupImpl *misc = MppBufferService::get_instance()->get_misc(mode, type);
|
|
||||||
if (NULL == misc) {
|
id = MppBufferService::get_instance()->get_misc(mode, type);
|
||||||
|
if (!id) {
|
||||||
char tag[32];
|
char tag[32];
|
||||||
RK_S32 offset = 0;
|
RK_S32 offset = 0;
|
||||||
|
|
||||||
@@ -633,12 +649,14 @@ MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType
|
|||||||
mode == MPP_BUFFER_INTERNAL ? "int" : "ext");
|
mode == MPP_BUFFER_INTERNAL ? "int" : "ext");
|
||||||
|
|
||||||
misc = MppBufferService::get_instance()->get_group(tag, __FUNCTION__, mode, type, 1);
|
misc = MppBufferService::get_instance()->get_group(tag, __FUNCTION__, mode, type, 1);
|
||||||
}
|
} else
|
||||||
|
misc = MppBufferService::get_instance()->get_group_by_id(id);
|
||||||
|
|
||||||
return misc;
|
return misc;
|
||||||
}
|
}
|
||||||
|
|
||||||
MppBufferService::MppBufferService()
|
MppBufferService::MppBufferService()
|
||||||
: group_id(0),
|
: group_id(1),
|
||||||
group_count(0),
|
group_count(0),
|
||||||
finalizing(0),
|
finalizing(0),
|
||||||
finished(0),
|
finished(0),
|
||||||
@@ -654,7 +672,10 @@ MppBufferService::MppBufferService()
|
|||||||
// NOTE: Do not create misc group at beginning. Only create on when needed.
|
// NOTE: Do not create misc group at beginning. Only create on when needed.
|
||||||
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
|
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
|
||||||
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++)
|
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++)
|
||||||
misc[i][j] = NULL;
|
misc[i][j] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < (RK_S32)HASH_SIZE(mHashGroup); i++)
|
||||||
|
INIT_HLIST_HEAD(&mHashGroup[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MppBufferService::~MppBufferService()
|
MppBufferService::~MppBufferService()
|
||||||
@@ -668,10 +689,11 @@ MppBufferService::~MppBufferService()
|
|||||||
mpp_log_f("cleaning misc group\n");
|
mpp_log_f("cleaning misc group\n");
|
||||||
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
|
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
|
||||||
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++) {
|
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++) {
|
||||||
MppBufferGroupImpl *pos = misc[i][j];
|
RK_U32 id = misc[i][j];
|
||||||
if (pos) {
|
|
||||||
put_group(pos);
|
if (id) {
|
||||||
misc[i][j] = NULL;
|
put_group(get_group_by_id(id));
|
||||||
|
misc[i][j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,12 +725,29 @@ MppBufferService::~MppBufferService()
|
|||||||
|
|
||||||
RK_U32 MppBufferService::get_group_id()
|
RK_U32 MppBufferService::get_group_id()
|
||||||
{
|
{
|
||||||
// avoid group_id reuse
|
RK_U32 id;
|
||||||
RK_U32 id = group_id++;
|
static RK_U32 overflowed = 0;
|
||||||
while (get_group_by_id(group_id)) {
|
|
||||||
|
/* avoid 0 group id */
|
||||||
|
if (!group_id)
|
||||||
group_id++;
|
group_id++;
|
||||||
|
|
||||||
|
id = group_id++;
|
||||||
|
/* check overflow */
|
||||||
|
if (!id) {
|
||||||
|
overflowed = 1;
|
||||||
|
id = group_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// avoid group_id reuse
|
||||||
|
if (overflowed) {
|
||||||
|
/* when it is overflow avoid the used id */
|
||||||
|
while (get_group_by_id(id))
|
||||||
|
id = group_id++;
|
||||||
|
}
|
||||||
|
|
||||||
group_count++;
|
group_count++;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,13 +768,12 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
|||||||
INIT_LIST_HEAD(&p->list_group);
|
INIT_LIST_HEAD(&p->list_group);
|
||||||
INIT_LIST_HEAD(&p->list_used);
|
INIT_LIST_HEAD(&p->list_used);
|
||||||
INIT_LIST_HEAD(&p->list_unused);
|
INIT_LIST_HEAD(&p->list_unused);
|
||||||
|
INIT_HLIST_NODE(&p->hlist);
|
||||||
|
|
||||||
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0);
|
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0);
|
||||||
p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0);
|
p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0);
|
||||||
p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0);
|
p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0);
|
||||||
|
|
||||||
list_add_tail(&p->list_group, &mListGroup);
|
|
||||||
|
|
||||||
if (tag) {
|
if (tag) {
|
||||||
snprintf(p->tag, sizeof(p->tag), "%s_%d", tag, id);
|
snprintf(p->tag, sizeof(p->tag), "%s_%d", tag, id);
|
||||||
} else {
|
} else {
|
||||||
@@ -749,6 +787,9 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
|||||||
p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0);
|
p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0);
|
||||||
p->dump_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_DUMP_ON_EXIT) ? (1) : (0);
|
p->dump_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_DUMP_ON_EXIT) ? (1) : (0);
|
||||||
|
|
||||||
|
list_add_tail(&p->list_group, &mListGroup);
|
||||||
|
hash_add(mHashGroup, &p->hlist, hash_32(p->group_id, MAX_GROUP_BIT));
|
||||||
|
|
||||||
mpp_allocator_get(&p->allocator, &p->alloc_api, type);
|
mpp_allocator_get(&p->allocator, &p->alloc_api, type);
|
||||||
|
|
||||||
buffer_group_add_log(p, NULL, GRP_CREATE, __FUNCTION__);
|
buffer_group_add_log(p, NULL, GRP_CREATE, __FUNCTION__);
|
||||||
@@ -757,18 +798,19 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
|||||||
mpp_assert(buffer_type < MPP_BUFFER_TYPE_BUTT);
|
mpp_assert(buffer_type < MPP_BUFFER_TYPE_BUTT);
|
||||||
|
|
||||||
if (is_misc) {
|
if (is_misc) {
|
||||||
misc[mode][buffer_type] = p;
|
misc[mode][buffer_type] = id;
|
||||||
|
p->is_misc = 1;
|
||||||
misc_count++;
|
misc_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
MppBufferGroupImpl *MppBufferService::get_misc(MppBufferMode mode, MppBufferType type)
|
RK_U32 MppBufferService::get_misc(MppBufferMode mode, MppBufferType type)
|
||||||
{
|
{
|
||||||
type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
|
type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
|
||||||
if (type == MPP_BUFFER_TYPE_NORMAL)
|
if (type == MPP_BUFFER_TYPE_NORMAL)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
|
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
|
||||||
mpp_assert(type < MPP_BUFFER_TYPE_BUTT);
|
mpp_assert(type < MPP_BUFFER_TYPE_BUTT);
|
||||||
@@ -776,18 +818,6 @@ MppBufferGroupImpl *MppBufferService::get_misc(MppBufferMode mode, MppBufferType
|
|||||||
return misc[mode][type];
|
return misc[mode][type];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MppBufferService::set_misc(MppBufferMode mode, MppBufferType type, MppBufferGroupImpl *val)
|
|
||||||
{
|
|
||||||
type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
|
|
||||||
if (type == MPP_BUFFER_TYPE_NORMAL)
|
|
||||||
return ;
|
|
||||||
|
|
||||||
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
|
|
||||||
mpp_assert(type < MPP_BUFFER_TYPE_BUTT);
|
|
||||||
|
|
||||||
misc[mode][type] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MppBufferService::put_group(MppBufferGroupImpl *p)
|
void MppBufferService::put_group(MppBufferGroupImpl *p)
|
||||||
{
|
{
|
||||||
if (finished)
|
if (finished)
|
||||||
@@ -846,6 +876,7 @@ void MppBufferService::destroy_group(MppBufferGroupImpl *group)
|
|||||||
{
|
{
|
||||||
MppBufferMode mode = group->mode;
|
MppBufferMode mode = group->mode;
|
||||||
MppBufferType type = group->type;
|
MppBufferType type = group->type;
|
||||||
|
RK_U32 id = group->group_id;
|
||||||
|
|
||||||
mpp_assert(group->count_used == 0);
|
mpp_assert(group->count_used == 0);
|
||||||
mpp_assert(group->count_unused == 0);
|
mpp_assert(group->count_unused == 0);
|
||||||
@@ -872,46 +903,47 @@ void MppBufferService::destroy_group(MppBufferGroupImpl *group)
|
|||||||
mpp_assert(group->allocator);
|
mpp_assert(group->allocator);
|
||||||
mpp_allocator_put(&group->allocator);
|
mpp_allocator_put(&group->allocator);
|
||||||
list_del_init(&group->list_group);
|
list_del_init(&group->list_group);
|
||||||
|
hash_del(&group->hlist);
|
||||||
mpp_free(group);
|
mpp_free(group);
|
||||||
group_count--;
|
group_count--;
|
||||||
|
|
||||||
if (group == misc[mode][type]) {
|
if (id == misc[mode][type]) {
|
||||||
misc[mode][type] = NULL;
|
misc[mode][type] = 0;
|
||||||
misc_count--;
|
misc_count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MppBufferGroupImpl *MppBufferService::get_group_by_id(RK_U32 id)
|
MppBufferGroupImpl *MppBufferService::get_group_by_id(RK_U32 id)
|
||||||
{
|
{
|
||||||
MppBufferGroupImpl *pos, *n;
|
MppBufferGroupImpl *impl = NULL;
|
||||||
list_for_each_entry_safe(pos, n, &mListGroup, MppBufferGroupImpl, list_group) {
|
RK_U32 key = hash_32(id, MAX_GROUP_BIT);
|
||||||
if (pos->group_id == id) {
|
|
||||||
return pos;
|
hash_for_each_possible(mHashGroup, impl, hlist, key) {
|
||||||
}
|
if (impl->group_id == id)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &mListOrphan, MppBufferGroupImpl, list_group) {
|
return impl;
|
||||||
if (pos->group_id == id) {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MppBufferService::dump_misc_group()
|
void MppBufferService::dump(const char *info)
|
||||||
{
|
{
|
||||||
RK_S32 i, j;
|
MppBufferGroupImpl *group;
|
||||||
|
struct hlist_node *n;
|
||||||
|
RK_U32 key;
|
||||||
|
|
||||||
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
|
mpp_log("dumping all buffer groups for %s\n", info);
|
||||||
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++) {
|
|
||||||
if (misc[i][j])
|
if (hash_empty(mHashGroup)) {
|
||||||
mpp_buffer_group_dump(misc[i][j], __FUNCTION__);
|
mpp_log("no buffer group can be dumped\n");
|
||||||
|
} else {
|
||||||
|
hash_for_each_safe(mHashGroup, key, n, group, hlist) {
|
||||||
|
mpp_buffer_group_dump(group, __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RK_U32 MppBufferService::is_finalizing()
|
RK_U32 MppBufferService::is_finalizing()
|
||||||
{
|
{
|
||||||
return finalizing;
|
return finalizing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user