[CP] optimize common_realloc

This commit is contained in:
tushicheng 2024-05-24 05:13:16 +00:00 committed by ob-robot
parent af23b4004c
commit a50f6b5bdd
8 changed files with 86 additions and 92 deletions

View File

@ -14,6 +14,7 @@
#define _OCEABASE_COMMON_OB_COMMON_UTILITY_H_
#include <sys/time.h>
#include "lib/ob_define.h"
#include "lib/time/ob_tsc_timestamp.h"
namespace oceanbase
{
namespace common
@ -57,11 +58,7 @@ private:
inline int64_t get_cur_ts()
{
struct timeval tv;
gettimeofday(&tv, NULL);
const int64_t us =
static_cast<int64_t>(tv.tv_sec) * static_cast<int64_t>(1000000) + static_cast<int64_t>(tv.tv_usec);
return us;
return OB_TSC_TIMESTAMP.fast_current_time();
}
class ObBasicTimeGuard

View File

@ -16,7 +16,6 @@
#include "lib/allocator/ob_tc_malloc.h"
#include "lib/ob_define.h"
#include "lib/alloc/ob_tenant_ctx_allocator.h"
#include "lib/alloc/ob_malloc_callback.h"
using namespace oceanbase;
using namespace oceanbase::lib;
@ -92,12 +91,6 @@ ABlock *BlockSet::alloc_block(const uint64_t size, const ObMemAttr &attr)
uint64_t payload = 0;
block->hold(&payload);
UNUSED(ATOMIC_FAA(&total_used_, payload));
if (OB_NOT_NULL(malloc_callback)) {
(*malloc_callback)(attr, size);
for (auto *p = malloc_callback->next(); p != malloc_callback; p = p->next()) {
(*p)(attr, size);
}
}
}
return block;
@ -117,12 +110,6 @@ void BlockSet::free_block(ABlock *const block)
if (!!block->is_large_) {
free_chunk(chunk);
} else {
if (OB_NOT_NULL(malloc_callback)) {
(*malloc_callback)(attr_, -block->alloc_bytes_);
for (auto *p = malloc_callback->next(); p != malloc_callback; p = p->next()) {
(*p)(attr_, -block->alloc_bytes_);
}
}
ABlock *prev_block = NULL;
ABlock *next_block = NULL;

View File

@ -20,6 +20,7 @@
#include "lib/utility/ob_print_utils.h"
#include "lib/alloc/memory_dump.h"
#include "lib/alloc/memory_sanity.h"
#include "lib/alloc/ob_malloc_callback.h"
#include "lib/oblog/ob_log.h"
#include "common/ob_smart_var.h"
#include "rpc/obrpc/ob_rpc_packet.h"
@ -401,6 +402,66 @@ void ObTenantCtxAllocator::update_wash_stat(int64_t related_chunks, int64_t bloc
(void)ATOMIC_FAA(&washed_size_, size);
}
void ObTenantCtxAllocator::on_alloc(AObject& obj, const ObMemAttr& attr)
{
if (attr.label_.str_ != nullptr) {
STRNCPY(obj.label_, attr.label_.str_, sizeof(obj.label_));
obj.label_[sizeof(obj.label_) - 1] = '\0';
} else {
MEMSET(obj.label_, '\0', sizeof(obj.label_));
}
if (attr.alloc_extra_info_) {
void *addrs[100] = {nullptr};
ob_backtrace(addrs, ARRAYSIZEOF(addrs));
STATIC_ASSERT(AOBJECT_BACKTRACE_SIZE < sizeof(addrs), "AOBJECT_BACKTRACE_SIZE must be less than addrs!");
MEMCPY(obj.bt(), (char*)addrs, AOBJECT_BACKTRACE_SIZE);
obj.on_malloc_sample_ = true;
}
obj.ignore_version_ = attr.ignore_version() || ObMemVersionNode::tl_ignore_node;
if (!obj.ignore_version_) {
obj.version_ = ObMemVersionNode::tl_node->version_;
}
get_mem_leak_checker().on_alloc(obj, attr);
SANITY_POISON(&obj, obj.nobjs_ * AOBJECT_CELL_BYTES);
SANITY_UNPOISON(obj.data_, obj.alloc_bytes_);
if (OB_NOT_NULL(malloc_callback)) {
const int64_t size = obj.alloc_bytes_;
(*malloc_callback)(attr, size);
for (auto *p = malloc_callback->next(); p != malloc_callback; p = p->next()) {
(*p)(attr, size);
}
}
}
void ObTenantCtxAllocator::on_free(AObject &obj)
{
abort_unless(obj.is_valid());
abort_unless(obj.in_use_);
ABlock *block = obj.block();
abort_unless(block->is_valid());
abort_unless(block->in_use_);
abort_unless(NULL != block->obj_set_);
SANITY_POISON(obj.data_, obj.alloc_bytes_);
get_mem_leak_checker().on_free(obj);
IBlockMgr *blk_mgr = block->obj_set_->get_block_mgr();
abort_unless(NULL != blk_mgr);
int64_t tenant_id = blk_mgr->get_tenant_id();
int64_t ctx_id = blk_mgr->get_ctx_id();
ObMemAttr attr(tenant_id, obj.label_, ctx_id);
if (OB_NOT_NULL(malloc_callback)) {
const int64_t size = obj.alloc_bytes_;
(*malloc_callback)(attr, -size);
for (auto *p = malloc_callback->next(); p != malloc_callback; p = p->next()) {
(*p)(attr, -size);
}
}
}
template <typename T>
void* ObTenantCtxAllocator::common_realloc(const void *ptr, const int64_t size,
const ObMemAttr &attr, ObTenantCtxAllocator& ta,
@ -417,12 +478,7 @@ void* ObTenantCtxAllocator::common_realloc(const void *ptr, const int64_t size,
bool is_errsim = false;
if (NULL != ptr) {
obj = reinterpret_cast<AObject*>((char*)ptr - AOBJECT_HEADER_SIZE);
abort_unless(obj->is_valid());
abort_unless(obj->in_use_);
abort_unless(obj->block()->is_valid());
abort_unless(obj->block()->in_use_);
SANITY_POISON(obj->data_, obj->alloc_bytes_);
get_mem_leak_checker().on_free(*obj);
on_free(*obj);
}
#ifdef ERRSIM
@ -459,27 +515,8 @@ void* ObTenantCtxAllocator::common_realloc(const void *ptr, const int64_t size,
}
if (obj != NULL) {
if (inner_attr.label_.str_ != nullptr) {
STRNCPY(obj->label_, inner_attr.label_.str_, sizeof(obj->label_));
obj->label_[sizeof(obj->label_) - 1] = '\0';
} else {
MEMSET(obj->label_, '\0', sizeof(obj->label_));
}
if (sample_allowed) {
void *addrs[100] = {nullptr};
ob_backtrace(addrs, ARRAYSIZEOF(addrs));
STATIC_ASSERT(AOBJECT_BACKTRACE_SIZE < sizeof(addrs), "AOBJECT_BACKTRACE_SIZE must be less than addrs!");
MEMCPY(obj->bt(), (char*)addrs, AOBJECT_BACKTRACE_SIZE);
obj->on_malloc_sample_ = true;
}
obj->ignore_version_ = inner_attr.ignore_version() || ObMemVersionNode::tl_ignore_node;
if (!obj->ignore_version_) {
obj->version_ = ObMemVersionNode::tl_node->version_;
}
on_alloc(*obj, inner_attr);
nptr = obj->data_;
get_mem_leak_checker().on_alloc(*obj, inner_attr);
SANITY_POISON(obj, obj->nobjs_ * AOBJECT_CELL_BYTES);
SANITY_UNPOISON(obj->data_, size);
} else if (TC_REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
#ifdef FATAL_ERROR_HANG
if (g_alloc_failed_ctx().reach_limit_except_ctx() &&
@ -506,22 +543,8 @@ void ObTenantCtxAllocator::common_free(void *ptr)
SANITY_DISABLE_CHECK_RANGE(); // prevent sanity_check_range
if (NULL != ptr) {
AObject *obj = reinterpret_cast<AObject*>((char*)ptr - AOBJECT_HEADER_SIZE);
abort_unless(NULL != obj);
abort_unless(obj->MAGIC_CODE_ == AOBJECT_MAGIC_CODE
|| obj->MAGIC_CODE_ == BIG_AOBJECT_MAGIC_CODE);
abort_unless(obj->in_use_);
SANITY_POISON(obj->data_, obj->alloc_bytes_);
get_mem_leak_checker().on_free(*obj);
AChunk *chunk = AChunk::ptr2chunk(obj);
abort_unless(chunk->is_valid());
ABlock *block = chunk->ptr2blk(obj);
abort_unless(block);
abort_unless(block->is_valid());
abort_unless(block->in_use_);
abort_unless(block->obj_set_ != NULL);
ObjectSet *os = block->obj_set_;
on_free(*obj);
ObjectSet *os = obj->block()->obj_set_;
os->free_object(obj);
}
}

View File

@ -298,6 +298,9 @@ private:
}
return ret;
}
private:
static void on_alloc(AObject& obj, const ObMemAttr& attr);
static void on_free(AObject& obj);
public:
template <typename T>
static void* common_realloc(const void *ptr, const int64_t size,

View File

@ -936,7 +936,8 @@ void ObLogger::log_it(const char *mod_name,
int64_t buf_len = tb->get_cap();
int64_t &pos = tb->get_pos();
int64_t orig_pos = pos;
ret = log_head(get_cur_ts(), mod_name, level, file, line, function, errcode, buf, buf_len, pos);
int64_t ts = OB_TSC_TIMESTAMP.current_time();
ret = log_head(ts, mod_name, level, file, line, function, errcode, buf, buf_len, pos);
if (OB_SUCC(ret)) {
ret = log_data_func(buf, buf_len, pos);
}
@ -1156,6 +1157,7 @@ inline void ObLogger::do_log_message(const bool is_async,
const int64_t log_size = limited_left_log_size_ + NORMAL_LOG_SIZE;
limited_left_log_size_ = 0;
BASIC_TIME_GUARD(tg, "ObLog");
int64_t start_ts = OB_TSC_TIMESTAMP.current_time();
if (FD_TRACE_FILE != fd_type && OB_FAIL(check_tl_log_limiter(location_hash_val, level, errcode, log_size,
allow, limiter_info))) {
LOG_STDERR("precheck_tl_log_limiter error, ret=%d\n", ret);
@ -1167,7 +1169,7 @@ inline void ObLogger::do_log_message(const bool is_async,
ObPLogItem *log_item = new (local_buf_) ObPLogItem();
log_item->set_buf_size(MAX_LOG_SIZE);
log_item->set_log_level(level);
log_item->set_timestamp(tg.get_start_ts());
log_item->set_timestamp(start_ts);
log_item->set_tl_type(tl_type_);
log_item->set_force_allow(is_force_allows());
log_item->set_fd_type(fd_type);
@ -1176,7 +1178,7 @@ inline void ObLogger::do_log_message(const bool is_async,
int64_t buf_len = log_item->get_buf_size();
int64_t pos = log_item->get_data_len();
if (with_head) {
if (OB_FAIL(log_head(tg.get_start_ts(), mod_name, level, file, line, function, errcode,
if (OB_FAIL(log_head(start_ts, mod_name, level, file, line, function, errcode,
buf, buf_len, pos))) {
LOG_STDERR("log_header error ret = %d\n", ret);
}
@ -1272,7 +1274,7 @@ _Pragma("GCC diagnostic pop")
const int64_t buf_len = sizeof buf;
int64_t pos = 0;
int tmp_ret = OB_SUCCESS;
if (OB_TMP_FAIL(log_head(tg.get_start_ts(), mod_name, OB_LOG_LEVEL_ERROR, file, line, function,
if (OB_TMP_FAIL(log_head(start_ts, mod_name, OB_LOG_LEVEL_ERROR, file, line, function,
errcode, buf, buf_len, pos))) {
} else if (OB_TMP_FAIL(logdata_printf(buf, buf_len, pos,
"LOGGER COST TOO MUCH TIME, cost: %ld, ", cost_time))) {

View File

@ -76,35 +76,19 @@ int64_t ObTscTimestamp::current_time()
return (static_cast<int64_t>(tv.tv_sec) * static_cast<int64_t>(1000000) + static_cast<int64_t>(tv.tv_usec));
}
int64_t ObTscTimestamp::current_monotonic_time()
int64_t ObTscTimestamp::fast_current_time()
{
int ret = OB_SUCCESS;
int64_t result_time = 0;
if (OB_UNLIKELY(!is_init_)) {
// init failed, use system call.
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
ret = OB_ERR_UNEXPECTED;
LIB_LOG(WARN, "sys gettimeofday unexpected", K(ret));
}
result_time = (static_cast<int64_t>(tv.tv_sec) * static_cast<int64_t>(1000000) + static_cast<int64_t>(tv.tv_usec));
result_time = current_time();
} else {
uint64_t cpuid = 0;
const uint64_t current_tsc = rdtscp_id(cpuid);
if (base_per_cpu_[cpuid].is_valid()) {
const int64_t tsc_count = base_per_cpu_[cpuid].tsc_count_;
const int64_t start_us = base_per_cpu_[cpuid].start_us_;
result_time = ((current_tsc - tsc_count) * scale_ >> 20) + start_us;
} else {
ObTscBase cur_base;
cur_base.init(current_tsc);
base_per_cpu_[cpuid] = cur_base;
result_time = cur_base.start_us_;
}
const uint64_t current_tsc = rdtsc();
result_time = current_tsc * scale_ >> 20;
}
return result_time;
}
#if defined(__x86_64__)
uint64_t ObTscTimestamp::get_cpufreq_khz_()
{

View File

@ -126,7 +126,7 @@ public:
~ObTscTimestamp() {}
int init();
int64_t current_time();
int64_t current_monotonic_time();
int64_t fast_current_time();
static ObTscTimestamp &get_instance()
{
@ -162,8 +162,6 @@ private:
uint64_t tsc_count_;
// cycles2ns scale
uint64_t scale_;
// for monotonic tsc
ObTscBase base_per_cpu_[MAX_CPU_COUNT];
};
}//common

View File

@ -44,7 +44,7 @@ TEST_F(TestObMallocCallbackGuard, AllocAndFree)
ObMallocCallbackGuard guard(cb);
auto *ptr = ob_malloc(2113, ObNewModIds::TEST);
std::cout << "alloc" << std::endl;
ASSERT_EQ(hold, 8192);
ASSERT_EQ(hold, 2113);
ob_free(ptr);
std::cout << "free" << std::endl << std::endl;
ASSERT_EQ(hold, 0);
@ -53,8 +53,8 @@ TEST_F(TestObMallocCallbackGuard, AllocAndFree)
MallocCallback cb(hold2);
ObMallocCallbackGuard guard(cb);
auto *ptr = ob_malloc(2113, ObNewModIds::TEST);
ASSERT_EQ(hold, 8192);
ASSERT_EQ(hold2, 8192);
ASSERT_EQ(hold, 2113);
ASSERT_EQ(hold2, 2113);
std::cout << "alloc" << std::endl;
ob_free(ptr);
ASSERT_EQ(hold, 0);
@ -62,7 +62,7 @@ TEST_F(TestObMallocCallbackGuard, AllocAndFree)
std::cout << "free" << std::endl << std::endl;
}
ptr = ob_malloc(2113, ObNewModIds::TEST);
ASSERT_EQ(hold, 8192);
ASSERT_EQ(hold, 2113);
std::cout << "alloc" << std::endl;
ob_free(ptr);
std::cout << "free" << std::endl;