/** * Copyright (c) 2021 OceanBase * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * 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 PubL v2 for more details. */ #include "lib/allocator/ob_malloc.h" #include #include "lib/thread_local/ob_tsi_factory.h" #include "lib/utility/utility.h" #include #include "obutils/ob_proxy_config.h" #ifdef __OB_MTRACE__ #include #endif oceanbase::common::ObMemAttr oceanbase::common::default_memattr; int oceanbase::common::ObMemBuf::ensure_space(const int64_t size, const int64_t mod_id) { int ret = OB_SUCCESS; char *new_buf = NULL; int64_t buf_len = size > buf_size_ ? size : buf_size_; if (size <= 0 || (NULL != buf_ptr_ && buf_size_ <= 0)) { _OB_LOG(WARN, "invalid param, size=%ld, buf_ptr_=%p, " "buf_size_=%ld", size, buf_ptr_, buf_size_); ret = OB_ERROR; } else if (NULL == buf_ptr_ || (NULL != buf_ptr_ && size > buf_size_)) { new_buf = static_cast(ob_malloc(buf_len, mod_id)); if (NULL == new_buf) { _OB_LOG(ERROR, "Problem allocate memory for buffer"); ret = OB_ERROR; } else { if (NULL != buf_ptr_) { ob_free(buf_ptr_); buf_ptr_ = NULL; } buf_size_ = buf_len; buf_ptr_ = new_buf; mod_id_ = mod_id; } } return ret; } void *oceanbase::common::ob_malloc_align(const int64_t alignment, const int64_t nbyte, const int64_t mod_id) { char *ptr = static_cast(oceanbase::common::ob_malloc(nbyte + alignment, mod_id)); char *align_ptr = NULL; if (NULL != ptr) { align_ptr = reinterpret_cast(oceanbase::common::upper_align(reinterpret_cast(ptr), alignment)); if (align_ptr == ptr) { align_ptr = ptr + alignment; } int64_t padding = align_ptr - ptr; if (!(padding <= alignment && padding > 0)) { _OB_LOG(ERROR, "invalid padding(padding=%ld, alignment=%ld", padding, alignment); } uint8_t *sign_ptr = reinterpret_cast(align_ptr - 1); int64_t *header_ptr = reinterpret_cast(align_ptr - 1 - sizeof(int64_t)); if (padding < (int64_t)sizeof(int64_t) + 1) { *sign_ptr = static_cast(padding) & 0x7f; } else { *sign_ptr = 0x80; *header_ptr = padding; } } else { _OB_LOG(WARN, "ob_tc_malloc allocate memory failed, alignment[%ld], nbyte[%ld], mod[%ld].", alignment, nbyte, mod_id); } return align_ptr; } void *oceanbase::common::ob_malloc_align(const int64_t alignment, const int64_t nbyte, const ObMemAttr &attr) { char *ptr = static_cast(oceanbase::common::ob_malloc(nbyte + alignment, attr)); char *align_ptr = NULL; if (NULL != ptr) { align_ptr = reinterpret_cast(oceanbase::common::upper_align(reinterpret_cast(ptr), alignment)); if (align_ptr == ptr) { align_ptr = ptr + alignment; } int64_t padding = align_ptr - ptr; if (!(padding <= alignment && padding > 0)) { _OB_LOG(ERROR, "invalid padding(padding=%ld, alignment=%ld", padding, alignment); } uint8_t *sign_ptr = reinterpret_cast(align_ptr - 1); int64_t *header_ptr = reinterpret_cast(align_ptr - 1 - sizeof(int64_t)); if (padding < (int64_t)sizeof(int64_t) + 1) { *sign_ptr = static_cast(padding) & 0x7f; } else { *sign_ptr = 0x80; *header_ptr = padding; } } else { _OB_LOG(WARN, "ob_tc_malloc allocate memory failed, alignment[%ld], nbyte[%ld], tenant_id[%lu], mod[%ld].", alignment, nbyte, attr.tenant_id_, attr.mod_id_); } return align_ptr; } void oceanbase::common::ob_free_align(void *ptr) { if (NULL == ptr) { _OB_LOG(WARN, "cannot free NULL pointer."); } else { uint8_t *sign_ptr = reinterpret_cast(static_cast(ptr) - 1); int64_t *header_ptr = reinterpret_cast(static_cast(ptr) - 1 - sizeof(int64_t)); char *origin_ptr = NULL; if (NULL != sign_ptr) { if (*sign_ptr & 0x80) { origin_ptr = reinterpret_cast(ptr) - (*header_ptr); } else { origin_ptr = reinterpret_cast(ptr) - (*sign_ptr & 0x7f); } if (NULL != origin_ptr) { oceanbase::common::ob_free(origin_ptr); } } } }