* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* cm_context_pool.c
*
*
* IDENTIFICATION
* src/common/cm_context_pool.c
*
* -------------------------------------------------------------------------
*/
#include "cm_common_module.h"
#include "cm_hash.h"
#include "cm_context_pool.h"
status_t ogx_pool_create(context_pool_profile_t *profile, context_pool_t **pool)
{
uint32 pool_size = OFFSET_OF(context_pool_t, buckets) + profile->bucket_count * sizeof(context_bucket_t);
pool_size = CM_ALIGN8(pool_size);
uint32 map_size = OFFSET_OF(context_map_t, items) + profile->optimize_pages * sizeof(uint32);
map_size = CM_ALIGN8(map_size);
uint32 total_size = pool_size + sizeof(memory_pool_t) + map_size + OG_LRU_LIST_CNT * sizeof(lru_list_t);
total_size = CM_ALIGN8(total_size);
context_pool_t *ogx_pool = (context_pool_t *)malloc(total_size);
if (ogx_pool == NULL) {
OG_THROW_ERROR(ERR_ALLOC_MEMORY, (uint64)total_size, profile->name);
return OG_ERROR;
}
errno_t rc_memzero = memset_sp(ogx_pool, (size_t)total_size, 0, (size_t)total_size);
if (rc_memzero != EOK) {
CM_FREE_PTR(ogx_pool);
OG_THROW_ERROR(ERR_RESET_MEMORY, "ogx_pool");
return OG_ERROR;
}
ogx_pool->memory = (memory_pool_t *)((char *)ogx_pool + pool_size);
ogx_pool->map = (context_map_t *)((char *)ogx_pool + pool_size + sizeof(memory_pool_t));
ogx_pool->map->map_size = profile->optimize_pages;
ogx_pool->map->free_items.first = OG_INVALID_ID32;
ogx_pool->lru_list = (lru_list_t *)((char *)ogx_pool + pool_size + sizeof(memory_pool_t) + map_size);
ogx_pool->lru_list_cnt = OG_LRU_LIST_CNT;
if (mpool_create(profile->area, profile->name,
profile->init_pages, profile->optimize_pages, ogx_pool->memory) != OG_SUCCESS) {
CM_FREE_PTR(ogx_pool);
return OG_ERROR;
}
*pool = ogx_pool;
ogx_pool->context_size = profile->context_size;
ogx_pool->bucket_count = profile->bucket_count;
ogx_pool->clean = profile->clean;
ogx_pool->memory->mem_alloc.ogx = ogx_pool;
ogx_pool->memory->mem_alloc.mem_func = (mem_func_t)sql_ctx_alloc_mem;
return OG_SUCCESS;
}
void ogx_pool_destroy(context_pool_t *pool)
{
CM_FREE_PTR(pool);
}
static void ogx_lru_add(lru_list_t *lru_list, context_ctrl_t *ctrl)
{
if (lru_list->lru_head == NULL) {
lru_list->lru_head = ctrl;
lru_list->lru_tail = ctrl;
ctrl->lru_prev = NULL;
ctrl->lru_next = NULL;
} else {
ctrl->lru_next = lru_list->lru_head;
ctrl->lru_prev = NULL;
lru_list->lru_head->lru_prev = ctrl;
lru_list->lru_head = ctrl;
}
lru_list->lru_count++;
}
static inline void ogx_lru_remove(lru_list_t *lru_list, context_ctrl_t *ctrl)
{
if (lru_list->lru_head == ctrl) {
lru_list->lru_head = ctrl->lru_next;
}
if (lru_list->lru_tail == ctrl) {
lru_list->lru_tail = ctrl->lru_prev;
}
if (ctrl->lru_prev != NULL) {
ctrl->lru_prev->lru_next = ctrl->lru_next;
}
if (ctrl->lru_next != NULL) {
ctrl->lru_next->lru_prev = ctrl->lru_prev;
}
ctrl->lru_prev = NULL;
ctrl->lru_next = NULL;
lru_list->lru_count--;
}
static inline void ogx_bucket_remove(context_ctrl_t *ctrl)
{
cm_spin_lock(&ctrl->bucket->enque_lock, NULL);
if (ctrl->hash_prev != NULL) {
ctrl->hash_prev->hash_next = ctrl->hash_next;
}
if (ctrl->hash_next != NULL) {
ctrl->hash_next->hash_prev = ctrl->hash_prev;
}
if (ctrl == ctrl->bucket->first) {
ctrl->bucket->first = ctrl->hash_next;
}
ctrl->hash_next = NULL;
ctrl->hash_prev = NULL;
cm_spin_unlock(&ctrl->bucket->enque_lock);
}
void ogx_bucket_insert(context_bucket_t *bucket, context_ctrl_t *ctrl)
{
cm_spin_lock(&bucket->enque_lock, NULL);
HASH_BUCKET_INSERT(bucket, ctrl);
cm_spin_unlock(&bucket->enque_lock);
}
static void ogx_map_remove(context_pool_t *pool, context_ctrl_t *ctrl)
{
if (ctrl->map_id == OG_INVALID_ID32) {
return;
}
pool->map->items[ctrl->map_id] = pool->map->free_items.first;
pool->map->free_items.first = (0x80000000 | ctrl->map_id);
pool->map->free_items.count++;
}
static void ogx_map_add(context_pool_t *pool, context_ctrl_t *ctrl)
{
uint32 id = OG_INVALID_ID32;
if (pool->map->free_items.count > 0) {
id = pool->map->free_items.first & 0x7FFFFFFF;
pool->map->free_items.count--;
pool->map->free_items.first = pool->map->items[id];
} else if (pool->map->hwm < pool->map->map_size) {
id = pool->map->hwm;
pool->map->hwm++;
}
ctrl->map_id = id;
if (id != OG_INVALID_ID32) {
pool->map->items[id] = ctrl->memory->pages.first;
}
}
void ogx_insert(context_pool_t *pool, context_ctrl_t *ctrl)
{
lru_list_t *lru_list = &pool->lru_list[ctrl->hash_value % pool->lru_list_cnt];
cm_spin_lock(&lru_list->lock, NULL);
ogx_lru_add(lru_list, ctrl);
cm_spin_unlock(&lru_list->lock);
#ifndef TEST_MEM
cm_spin_lock(&pool->lock, NULL);
ogx_map_add(pool, ctrl);
cm_spin_unlock(&pool->lock);
#endif
}
static bool32 ogx_pool_try_remove(context_pool_t *pool, context_ctrl_t *ctrl)
{
lru_list_t *lru_list = NULL;
cm_spin_lock(&ctrl->lock, NULL);
if (ctrl->ref_count > 0) {
cm_spin_unlock(&ctrl->lock);
return OG_FALSE;
}
ctrl->valid = OG_FALSE;
pool->clean(ctrl);
cm_spin_unlock(&ctrl->lock);
cm_spin_lock(&pool->lock, NULL);
ogx_map_remove(pool, ctrl);
cm_spin_unlock(&pool->lock);
lru_list = &pool->lru_list[ctrl->hash_value % pool->lru_list_cnt];
ogx_lru_remove(lru_list, ctrl);
return OG_TRUE;
}
static inline void ogx_pool_lru_shift(lru_list_t *lru_list, context_ctrl_t *ctrl)
{
ogx_lru_remove(lru_list, ctrl);
ogx_lru_add(lru_list, ctrl);
}
void ogx_pool_lru_move_to_head(context_pool_t *pool, context_ctrl_t *ctrl)
{
if (mpool_has_remain_page(pool->memory)) {
return;
}
lru_list_t *lru_list = &pool->lru_list[ctrl->hash_value % pool->lru_list_cnt];
if (lru_list->lru_head == ctrl) {
return;
}
cm_spin_lock(&lru_list->lock, NULL);
ogx_pool_lru_shift(lru_list, ctrl);
cm_spin_unlock(&lru_list->lock);
}
static inline void ogx_destroy(context_ctrl_t *ctrl)
{
if (ctrl->subpool != NULL) {
ogx_recycle_all_core(ctrl->subpool);
}
ogx_bucket_remove(ctrl);
mctx_destroy(ctrl->memory);
}
static void ogx_recycle_referred_objects(context_pool_t *pool, context_ctrl_t *ctrl)
{
if (ctrl->subpool != NULL) {
ogx_recycle_all_core(ctrl->subpool);
}
cm_spin_lock(&ctrl->lock, NULL);
if (!ctrl->valid && ctrl->exec_count == 0) {
pool->clean(ctrl);
}
cm_spin_unlock(&ctrl->lock);
}
void ogx_recycle_all_core(context_pool_t *pool)
{
context_ctrl_t *ctrl = NULL;
context_ctrl_t *prev = NULL;
lru_list_t *lru_list = NULL;
for (uint32 i = 0; i < pool->lru_list_cnt; i++) {
lru_list = &pool->lru_list[i];
cm_spin_lock(&lru_list->lock, NULL);
ctrl = lru_list->lru_tail;
while (ctrl != NULL) {
prev = ctrl->lru_prev;
if (ogx_pool_try_remove(pool, ctrl)) {
ogx_destroy(ctrl);
} else {
ogx_recycle_referred_objects(pool, ctrl);
}
ctrl = prev;
}
cm_spin_unlock(&lru_list->lock);
}
}
bool32 ogx_recycle_internal_core(context_pool_t *pool)
{
context_ctrl_t *ctrl = NULL;
context_ctrl_t *head = NULL;
context_ctrl_t *prev = NULL;
lru_list_t *lru_list = NULL;
bool32 removed = OG_FALSE;
uint32 idx = pool->lru_list_idx++ % pool->lru_list_cnt;
for (uint32 i = 0; i < pool->lru_list_cnt; i++) {
lru_list = &pool->lru_list[(idx + i) % pool->lru_list_cnt];
cm_spin_lock(&lru_list->lock, NULL);
head = lru_list->lru_head;
ctrl = lru_list->lru_tail;
while (ctrl != NULL) {
if (!ctrl->fixed && ogx_pool_try_remove(pool, ctrl)) {
ogx_destroy(ctrl);
removed = OG_TRUE;
break;
}
if (ctrl->subpool != NULL && ogx_recycle_internal_core(ctrl->subpool)) {
removed = OG_TRUE;
break;
}
if (ctrl == head) {
break;
}
prev = ctrl->lru_prev;
if (ctrl->valid) {
ogx_pool_lru_shift(lru_list, ctrl);
}
ctrl = prev;
}
cm_spin_unlock(&lru_list->lock);
if (removed == OG_TRUE) {
break;
}
}
return removed;
}
static bool32 ogx_recycle_external(context_pool_t *pool)
{
if (pool->external_recycle == NULL) {
return OG_FALSE;
}
return pool->external_recycle();
}
static bool32 ogx_recycle(context_pool_t *pool)
{
if (ogx_recycle_internal_core(pool)) {
return OG_TRUE;
}
if (ogx_recycle_external(pool)) {
return OG_TRUE;
}
OG_THROW_ERROR(ERR_ALLOC_GA_MEMORY, pool->memory->name);
return OG_FALSE;
}
status_t ogx_alloc_exhausted(context_ctrl_t *ctrl, uint32 size, void **buf, uint32 *buf_size)
{
while (!mctx_try_alloc_exhausted(ctrl->memory, size, buf, buf_size)) {
if (!ogx_recycle(ctrl->pool)) {
return OG_ERROR;
}
}
return OG_SUCCESS;
}
#ifndef TEST_MEM
status_t ogx_write_text(context_ctrl_t *ctrl, text_t *text)
{
uint32 buf_size;
uint32 remain_size;
uint32 copy_size;
ctrl->text_size = text->len;
remain_size = text->len;
char *piece_str = text->str;
char *buf = NULL;
while (remain_size > 0) {
if (ogx_alloc_exhausted(ctrl, remain_size, (void **)&buf, &buf_size) != OG_SUCCESS) {
return OG_ERROR;
}
if (ctrl->text_addr == NULL) {
ctrl->text_addr = buf;
}
copy_size = buf_size > remain_size ? remain_size : buf_size;
if (copy_size != 0) {
MEMS_RETURN_IFERR(memcpy_sp(buf, (size_t)buf_size, piece_str, (size_t)copy_size));
}
piece_str += copy_size;
remain_size -= copy_size;
}
return OG_SUCCESS;
}
#else
status_t ogx_write_text(context_ctrl_t *ctrl, text_t *text)
{
errno_t errcode;
ctrl->text_size = text->len;
if (text->len == 0) {
OG_THROW_ERROR(ERR_MALLOC_BYTES_MEMORY, text->len);
return OG_ERROR;
}
ctrl->text_addr = (char *)malloc(text->len + 1);
if (ctrl->text_addr == NULL) {
OG_THROW_ERROR(ERR_MALLOC_BYTES_MEMORY, text->len);
return OG_ERROR;
}
errcode = memcpy_sp(ctrl->text_addr, text->len + 1, text->str, text->len);
if (errcode != EOK) {
CM_FREE_PTR(ctrl->text_addr);
OG_THROW_ERROR(ERR_RESET_MEMORY, "ctrl->text_addr");
return OG_ERROR;
}
ctrl->text_addr[text->len] = '\0';
return OG_SUCCESS;
}
#endif
void ogx_reuse(context_pool_t *pool, context_ctrl_t *ctrl)
{
memory_context_t *mctx = ctrl->memory;
if (pool->context_size != 0) {
MEMS_RETVOID_IFERR(memset_sp(ctrl, (size_t)pool->context_size, 0, (size_t)pool->context_size));
}
mctx->alloc_pos = sizeof(memory_context_t) + pool->context_size;
mctx->curr_page_id = mctx->pages.first;
mctx->curr_page_addr = mpool_page_addr(pool->memory, mctx->curr_page_id);
ctrl->valid = OG_TRUE;
ctrl->memory = mctx;
ctrl->pool = pool;
ctrl->subpool = NULL;
}
status_t ogx_create_mctx(context_pool_t *pool, memory_context_t **mctx)
{
while (!mctx_try_create(pool->memory, mctx)) {
if (!ogx_recycle(pool)) {
return OG_ERROR;
}
}
return OG_SUCCESS;
}
status_t ogx_create(context_pool_t *pool, context_ctrl_t **ctrl)
{
memory_context_t *mctx = NULL;
context_ctrl_t *ogx_ctrl = NULL;
if (ogx_create_mctx(pool, &mctx) != OG_SUCCESS) {
return OG_ERROR;
}
if (mctx_alloc(mctx, pool->context_size, (void **)&ogx_ctrl) != OG_SUCCESS) {
return OG_ERROR;
}
if (pool->context_size != 0) {
MEMS_RETURN_IFERR(memset_sp(ogx_ctrl, (size_t)pool->context_size, 0, (size_t)pool->context_size));
}
ogx_ctrl->valid = OG_TRUE;
ogx_ctrl->memory = mctx;
ogx_ctrl->pool = pool;
ogx_ctrl->subpool = NULL;
*ctrl = ogx_ctrl;
return OG_SUCCESS;
}
static inline void ogx_ctrl_dec_ref(context_ctrl_t *ctrl)
{
cm_spin_lock(&ctrl->lock, NULL);
ctrl->ref_count--;
cm_spin_unlock(&ctrl->lock);
}
#ifndef TEST_MEM
static bool32 ogx_matched(context_pool_t *pool, context_ctrl_t *ctrl, uint32 hash_value, text_t *text, uint32 uid)
{
text_t piece;
text_t sub_text;
uint32 remain_size;
uint32 page_id;
char *page = NULL;
cm_spin_lock(&ctrl->lock, NULL);
bool32 cond = (ctrl->hash_value != hash_value || text->len != ctrl->text_size || !ctrl->valid || ctrl->uid != uid);
if (cond) {
cm_spin_unlock(&ctrl->lock);
return OG_FALSE;
}
ctrl->ref_count++;
cm_spin_unlock(&ctrl->lock);
page_id = ctrl->memory->pages.first;
remain_size = ctrl->text_size;
sub_text.str = text->str;
while (remain_size > 0) {
page = mpool_page_addr(pool->memory, page_id);
if (page_id == ctrl->memory->pages.first) {
piece.str = ctrl->text_addr;
piece.len = (uint32)(pool->memory->page_size - (ctrl->text_addr - page));
} else {
piece.str = page;
piece.len = pool->memory->page_size;
}
piece.len = (piece.len > remain_size) ? remain_size : piece.len;
sub_text.len = piece.len;
if (!cm_text_equal(&piece, &sub_text)) {
ogx_ctrl_dec_ref(ctrl);
return OG_FALSE;
}
sub_text.str += piece.len;
remain_size -= piece.len;
if (page_id == ctrl->memory->pages.last) {
break;
}
page_id = MEM_NEXT_PAGE(pool->memory, page_id);
}
if (remain_size != 0) {
ogx_ctrl_dec_ref(ctrl);
return OG_FALSE;
}
return OG_TRUE;
}
#else
static bool32 ogx_matched(context_pool_t *pool, context_ctrl_t *ctrl, uint32 hash_value, text_t *text, uint32 uid)
{
cm_spin_lock(&ctrl->lock, NULL);
if (ctrl->hash_value != hash_value || text->len != ctrl->text_size || !ctrl->valid || ctrl->uid != uid) {
cm_spin_unlock(&ctrl->lock);
return OG_FALSE;
}
ctrl->ref_count++;
cm_spin_unlock(&ctrl->lock);
if (!cm_text_str_equal(text, ctrl->text_addr)) {
ogx_ctrl_dec_ref(ctrl);
return OG_FALSE;
}
return OG_TRUE;
}
#endif
void *ogx_pool_find(context_pool_t *pool, text_t *text, uint32 hash_value, uint32 uid)
{
context_bucket_t *bucket = NULL;
context_ctrl_t *ctrl = NULL;
bucket = &pool->buckets[hash_value % pool->bucket_count];
cm_spin_lock(&bucket->enque_lock, NULL);
ctrl = bucket->first;
while (ctrl != NULL) {
if (ogx_matched(pool, ctrl, hash_value, text, uid)) {
cm_spin_unlock(&bucket->enque_lock);
return ctrl;
}
ctrl = ctrl->hash_next;
}
cm_spin_unlock(&bucket->enque_lock);
return ctrl;
}
void ogx_dec_exec(context_ctrl_t *ctrl)
{
cm_spin_lock(&ctrl->lock, NULL);
ctrl->exec_count--;
CM_ASSERT(ctrl->exec_count >= 0);
cm_spin_unlock(&ctrl->lock);
}
void ogx_dec_ref(context_pool_t *pool, context_ctrl_t *ctrl)
{
cm_spin_lock(&ctrl->lock, NULL);
if (ctrl->ref_count > 1 || ctrl->valid) {
ctrl->ref_count--;
cm_spin_unlock(&ctrl->lock);
return;
}
pool->clean(ctrl);
cm_spin_unlock(&ctrl->lock);
cm_spin_lock(&pool->lock, NULL);
ogx_map_remove(pool, ctrl);
cm_spin_unlock(&pool->lock);
lru_list_t *lru_list = &pool->lru_list[ctrl->hash_value % pool->lru_list_cnt];
cm_spin_lock(&lru_list->lock, NULL);
ogx_lru_remove(lru_list, ctrl);
cm_spin_unlock(&lru_list->lock);
ogx_destroy(ctrl);
}
static inline uint32 ogx_get_first_sql_page_id(context_pool_t *pool, context_ctrl_t *ctrl)
{
uint32 page_id = ctrl->memory->pages.first;
char *page = NULL;
while (page_id != ctrl->memory->pages.last) {
page = mpool_page_addr(pool->memory, page_id);
if (ctrl->text_addr >= page && ctrl->text_addr < (page + pool->memory->page_size)) {
break;
}
page_id = MEM_NEXT_PAGE(pool->memory, page_id);
}
return page_id;
}
#ifndef TEST_MEM
void ogx_read_first_page_text(context_pool_t *pool, context_ctrl_t *ctrl, text_t *text)
{
uint32 remain_size;
uint32 piece_len;
uint32 page_id;
page_id = ogx_get_first_sql_page_id(pool, ctrl);
remain_size = ctrl->text_size;
piece_len = remain_size;
if (remain_size > 0) {
char *page = mpool_page_addr(pool->memory, page_id);
piece_len = (uint32)(pool->memory->page_size - (ctrl->text_addr - page));
piece_len = (piece_len > remain_size) ? remain_size : piece_len;
}
text->str = ctrl->text_addr;
text->len = piece_len;
}
#else
void ogx_read_first_page_text(context_pool_t *pool, context_ctrl_t *ctrl, text_t *text)
{
text->str = ctrl->text_addr;
text->len = ctrl->text_size;
}
#endif
#ifndef TEST_MEM
status_t ogx_read_text(context_pool_t *pool, context_ctrl_t *ctrl, text_t *text, bool32 is_cut)
{
char *page = NULL;
char *piece_str = NULL;
uint32 remain_size;
uint32 piece_len;
uint32 first_page_id;
uint32 page_id;
uint32 offset;
if (text->len <= ctrl->text_size && is_cut == OG_FALSE) {
OG_THROW_ERROR(ERR_BUFFER_OVERFLOW, ctrl->text_size, text->len);
return OG_ERROR;
} else if (text->len <= ctrl->text_size &&
is_cut == OG_TRUE) {
remain_size = text->len - 1;
} else {
remain_size = ctrl->text_size;
}
offset = 0;
first_page_id = ogx_get_first_sql_page_id(pool, ctrl);
page_id = first_page_id;
while (remain_size > 0) {
page = mpool_page_addr(pool->memory, page_id);
if (page_id == first_page_id) {
piece_str = ctrl->text_addr;
piece_len = (uint32)(pool->memory->page_size - (ctrl->text_addr - page));
} else {
piece_str = page;
piece_len = pool->memory->page_size;
}
piece_len = (piece_len > remain_size) ? remain_size : piece_len;
if (piece_len != 0) {
MEMS_RETURN_IFERR(memcpy_sp(text->str + offset, (size_t)(text->len - offset), piece_str,
(size_t)piece_len));
}
offset += piece_len;
remain_size -= piece_len;
if (page_id == ctrl->memory->pages.last) {
break;
}
page_id = MEM_NEXT_PAGE(pool->memory, page_id);
}
text->str[offset] = '\0';
text->len = offset;
return OG_SUCCESS;
}
#else
status_t ogx_read_text(context_pool_t *pool, context_ctrl_t *ctrl, text_t *text, bool32 is_cut)
{
text->str = ctrl->text_addr;
text->len = ctrl->text_size;
return OG_SUCCESS;
}
#endif
status_t sql_ctx_alloc_mem(context_pool_t *pool, memory_context_t *memory, uint32 size, void **buf)
{
uint32 align_size = CM_ALIGN8(size);
if (align_size > memory->pool->page_size) {
OG_THROW_ERROR(ERR_ALLOC_MEMORY, (uint64)size, "context memory");
return OG_ERROR;
}
while (!mctx_try_alloc(memory, size, buf)) {
if (!ogx_recycle(pool)) {
return OG_ERROR;
}
}
if (size != 0) {
MEMS_RETURN_IFERR(memset_sp(*buf, (size_t)size, 0, (size_t)size));
}
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
test_memory_pool_maps(pool->memory);
#endif
return OG_SUCCESS;
}
context_ctrl_t *ogx_get(context_pool_t *pool, uint32 id)
{
if (pool->map->items[id] >= 0x80000000 || id >= pool->map->hwm) {
return NULL;
}
char *page_addr = mpool_page_addr(pool->memory, pool->map->items[id]);
return (context_ctrl_t *)(page_addr + sizeof(memory_context_t));
}
* flush all sql context in shared pool
*/
void ogx_flush_shared_pool(context_pool_t *pool)
{
* shouldn't lock pool->lock, otherwise
* one sql thread may lock bucket->parsing_lock, then pool->lock (context recycle to realloc)
* flush shared pool thread lock pool->lock, then bucket->parsing_lock
* A-B B-A deadlock
*/
for (uint32 i = 0; i < OG_SQL_BUCKETS; i++) {
context_bucket_t *bucket = &pool->buckets[i];
context_ctrl_t *ctrl = NULL;
cm_spin_lock(&bucket->parsing_lock.mutex, NULL);
cm_spin_lock(&bucket->enque_lock, NULL);
ctrl = bucket->first;
while (ctrl != NULL) {
ctrl->fixed = OG_FALSE;
ctrl->valid = OG_FALSE;
ctrl = ctrl->hash_next;
}
cm_spin_unlock(&bucket->enque_lock);
cm_spin_unlock(&bucket->parsing_lock.mutex);
}
}
uint32 ogx_pool_get_lru_cnt(context_pool_t *pool)
{
uint32 lru_cnt = 0;
for (uint32 i = 0; i < pool->lru_list_cnt; i++) {
lru_cnt += pool->lru_list[i].lru_count;
}
return lru_cnt;
}