[mpp_buffer]: add log mechanism to mpp_buffer

git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@894 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
ChenHengming
2016-06-08 06:09:30 +00:00
parent c25d5ec6e0
commit c511cf3688
2 changed files with 126 additions and 71 deletions

View File

@@ -42,7 +42,7 @@ struct MppBufferImpl_t {
char tag[MPP_TAG_SIZE]; char tag[MPP_TAG_SIZE];
const char *caller; const char *caller;
RK_U32 group_id; RK_U32 group_id;
RK_U32 buffer_id; RK_S32 buffer_id;
MppBufferMode mode; MppBufferMode mode;
MppBufferInfo info; MppBufferInfo info;
@@ -72,14 +72,14 @@ struct MppBufferGroupImpl_t {
// status record // status record
size_t limit; size_t limit;
size_t usage; size_t usage;
RK_S32 count; RK_S32 buffer_id;
RK_S32 buffer_count;
RK_S32 count_used;
RK_S32 count_unused;
MppAllocator allocator; MppAllocator allocator;
MppAllocatorApi *alloc_api; MppAllocatorApi *alloc_api;
RK_S32 count_used;
RK_S32 count_unused;
// thread that will be signal on buffer return // thread that will be signal on buffer return
void *listener; void *listener;
@@ -88,6 +88,12 @@ struct MppBufferGroupImpl_t {
// is_orphan: 0 - normal group 1 - orphan group // is_orphan: 0 - normal group 1 - orphan group
RK_U32 is_orphan; RK_U32 is_orphan;
// buffer log function
RK_U32 log_runtime_en;
RK_U32 log_history_en;
RK_U32 log_count;
struct list_head list_logs;
// link to the other MppBufferGroupImpl // link to the other MppBufferGroupImpl
struct list_head list_group; struct list_head list_group;

View File

@@ -24,11 +24,18 @@
#include "mpp_buffer_impl.h" #include "mpp_buffer_impl.h"
#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))
typedef MPP_RET (*BufferOp)(MppAllocator allocator, MppBufferInfo *data); typedef MPP_RET (*BufferOp)(MppAllocator allocator, MppBufferInfo *data);
typedef enum MppBufOps_e { typedef enum MppBufOps_e {
GRP_CREATE,
GRP_RELEASE,
GRP_DESTROY,
GRP_OPS_BUTT = GRP_DESTROY,
BUF_COMMIT, BUF_COMMIT,
BUF_CREATE, BUF_CREATE,
BUF_REF_INC, BUF_REF_INC,
@@ -39,7 +46,8 @@ typedef enum MppBufOps_e {
typedef struct MppBufLog_t { typedef struct MppBufLog_t {
struct list_head list; struct list_head list;
MppBuffer buf; RK_U32 group_id;
RK_S32 buffer_id;
MppBufOps ops; MppBufOps ops;
RK_S32 ref_count; RK_S32 ref_count;
} MppBufLog; } MppBufLog;
@@ -56,13 +64,11 @@ private:
MppBufferService &operator=(const MppBufferService &); MppBufferService &operator=(const MppBufferService &);
// buffer group final release function // buffer group final release function
void release_group(MppBufferGroupImpl *group); void destroy_group(MppBufferGroupImpl *group);
RK_U32 get_group_id(); RK_U32 get_group_id();
RK_U32 group_id; RK_U32 group_id;
RK_U32 group_count; RK_U32 group_count;
RK_U32 buffer_id;
RK_U32 buffer_count;
MppBufferGroupImpl *mLegacyGroup; MppBufferGroupImpl *mLegacyGroup;
@@ -71,11 +77,6 @@ private:
// 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;
// buffer log function
RK_U32 log_runtime_en;
RK_U32 log_history_en;
struct list_head list_logs;
public: public:
static MppBufferService *get_instance() static MppBufferService *get_instance()
{ {
@@ -91,10 +92,7 @@ public:
MppBufferGroupImpl *get_group(const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); MppBufferGroupImpl *get_group(const char *tag, const char *caller, MppBufferMode mode, MppBufferType type);
MppBufferGroupImpl *get_legacy_group(); MppBufferGroupImpl *get_legacy_group();
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 add_log(MppBufferGroupImpl *group, MppBufferImpl *buffer, MppBufOps ops);
}; };
static const char *mode2str[MPP_BUFFER_MODE_BUTT] = { static const char *mode2str[MPP_BUFFER_MODE_BUTT] = {
@@ -109,15 +107,67 @@ static const char *type2str[MPP_BUFFER_TYPE_BUTT] = {
"drm", "drm",
}; };
static const char *ops2str[BUF_OPS_BUTT] = { static const char *ops2str[BUF_OPS_BUTT] = {
"commit", "grp create ",
"create", "grp release",
"ref inc", "grp destroy",
"ref dec", "buf commit ",
"destroy", "buf create ",
"buf ref inc",
"buf ref dec",
"buf destroy",
}; };
RK_U32 mpp_buffer_debug = 0; RK_U32 mpp_buffer_debug = 0;
void buffer_group_add_log(MppBufferGroupImpl *group, MppBufferImpl *buffer, MppBufOps ops)
{
if (group->log_runtime_en) {
if (buffer) {
mpp_log("group %3d buffer %4d ops %s ref_count %d\n", group->group_id,
buffer->buffer_id, ops2str[ops], buffer->ref_count);
} else {
mpp_log("group %3d ops %s\n", group->group_id, ops2str[ops]);
}
}
if (group->log_history_en) {
struct list_head *logs = &group->list_logs;
MppBufLog *log = mpp_malloc(MppBufLog, 1);
if (log) {
INIT_LIST_HEAD(&log->list);
log->group_id = group->group_id;
log->buffer_id = (buffer) ? (buffer->buffer_id) : (-1);
log->ops = ops;
log->ref_count = (buffer) ? (buffer->ref_count) : (0);
}
if (group->log_count >= BUFFER_OPS_MAX_COUNT) {
struct list_head *tmp = logs->next;
list_del_init(tmp);
mpp_free(list_entry(tmp, MppBufLog, list));
}
list_add_tail(&log->list, logs);
}
}
void buffer_group_dump_log(MppBufferGroupImpl *group)
{
if (group->log_history_en) {
struct list_head *logs = &group->list_logs;
while (!list_empty(logs)) {
struct list_head *tmp = logs->next;
MppBufLog *log = list_entry(tmp, MppBufLog, list);
list_del_init(tmp);
if (log->buffer_id >= 0) {
mpp_log("group %3d buffer %4d ops %s ref_count %d\n", group->group_id,
log->buffer_id, ops2str[log->ops], log->ref_count);
} else {
mpp_log("group %3d ops %s\n", group->group_id, ops2str[log->ops]);
}
mpp_free(log);
}
}
}
MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer) MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer)
{ {
mpp_assert(buffer->ref_count == 0); mpp_assert(buffer->ref_count == 0);
@@ -125,20 +175,17 @@ MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer)
list_del_init(&buffer->list_status); list_del_init(&buffer->list_status);
MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id);
if (!group->is_orphan) { BufferOp func = (group->mode == MPP_BUFFER_INTERNAL) ?
BufferOp func = (group->mode == MPP_BUFFER_INTERNAL) ? (group->alloc_api->free) :
(group->alloc_api->free) : (group->alloc_api->release);
(group->alloc_api->release); func(group->allocator, &buffer->info);
func(group->allocator, &buffer->info); group->usage -= buffer->info.size;
group->usage -= buffer->info.size; group->buffer_count--;
group->count--;
} else { buffer_group_add_log(group, buffer, BUF_DESTROY);
mpp_assert(buffer->mode == MPP_BUFFER_INTERNAL);
group->alloc_api->free(group->allocator, &buffer->info); if (group->is_orphan && !group->usage) {
group->usage -= buffer->info.size; MppBufferService::get_instance()->put_group(group);
group->count--;
if (0 == group->usage)
MppBufferService::get_instance()->put_group(group);
} }
mpp_free(buffer); mpp_free(buffer);
@@ -149,8 +196,8 @@ MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer)
static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer) static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id);
if (!buffer->used) { if (!buffer->used) {
MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id);
// NOTE: when increasing ref_count the unused buffer must be under certain group // NOTE: when increasing ref_count the unused buffer must be under certain group
mpp_assert(group); mpp_assert(group);
buffer->used = 1; buffer->used = 1;
@@ -164,6 +211,7 @@ static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer)
ret = MPP_NOK; ret = MPP_NOK;
} }
} }
buffer_group_add_log(group, buffer, BUF_REF_INC);
buffer->ref_count++; buffer->ref_count++;
return ret; return ret;
} }
@@ -190,7 +238,7 @@ MPP_RET mpp_buffer_create(const char *tag, const char *caller, RK_U32 group_id,
goto RET; goto RET;
} }
if (group->limit_count && group->count >= group->limit_count) { if (group->limit_count && group->buffer_count >= group->limit_count) {
mpp_err_f("reach group count limit %d\n", group->limit_count); mpp_err_f("reach group count limit %d\n", group->limit_count);
ret = MPP_NOK; ret = MPP_NOK;
goto RET; goto RET;
@@ -228,11 +276,15 @@ MPP_RET mpp_buffer_create(const char *tag, const char *caller, RK_U32 group_id,
strncpy(p->tag, tag, sizeof(p->tag)); strncpy(p->tag, tag, sizeof(p->tag));
p->caller = caller; p->caller = caller;
p->group_id = group_id; p->group_id = group_id;
p->buffer_id = group->buffer_id;
INIT_LIST_HEAD(&p->list_status); INIT_LIST_HEAD(&p->list_status);
list_add_tail(&p->list_status, &group->list_unused); list_add_tail(&p->list_status, &group->list_unused);
group->buffer_id++;
group->usage += info->size; group->usage += info->size;
group->count++; group->buffer_count++;
group->count_unused++; group->count_unused++;
buffer_group_add_log(group, p, (group->mode == MPP_BUFFER_INTERNAL)?(BUF_CREATE):(BUF_COMMIT));
RET: RET:
MPP_BUF_FUNCTION_LEAVE(); MPP_BUF_FUNCTION_LEAVE();
return ret; return ret;
@@ -267,6 +319,8 @@ MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer)
MPP_BUF_FUNCTION_ENTER(); MPP_BUF_FUNCTION_ENTER();
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id);
buffer_group_add_log(group, buffer, BUF_REF_DEC);
if (buffer->ref_count <= 0) { if (buffer->ref_count <= 0) {
mpp_err_f("found non-positive ref_count %d caller %s\n", mpp_err_f("found non-positive ref_count %d caller %s\n",
@@ -277,7 +331,6 @@ MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer)
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);
MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id);
if (group == MppBufferService::get_instance()->get_legacy_group()) { if (group == MppBufferService::get_instance()->get_legacy_group()) {
deinit_buffer_no_lock(buffer); deinit_buffer_no_lock(buffer);
} else { } else {
@@ -423,6 +476,8 @@ void mpp_buffer_group_dump(MppBufferGroupImpl *group)
list_for_each_entry_safe(pos, n, &group->list_unused, MppBufferImpl, list_status) { list_for_each_entry_safe(pos, n, &group->list_unused, MppBufferImpl, list_status) {
dump_buffer_info(pos); dump_buffer_info(pos);
} }
buffer_group_dump_log(group);
} }
MppBufferGroupImpl *mpp_buffer_legacy_group() MppBufferGroupImpl *mpp_buffer_legacy_group()
@@ -434,20 +489,10 @@ MppBufferGroupImpl *mpp_buffer_legacy_group()
MppBufferService::MppBufferService() MppBufferService::MppBufferService()
: group_id(0), : group_id(0),
group_count(0), group_count(0),
buffer_id(0), mLegacyGroup(NULL)
buffer_count(0),
mLegacyGroup(NULL),
log_runtime_en(0),
log_history_en(0)
{ {
INIT_LIST_HEAD(&mListGroup); INIT_LIST_HEAD(&mListGroup);
INIT_LIST_HEAD(&mListOrphan); INIT_LIST_HEAD(&mListOrphan);
INIT_LIST_HEAD(&list_logs);
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0);
log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0);
log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0);
// NOTE: here can not call mpp_buffer_group_init for the service is not started // NOTE: here can not call mpp_buffer_group_init for the service is not started
mLegacyGroup = get_group("legacy", "MppBufferService", MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION); mLegacyGroup = get_group("legacy", "MppBufferService", MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION);
} }
@@ -499,10 +544,15 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
RK_U32 id = get_group_id(); RK_U32 id = get_group_id();
INIT_LIST_HEAD(&p->list_logs);
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);
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_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0);
list_add_tail(&p->list_group, &mListGroup); list_add_tail(&p->list_group, &mListGroup);
if (tag) { if (tag) {
@@ -519,6 +569,8 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
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);
return p; return p;
} }
@@ -529,6 +581,8 @@ MppBufferGroupImpl *MppBufferService::get_legacy_group()
void MppBufferService::put_group(MppBufferGroupImpl *p) void MppBufferService::put_group(MppBufferGroupImpl *p)
{ {
buffer_group_add_log(p, NULL, GRP_RELEASE);
// remove unused list // remove unused list
if (!list_empty(&p->list_unused)) { if (!list_empty(&p->list_unused)) {
MppBufferImpl *pos, *n; MppBufferImpl *pos, *n;
@@ -539,7 +593,7 @@ void MppBufferService::put_group(MppBufferGroupImpl *p)
} }
if (list_empty(&p->list_used)) { if (list_empty(&p->list_used)) {
release_group(p); destroy_group(p);
} else { } else {
mpp_err("mpp_group %p tag %s caller %s mode %s type %s deinit with %d bytes not released\n", mpp_err("mpp_group %p tag %s caller %s mode %s type %s deinit with %d bytes not released\n",
p, p->tag, p->caller, mode2str[p->mode], type2str[p->type], p->usage); p, p->tag, p->caller, mode2str[p->mode], type2str[p->type], p->usage);
@@ -561,7 +615,7 @@ void MppBufferService::put_group(MppBufferGroupImpl *p)
p->count_used--; p->count_used--;
} }
release_group(p); destroy_group(p);
} else { } else {
// otherwise move the group to list_orphan and wait for buffer release // otherwise move the group to list_orphan and wait for buffer release
list_del_init(&p->list_group); list_del_init(&p->list_group);
@@ -571,7 +625,7 @@ void MppBufferService::put_group(MppBufferGroupImpl *p)
} }
} }
void MppBufferService::release_group(MppBufferGroupImpl *group) void MppBufferService::destroy_group(MppBufferGroupImpl *group)
{ {
mpp_assert(group->count_used == 0); mpp_assert(group->count_used == 0);
mpp_assert(group->count_unused == 0); mpp_assert(group->count_unused == 0);
@@ -582,6 +636,17 @@ void MppBufferService::release_group(MppBufferGroupImpl *group)
group->count_used = 0; group->count_used = 0;
} }
buffer_group_add_log(group, NULL, GRP_DESTROY);
if (group->log_history_en) {
struct list_head *logs = &group->list_logs;
while (!list_empty(logs)) {
struct list_head *tmp = logs->next;
list_del_init(tmp);
mpp_free(list_entry(tmp, MppBufLog, list));
}
}
mpp_allocator_put(&group->allocator); mpp_allocator_put(&group->allocator);
list_del_init(&group->list_group); list_del_init(&group->list_group);
mpp_free(group); mpp_free(group);
@@ -591,7 +656,7 @@ void MppBufferService::release_group(MppBufferGroupImpl *group)
mLegacyGroup = NULL; mLegacyGroup = NULL;
} else { } else {
/* if only legacy group left dump the legacy group */ /* if only legacy group left dump the legacy group */
if (group_count == 1 && mLegacyGroup->count) { if (group_count == 1 && mLegacyGroup->buffer_count) {
mpp_log("found legacy group has buffer remain, start dumping\n"); mpp_log("found legacy group has buffer remain, start dumping\n");
mpp_buffer_group_dump(mLegacyGroup); mpp_buffer_group_dump(mLegacyGroup);
abort(); abort();
@@ -617,20 +682,4 @@ MppBufferGroupImpl *MppBufferService::get_group_by_id(RK_U32 id)
return NULL; return NULL;
} }
void MppBufferService::add_log(MppBufferGroupImpl *group, MppBufferImpl *buffer, MppBufOps ops)
{
if (log_runtime_en) {
mpp_log("group %p buffer %p ops %s val ref_count %d\n", group, buffer, ops2str[ops], buffer->ref_count);
}
if (log_history_en) {
MppBufLog *log = mpp_malloc(MppBufLog, 1);
if (log) {
INIT_LIST_HEAD(&log->list);
log->buf = buffer;
log->ops = ops;
log->ref_count = buffer->ref_count;
}
}
}