patch 4.0
This commit is contained in:
360
deps/oblib/src/lib/allocator/ob_slice_alloc.h
vendored
360
deps/oblib/src/lib/allocator/ob_slice_alloc.h
vendored
@ -19,58 +19,49 @@
|
||||
#include "lib/allocator/ob_qsync.h"
|
||||
#include "lib/utility/ob_print_utils.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
extern ObBlockAllocMgr default_blk_alloc;
|
||||
|
||||
class ObSimpleSync {
|
||||
class ObSimpleSync
|
||||
{
|
||||
public:
|
||||
ObSimpleSync() : ref_(0)
|
||||
{}
|
||||
int32_t ref(int32_t x)
|
||||
{
|
||||
return ATOMIC_AAF(&ref_, x);
|
||||
}
|
||||
void sync()
|
||||
{
|
||||
while (ATOMIC_LOAD(&ref_) > 0) {
|
||||
ObSimpleSync(): ref_(0) {}
|
||||
int32_t ref(int32_t x) { return ATOMIC_AAF(&ref_, x); }
|
||||
void sync() {
|
||||
while(ATOMIC_LOAD(&ref_) > 0) {
|
||||
PAUSE();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t ref_;
|
||||
};
|
||||
|
||||
class ObDListWithLock {
|
||||
class ObDListWithLock
|
||||
{
|
||||
public:
|
||||
typedef ObDLink DLink;
|
||||
ObDListWithLock() : lock_()
|
||||
{
|
||||
ObDListWithLock(): lock_() {
|
||||
head_.next_ = &head_;
|
||||
head_.prev_ = &head_;
|
||||
}
|
||||
~ObDListWithLock()
|
||||
{}
|
||||
void add(DLink* p)
|
||||
{
|
||||
~ObDListWithLock() {}
|
||||
void add(DLink* p) {
|
||||
lib::ObLockGuard<common::ObSpinLock> guard(lock_);
|
||||
add_(p);
|
||||
}
|
||||
void del(DLink* p)
|
||||
{
|
||||
void del(DLink* p) {
|
||||
lib::ObLockGuard<common::ObSpinLock> guard(lock_);
|
||||
del_(p);
|
||||
}
|
||||
DLink* top()
|
||||
{
|
||||
DLink* top() {
|
||||
DLink* p = (DLink*)ATOMIC_LOAD(&head_.next_);
|
||||
return &head_ == p ? NULL : p;
|
||||
return &head_ == p? NULL: p;
|
||||
}
|
||||
|
||||
private:
|
||||
void add_(DLink* p)
|
||||
{
|
||||
void add_(DLink* p) {
|
||||
DLink* prev = head_.prev_;
|
||||
DLink* next = &head_;
|
||||
p->prev_ = prev;
|
||||
@ -78,44 +69,42 @@ private:
|
||||
prev->next_ = p;
|
||||
next->prev_ = p;
|
||||
}
|
||||
void del_(DLink* p)
|
||||
{
|
||||
void del_(DLink* p) {
|
||||
DLink* prev = p->prev_;
|
||||
DLink* next = (DLink*)p->next_;
|
||||
prev->next_ = next;
|
||||
next->prev_ = prev;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable common::ObSpinLock lock_;
|
||||
DLink head_ CACHE_ALIGNED;
|
||||
};
|
||||
|
||||
class ObEmbedFixedQueue {
|
||||
class ObEmbedFixedQueue
|
||||
{
|
||||
public:
|
||||
ObEmbedFixedQueue(): push_(0), pop_(0), capacity_(0) {}
|
||||
ObEmbedFixedQueue(): push_(0), pop_(0), capacity_(0) {
|
||||
init(0);
|
||||
}
|
||||
~ObEmbedFixedQueue() {}
|
||||
void init(uint64_t capacity) {
|
||||
capacity_ = capacity;
|
||||
memset(data_, 0, sizeof(void*) * capacity);
|
||||
}
|
||||
void push(void* p)
|
||||
{
|
||||
void push(void* p) {
|
||||
void** addr = data_ + ATOMIC_FAA(&push_, 1) % capacity_;
|
||||
while (!ATOMIC_BCAS(addr, NULL, p)) {
|
||||
while(!ATOMIC_BCAS(addr, NULL, p)) {
|
||||
PAUSE();
|
||||
}
|
||||
}
|
||||
void* pop()
|
||||
{
|
||||
void* pop() {
|
||||
void* p = NULL;
|
||||
void** addr = data_ + ATOMIC_FAA(&pop_, 1) % capacity_;
|
||||
while (NULL == (p = ATOMIC_TAS(addr, NULL))) {
|
||||
while(NULL == (p = ATOMIC_TAS(addr, NULL))) {
|
||||
PAUSE();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t push_ CACHE_ALIGNED;
|
||||
uint64_t pop_ CACHE_ALIGNED;
|
||||
@ -128,133 +117,104 @@ private:
|
||||
acquire release recycle
|
||||
1. shared block must be linked in list
|
||||
2. private block can be used for alloc, or can be destroyed.
|
||||
3. flying block is a transient, difference with private state is that private block has no chance to trigger link to
|
||||
list.
|
||||
3. flying block is a transient, difference with private state is that private block has no chance to trigger link to list.
|
||||
*/
|
||||
class ObStockCtrl {
|
||||
class ObStockCtrl
|
||||
{
|
||||
public:
|
||||
enum { K = INT32_MAX / 2 };
|
||||
ObStockCtrl() : total_(0), stock_(0)
|
||||
{}
|
||||
~ObStockCtrl()
|
||||
{}
|
||||
void init_stock(int32_t n)
|
||||
{
|
||||
enum { K = INT32_MAX/2 };
|
||||
ObStockCtrl(): total_(0), stock_(0) {}
|
||||
~ObStockCtrl() {}
|
||||
void init_stock(int32_t n) {
|
||||
total_ = n;
|
||||
stock_ = n;
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t total()
|
||||
{
|
||||
return total_;
|
||||
}
|
||||
bool acquire()
|
||||
{
|
||||
return dec_if_gt(K, K) > K;
|
||||
}
|
||||
bool release()
|
||||
{
|
||||
return faa(-K) > 0;
|
||||
}
|
||||
bool recyle()
|
||||
{
|
||||
uint32_t total() { return total_; }
|
||||
bool acquire() { return dec_if_gt(K, K) > K; }
|
||||
bool release() { return faa(-K) > 0; }
|
||||
bool recyle() {
|
||||
int32_t total = total_;
|
||||
return inc_if_lt(2 * K, -K + total) == -K + total;
|
||||
return inc_if_lt(2 * K, -K + total) == -K + total;
|
||||
}
|
||||
bool alloc_stock()
|
||||
{
|
||||
return dec_if_gt(1, 0) > 0;
|
||||
}
|
||||
bool free_stock(bool& first_free)
|
||||
{
|
||||
bool alloc_stock() { return dec_if_gt(1, 0) > 0; }
|
||||
bool free_stock(bool& first_free) {
|
||||
int32_t total = total_;
|
||||
int32_t ov = cas_or_inc(K + total - 1, -K + total, 1);
|
||||
first_free = (ov == -K);
|
||||
return ov == K + total - 1;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t faa(int32_t x)
|
||||
{
|
||||
return ATOMIC_FAA(&stock_, x);
|
||||
}
|
||||
int32_t aaf(int32_t x)
|
||||
{
|
||||
return ATOMIC_AAF(&stock_, x);
|
||||
}
|
||||
int32_t dec_if_gt(int32_t x, int32_t b)
|
||||
{
|
||||
int32_t faa(int32_t x) { return ATOMIC_FAA(&stock_, x); }
|
||||
int32_t aaf(int32_t x) { return ATOMIC_AAF(&stock_, x); }
|
||||
int32_t dec_if_gt(int32_t x, int32_t b) {
|
||||
int32_t ov = ATOMIC_LOAD(&stock_);
|
||||
int32_t nv = 0;
|
||||
while (ov > b && ov != (nv = ATOMIC_VCAS(&stock_, ov, ov - x))) {
|
||||
while(ov > b && ov != (nv = ATOMIC_VCAS(&stock_, ov, ov - x))) {
|
||||
ov = nv;
|
||||
}
|
||||
return ov;
|
||||
}
|
||||
int32_t inc_if_lt(int32_t x, int32_t b)
|
||||
{
|
||||
int32_t inc_if_lt(int32_t x, int32_t b) {
|
||||
int32_t ov = ATOMIC_LOAD(&stock_);
|
||||
int32_t nv = 0;
|
||||
while (ov < b && ov != (nv = ATOMIC_VCAS(&stock_, ov, ov + x))) {
|
||||
while(ov < b && ov != (nv = ATOMIC_VCAS(&stock_, ov, ov + x))) {
|
||||
ov = nv;
|
||||
}
|
||||
return ov;
|
||||
}
|
||||
int32_t cas_or_inc(int32_t cmp, int32_t val, int32_t x)
|
||||
{
|
||||
int32_t cas_or_inc(int32_t cmp, int32_t val, int32_t x) {
|
||||
int32_t ov = ATOMIC_LOAD(&stock_);
|
||||
int32_t nv = 0;
|
||||
while (
|
||||
(cmp == ov) ? (ov != (nv = ATOMIC_VCAS(&stock_, cmp, val))) : (ov != (nv = ATOMIC_VCAS(&stock_, ov, ov + x)))) {
|
||||
while((cmp == ov)
|
||||
? (ov != (nv = ATOMIC_VCAS(&stock_, cmp, val)))
|
||||
: (ov != (nv = ATOMIC_VCAS(&stock_, ov, ov + x)))) {
|
||||
ov = nv;
|
||||
}
|
||||
return ov;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t total_ CACHE_ALIGNED;
|
||||
int32_t stock_ CACHE_ALIGNED;
|
||||
};
|
||||
|
||||
class ObBlockSlicer : public ObStockCtrl {
|
||||
class ObSliceAlloc;
|
||||
class ObBlockSlicer: public ObStockCtrl
|
||||
{
|
||||
public:
|
||||
static const uint32_t ITEM_MAGIC_CODE = 0XCCEEDDF1;
|
||||
static const uint32_t ITEM_MAGIC_CODE_MASK = 0XFFFFFFF0;
|
||||
typedef ObEmbedFixedQueue FList;
|
||||
typedef ObBlockSlicer Host;
|
||||
struct Item {
|
||||
struct Item
|
||||
{
|
||||
public:
|
||||
Item(Host* host) : host_(host)
|
||||
{}
|
||||
~Item()
|
||||
{}
|
||||
Item(Host* host): MAGIC_CODE_(ITEM_MAGIC_CODE), host_(host) {}
|
||||
~Item(){}
|
||||
uint32_t MAGIC_CODE_;
|
||||
ObBlockSlicer* host_;
|
||||
} __attribute__((aligned(16)));
|
||||
;
|
||||
|
||||
} __attribute__((aligned (16)));;
|
||||
public:
|
||||
ObDLink dlink_ CACHE_ALIGNED;
|
||||
|
||||
public:
|
||||
ObBlockSlicer(int32_t limit, int32_t slice_size, void* tmallocator = NULL) : tmallocator_(tmallocator)
|
||||
{
|
||||
ObBlockSlicer(int32_t limit, int32_t slice_size, ObSliceAlloc* slice_alloc, void* tmallocator = NULL)
|
||||
: slice_alloc_(slice_alloc), tmallocator_(tmallocator) {
|
||||
int64_t isize = lib::align_up2((int32_t)sizeof(Item) + slice_size, 16);
|
||||
int64_t total = (limit - (int32_t)sizeof(*this)) / (isize + (int32_t)sizeof(void*));
|
||||
int64_t total = (limit - (int32_t)sizeof(*this))/(isize + (int32_t)sizeof(void*));
|
||||
char* istart = (char*)lib::align_up2((uint64_t)((char*)(this + 1) + sizeof(void*) * total), 16);
|
||||
if (istart + isize * total > ((char*)this) + limit) {
|
||||
total--;
|
||||
}
|
||||
flist_.init((int32_t)total);
|
||||
for (int32_t i = 0; i < total; i++) {
|
||||
flist_.push((void*)new (istart + i * isize) Item(this));
|
||||
for(int32_t i = 0; i < total; i++) {
|
||||
flist_.push((void*)new(istart + i * isize)Item(this));
|
||||
}
|
||||
init_stock((int32_t)total);
|
||||
hash_ = cal_hash_((uint64_t)this);
|
||||
}
|
||||
~ObBlockSlicer()
|
||||
{
|
||||
~ObBlockSlicer() {
|
||||
tmallocator_ = NULL;
|
||||
}
|
||||
uint64_t cal_hash_(uint64_t h)
|
||||
static uint64_t hash(uint64_t h)
|
||||
{
|
||||
h ^= h >> 33;
|
||||
h *= 0xff51afd7ed558ccd;
|
||||
@ -263,102 +223,81 @@ public:
|
||||
h ^= h >> 33;
|
||||
return h;
|
||||
}
|
||||
Item* alloc_item()
|
||||
{
|
||||
return alloc_stock() ? (Item*)flist_.pop() : NULL;
|
||||
Item* alloc_item() {
|
||||
Item* ret = NULL;
|
||||
ret = alloc_stock()? (Item*)flist_.pop(): NULL;
|
||||
if (NULL != ret) {
|
||||
ret->MAGIC_CODE_ = ITEM_MAGIC_CODE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool free_item(Item* p, bool& first_free)
|
||||
{
|
||||
bool free_item(Item* p, bool& first_free) {
|
||||
flist_.push(p);
|
||||
return free_stock(first_free);
|
||||
}
|
||||
uint64_t hash() const
|
||||
{
|
||||
return hash_;
|
||||
}
|
||||
void* get_tmallocator()
|
||||
{
|
||||
return tmallocator_;
|
||||
}
|
||||
|
||||
void* get_tmallocator() { return tmallocator_; }
|
||||
void* get_slice_alloc() { return slice_alloc_; }
|
||||
private:
|
||||
uint64_t hash_;
|
||||
ObSliceAlloc* slice_alloc_;
|
||||
void* tmallocator_;
|
||||
FList flist_ CACHE_ALIGNED;
|
||||
};
|
||||
|
||||
class ObSliceAlloc {
|
||||
class ObSliceAlloc
|
||||
{
|
||||
public:
|
||||
enum { MAX_ARENA_NUM = 32, MAX_REF_NUM = 4096, DEFAULT_BLOCK_SIZE = OB_MALLOC_NORMAL_BLOCK_SIZE };
|
||||
typedef ObSimpleSync Sync;
|
||||
typedef ObBlockSlicer Block;
|
||||
typedef ObBlockAllocMgr BlockAlloc;
|
||||
typedef ObDListWithLock BlockList;
|
||||
class Arena {
|
||||
class Arena
|
||||
{
|
||||
public:
|
||||
Arena() : blk_(NULL)
|
||||
{}
|
||||
Block* blk()
|
||||
{
|
||||
return ATOMIC_LOAD(&blk_);
|
||||
}
|
||||
bool cas(Block* ov, Block* nv)
|
||||
{
|
||||
return ATOMIC_BCAS(&blk_, ov, nv);
|
||||
}
|
||||
Block* clear()
|
||||
{
|
||||
return ATOMIC_TAS(&blk_, NULL);
|
||||
}
|
||||
|
||||
Arena(): blk_(NULL) {}
|
||||
Block* blk() { return ATOMIC_LOAD(&blk_); }
|
||||
bool cas(Block* ov, Block* nv) { return ATOMIC_BCAS(&blk_, ov, nv); }
|
||||
Block* clear() { return ATOMIC_TAS(&blk_, NULL); }
|
||||
private:
|
||||
Block* blk_;
|
||||
} CACHE_ALIGNED;
|
||||
ObSliceAlloc() : nway_(0), bsize_(0), isize_(0), slice_limit_(0), blk_alloc_(default_blk_alloc), tmallocator_(NULL)
|
||||
{}
|
||||
ObSliceAlloc(const int size, const ObMemAttr& attr, int block_size = DEFAULT_BLOCK_SIZE,
|
||||
BlockAlloc& blk_alloc = default_blk_alloc, void* tmallocator = NULL)
|
||||
: nway_(1), bsize_(block_size), isize_(size), attr_(attr), blk_alloc_(blk_alloc), tmallocator_(tmallocator)
|
||||
{
|
||||
slice_limit_ = block_size - (int32_t)sizeof(Block) - (int32_t)sizeof(Block::Item);
|
||||
LIB_LOG(INFO, "ObSliceAlloc init finished", K(bsize_), K(isize_), K(slice_limit_), KP(tmallocator_));
|
||||
}
|
||||
~ObSliceAlloc()
|
||||
{
|
||||
ObSliceAlloc(): nway_(0), bsize_(0), isize_(0),
|
||||
slice_limit_(0), blk_alloc_(default_blk_alloc), tmallocator_(NULL) {}
|
||||
ObSliceAlloc(const int size, const ObMemAttr &attr, int block_size=DEFAULT_BLOCK_SIZE,
|
||||
BlockAlloc &blk_alloc = default_blk_alloc, void* tmallocator = NULL)
|
||||
: nway_(1), bsize_(block_size), isize_(size), attr_(attr),
|
||||
blk_alloc_(blk_alloc), tmallocator_(tmallocator) {
|
||||
slice_limit_ = block_size - (int32_t)sizeof(Block) - (int32_t)sizeof(Block::Item);
|
||||
LIB_LOG(INFO, "ObSliceAlloc init finished", K(bsize_), K(isize_), K(slice_limit_), KP(tmallocator_));
|
||||
}
|
||||
~ObSliceAlloc() {
|
||||
tmallocator_ = NULL;
|
||||
}
|
||||
int init(const int size, const int block_size, BlockAlloc& block_alloc, const ObMemAttr& attr)
|
||||
{
|
||||
int init(const int size, const int block_size, BlockAlloc& block_alloc, const ObMemAttr& attr) {
|
||||
int ret = common::OB_SUCCESS;
|
||||
new (this) ObSliceAlloc(size, attr, block_size, block_alloc, NULL);
|
||||
new(this)ObSliceAlloc(size, attr, block_size, block_alloc, NULL);
|
||||
return ret;
|
||||
}
|
||||
void set_nway(int nway)
|
||||
{
|
||||
void set_nway(int nway) {
|
||||
if (nway <= 0) {
|
||||
nway = 1;
|
||||
} else if (nway > MAX_ARENA_NUM) {
|
||||
nway = MAX_ARENA_NUM;
|
||||
}
|
||||
ATOMIC_STORE(&nway_, nway);
|
||||
ATOMIC_STORE(&nway_, nway);
|
||||
purge_extra_cached_block(nway);
|
||||
}
|
||||
void try_purge()
|
||||
{
|
||||
void try_purge() {
|
||||
if (NULL == blk_list_.top()) {
|
||||
purge_extra_cached_block(0);
|
||||
}
|
||||
}
|
||||
int64_t limit()
|
||||
{
|
||||
return blk_alloc_.limit();
|
||||
}
|
||||
int64_t hold()
|
||||
{
|
||||
return blk_alloc_.hold();
|
||||
}
|
||||
void* alloc()
|
||||
{
|
||||
int64_t limit() { return blk_alloc_.limit(); }
|
||||
int64_t hold() { return blk_alloc_.hold(); }
|
||||
void* alloc() {
|
||||
#ifdef OB_USE_ASAN
|
||||
return ::malloc(isize_);
|
||||
#else
|
||||
Block::Item* ret = NULL;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (isize_ > slice_limit_) {
|
||||
@ -368,7 +307,7 @@ public:
|
||||
LIB_LOG(ERROR, "slice size is larger than block size, unexpected !", K(tmp_ret), K(isize_), K(slice_limit_));
|
||||
}
|
||||
}
|
||||
while (NULL == ret && OB_SUCCESS == tmp_ret) {
|
||||
while(NULL == ret && OB_SUCCESS == tmp_ret) {
|
||||
Arena& arena = arena_[get_itid() % nway_];
|
||||
Block* blk = arena.blk();
|
||||
if (NULL == blk) {
|
||||
@ -383,7 +322,7 @@ public:
|
||||
}
|
||||
} else {
|
||||
Block* blk2release = NULL;
|
||||
int64_t slot_idx = blk->hash() % MAX_REF_NUM;
|
||||
int64_t slot_idx = ObBlockSlicer::hash((uint64_t)blk) % MAX_REF_NUM;
|
||||
blk_ref_[slot_idx].ref(1);
|
||||
if (blk == arena.blk()) {
|
||||
if (NULL == (ret = blk->alloc_item())) {
|
||||
@ -394,18 +333,31 @@ public:
|
||||
}
|
||||
blk_ref_[slot_idx].ref(-1);
|
||||
if (NULL != blk2release) {
|
||||
blk_ref_[blk2release->hash() % MAX_REF_NUM].sync();
|
||||
blk_ref_[ObBlockSlicer::hash((uint64_t)blk2release) % MAX_REF_NUM].sync();
|
||||
release_block(blk2release);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL == ret ? NULL : (void*)(ret + 1);
|
||||
return NULL == ret? NULL: (void*)(ret + 1);
|
||||
#endif
|
||||
}
|
||||
void free(void* p)
|
||||
{
|
||||
void free(void* p) {
|
||||
#ifdef OB_USE_ASAN
|
||||
::free(p);
|
||||
#else
|
||||
if (NULL != p) {
|
||||
Block::Item* item = (Block::Item*)p - 1;
|
||||
abort_unless(Block::ITEM_MAGIC_CODE == item->MAGIC_CODE_);
|
||||
Block* blk = item->host_;
|
||||
#ifndef NDEBUG
|
||||
abort_unless(blk->get_slice_alloc() == this);
|
||||
#else
|
||||
if (this != blk->get_slice_alloc()) {
|
||||
LIB_LOG(ERROR, "blk is freed or alloced by different slice_alloc", K(this), K(blk->get_slice_alloc()));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
item->MAGIC_CODE_ = item->MAGIC_CODE_ & Block::ITEM_MAGIC_CODE_MASK;
|
||||
bool first_free = false;
|
||||
bool need_destroy = blk->free_item(item, first_free);
|
||||
if (need_destroy) {
|
||||
@ -414,46 +366,36 @@ public:
|
||||
add_to_blist(blk);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void purge_extra_cached_block(int keep)
|
||||
{
|
||||
for (int i = MAX_ARENA_NUM - 1; i >= keep; i--) {
|
||||
void purge_extra_cached_block(int keep) {
|
||||
for(int i = MAX_ARENA_NUM - 1; i >= keep; i--) {
|
||||
Arena& arena = arena_[i];
|
||||
Block* old_blk = arena.clear();
|
||||
if (NULL != old_blk) {
|
||||
blk_ref_[old_blk->hash() % MAX_REF_NUM].sync();
|
||||
blk_ref_[ObBlockSlicer::hash((uint64_t)old_blk) % MAX_REF_NUM].sync();
|
||||
release_block(old_blk);
|
||||
}
|
||||
}
|
||||
}
|
||||
int64_t to_string(char* buf, const int64_t limit) const
|
||||
int64_t to_string(char *buf, const int64_t limit) const
|
||||
{
|
||||
return snprintf(buf,
|
||||
limit,
|
||||
"SliceAlloc: nway=%d bsize/isize=%d/%d limit=%d attr=%s",
|
||||
nway_,
|
||||
bsize_,
|
||||
isize_,
|
||||
slice_limit_,
|
||||
to_cstring(attr_));
|
||||
return snprintf(buf, limit, "SliceAlloc: nway=%d bsize/isize=%d/%d limit=%d attr=%s",
|
||||
nway_, bsize_, isize_, slice_limit_, to_cstring(attr_));
|
||||
}
|
||||
|
||||
private:
|
||||
void release_block(Block* blk)
|
||||
{
|
||||
void release_block(Block* blk) {
|
||||
if (blk->release()) {
|
||||
add_to_blist(blk);
|
||||
}
|
||||
}
|
||||
void add_to_blist(Block* blk)
|
||||
{
|
||||
void add_to_blist(Block* blk) {
|
||||
blk_list_.add(&blk->dlink_);
|
||||
if (blk->recyle()) {
|
||||
destroy_block(blk);
|
||||
}
|
||||
}
|
||||
Block* get_from_blist()
|
||||
{
|
||||
Block* get_from_blist() {
|
||||
Block* ret = NULL;
|
||||
ObDLink* dlink = NULL;
|
||||
do {
|
||||
@ -465,29 +407,27 @@ private:
|
||||
}
|
||||
}
|
||||
reclaim_sync_.ref(-1);
|
||||
} while (NULL == ret && dlink != NULL);
|
||||
} while(NULL == ret && dlink != NULL);
|
||||
if (NULL != ret) {
|
||||
blk_list_.del(&ret->dlink_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
Block* prepare_block()
|
||||
{
|
||||
Block* ret_blk = get_from_blist();
|
||||
Block* prepare_block() {
|
||||
Block *ret_blk = get_from_blist();
|
||||
if (NULL == ret_blk) {
|
||||
void* ptr = NULL;
|
||||
void *ptr = NULL;
|
||||
if (NULL != (ptr = blk_alloc_.alloc_block(bsize_, attr_))) {
|
||||
ret_blk = new (ptr) Block(bsize_, isize_, tmallocator_);
|
||||
ret_blk = new(ptr)Block(bsize_, isize_, this, tmallocator_);
|
||||
}
|
||||
}
|
||||
return ret_blk;
|
||||
}
|
||||
void destroy_block(Block* blk)
|
||||
{
|
||||
void destroy_block(Block* blk) {
|
||||
blk_list_.del(&blk->dlink_);
|
||||
reclaim_sync_.sync();
|
||||
blk_alloc_.free_block(blk, bsize_);
|
||||
// try_purge();
|
||||
//try_purge();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -500,9 +440,9 @@ protected:
|
||||
BlockList blk_list_ CACHE_ALIGNED;
|
||||
Arena arena_[MAX_ARENA_NUM];
|
||||
Sync blk_ref_[MAX_REF_NUM];
|
||||
BlockAlloc& blk_alloc_;
|
||||
BlockAlloc &blk_alloc_;
|
||||
void* tmallocator_;
|
||||
};
|
||||
}; // end namespace common
|
||||
}; // end namespace oceanbase
|
||||
}; // end namespace common
|
||||
}; // end namespace oceanbase
|
||||
#endif /* OCEANBASE_ALLOCATOR_OB_SLICE_ALLOC_H_ */
|
||||
|
||||
Reference in New Issue
Block a user