public void Set(RefCountPtr* ls, int cnt) { next = ls; count = cnt; }
public void SetValue(DataKey* src) { size = src->size; var rc = src->val_addr; val_addr = rc; if (rc != null) rc->AddRef(); }
public RefCountPtr* Pop() { var rc = next; if (rc != null) { next = rc->_list; rc->_data = 0; count--; } return rc; }
public void Push(RefCountPtr* bp) { bp->_list = next; next = bp; count++; }
private void ResetSlabs() { _cbuckets = 0; // hash bucket extra mem pages are returned to system on reset. if (_lpHash != null) { for (var ls = _lpHash; ls != null; ls = ls.next) ls.Release(); _lpHash = null; } if (_lpBase == null) _lpBase = new LargePage(_virtual_memory, 4); _htable = (HashBucket*)_lpBase.data; // init shared tables with clean values. for (var i = 0; i < _config.HashTableSize; i++) _htable[i] = new HashBucket(); var bp = (byte*)(_htable + _config.HashTableSize); _stabs = (int*)bp; // encoding slab max size and pos like -> 32 : 0 _stabs[0] = 0x200000; _stabs[1] = 0x400001; _slabs = (SlabList*)_align((byte*)(_stabs + 1 + (iLastSlabSize + SizeofRcp) / iQuantum)); // calculate slabs indexes and max sizes. int sbts = 64, scnt = 2, pos = scnt; for (var half = sbts / 2; sbts < iLastSlabSize; half = sbts / 2) { for (var es = sbts + half; sbts < es; sbts += iQuantum) _stabs[pos++] = scnt | (es << 16); scnt++; for (var es = sbts + half; sbts < es; sbts += iQuantum) _stabs[pos++] = scnt | (es << 16); scnt++; } _stabs[pos] = scnt; bp = _align((byte*)(_slabs + scnt + 1)); // pre-allocate ~32k into every slab slot. var quot = sbts / 4; while (scnt-- > 0) { RefCountPtr* ls = null; var count = 0; for (var todo = 32768; todo > 0; count++, todo -= sbts, bp += sbts) { var rc = (RefCountPtr*)bp; rc->_list = ls; ls = rc; } _slabs[scnt].Set(ls, count); sbts -= quot; if ((scnt & 1) != 0) quot = sbts / 4; } // pre-allocate 256k into hash table buckets; _hb_cp = (HashBucket*)bp; _hb_ep = (HashBucket*)(bp += 256 * 1024); // pre-allocate ~1mb into big-mem chunks. _sbigs = null; _cntBigs = 0; sbts = iBigBlockSize + SizeofRcp; for (int left = 1024 * (1024 + 16); left > 0; _cntBigs++, left -= sbts, bp += sbts) { var rc = (RefCountPtr*)bp; rc->_list = _sbigs; _sbigs = rc; } // pre-allocate large memory pages for cache purposes. if (!_config.ReserveMemory) _cntPages = 1 + (int)((Stats.MemoryLimit - 1) / _config.AllocPageSize); if (_lpList != null) if (_config.ReserveMemory) { } else { for (var ls = _lpList; ls != null; ls = ls.next) ls.Release(); _lpList = null; } else if (_config.ReserveMemory) for (var bytes = Stats.MemoryLimit; bytes > 0; bytes -= _lpList.size) _lpList = new LargePage(_virtual_memory, _config.AllocPageSize) { next = _lpList }; _lpNext = _lpList; _cp = bp; _ep = _lpBase.data + _lpBase.size; }
private void FreeMem(RefCountPtr* bp, int size) { if (size <= iLastSlabSize) _slabs[_slab_id(size + SizeofRcp)].Push(bp); else { var ls = bp->Next; bp->_list = _sbigs; _sbigs = bp; _cntBigs++; if (ls == null) return; for (_cntBigs++, bp = ls; bp->_list != null; bp = bp->_list) _cntBigs++; bp->_list = _sbigs; _sbigs = ls; } }
private RefCountPtr* GetBig(int size = iBigBlockSize) { RefCountPtr* db = _sbigs, cp = db; for (; cp != null; _cntBigs--, cp = cp->_list) if ((size -= iBigBlockSize) <= 0) { _sbigs = cp->_list; cp->_list = null; _cntBigs--; return db; } Debug.Assert(_cntBigs == 0, "big-mem"); _sbigs = null; do { var np = GetNewMem(iBigBlockSize + SizeofRcp); np->_list = db; db = np; } while ((size -= iBigBlockSize) > 0); return db; }