mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: Fixed allocator issue on thread exit
git-svn-id: svn://ultimatepp.org/upp/trunk@13410 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6551749499
commit
4cce8cb98b
5 changed files with 40 additions and 29 deletions
|
|
@ -449,6 +449,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
|
|||
void LargeFreeRemoteRaw() { LargeFreeRemoteRaw(large_remote_list); large_remote_list = NULL; }
|
||||
void LargeFreeRemote();
|
||||
void FreeRemoteRaw();
|
||||
void MoveLargeTo(Heap *to_heap);
|
||||
|
||||
void Shutdown();
|
||||
static void AuxFinalCheck();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace Upp {
|
|||
|
||||
#include "HeapImp.h"
|
||||
|
||||
#define LLOG(x) // LOG((void *)this << ' ' << x)
|
||||
#define LLOG(x) // DLOG(x) // LOG((void *)this << ' ' << x)
|
||||
|
||||
const char *asString(int i)
|
||||
{
|
||||
|
|
@ -63,15 +63,37 @@ void Heap::FreeRemoteRaw()
|
|||
LargeFreeRemoteRaw();
|
||||
}
|
||||
|
||||
void Heap::MoveLargeTo(Heap *to_heap)
|
||||
{
|
||||
while(large != large->next) {
|
||||
DLink *ml = large->next;
|
||||
LLOG("Large page " << asString(ml));
|
||||
ml->Unlink();
|
||||
ml->Link(to_heap->large);
|
||||
LBlkHeader *h = ml->GetFirst();
|
||||
for(;;) {
|
||||
LLOG("Large block " << asString(h) << " size " << AsString(h->GetSize() * 256) << (h->IsFree() ? " free" : ""));
|
||||
h->heap = to_heap;
|
||||
if(h->IsFree()) {
|
||||
h->UnlinkFree(); // will link it when adopting
|
||||
to_heap->lheap.LinkFree(h);
|
||||
}
|
||||
if(h->IsLast())
|
||||
break;
|
||||
h = h->GetNextHeader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Heap::Shutdown()
|
||||
{ // Move all active blocks, "orphans", to global aux heap
|
||||
LLOG("Shutdown");
|
||||
LLOG("**** Shutdown heap " << asString(this));
|
||||
Mutex::Lock __(mutex);
|
||||
Init();
|
||||
RemoteFlushRaw(); // Move remote blocks to originating heaps
|
||||
FreeRemoteRaw(); // Free all remotely freed blocks
|
||||
for(int i = 0; i < NKLASS; i++) {
|
||||
LLOG("Free cache " << i);
|
||||
for(int i = 0; i < NKLASS; i++) { // move all small pages to aux (some heap will pick them later)
|
||||
LLOG("Free cache " << asString(i));
|
||||
FreeLink *l = cache[i];
|
||||
while(l) {
|
||||
FreeLink *h = l;
|
||||
|
|
@ -101,19 +123,9 @@ void Heap::Shutdown()
|
|||
LLOG("Orphan empty " << (void *)empty[i]);
|
||||
}
|
||||
}
|
||||
while(large != large->next) { // Move all large pages to aux (some heap will pick them later)
|
||||
DLink *ml = large->next;
|
||||
ml->Unlink();
|
||||
ml->Link(aux.large);
|
||||
LBlkHeader *h = ml->GetFirst();
|
||||
for(;;) {
|
||||
h->heap = &aux;
|
||||
if(h->IsLast())
|
||||
break;
|
||||
h = h->GetNextHeader();
|
||||
}
|
||||
}
|
||||
MoveLargeTo(&aux); // move all large pages to aux, some heap will pick them later
|
||||
memset(this, 0, sizeof(Heap));
|
||||
LLOG("++++ Done Shutdown heap " << asString(this));
|
||||
}
|
||||
|
||||
void Heap::DblCheck(Page *p)
|
||||
|
|
|
|||
|
|
@ -88,11 +88,7 @@ void *Heap::LAlloc(size_t& size)
|
|||
Mutex::Lock __(mutex);
|
||||
aux.LargeFreeRemoteRaw();
|
||||
if(aux.large->next != aux.large) {
|
||||
while(aux.large->next != aux.large) { // adopt all abandoned large blocks
|
||||
DLink *ml = aux.large->next;
|
||||
ml->Unlink();
|
||||
ml->Link(large);
|
||||
}
|
||||
aux.MoveLargeTo(this); // adopt all abandoned large blocks
|
||||
ptr = TryLAlloc(i0, wcount);
|
||||
if(ptr)
|
||||
return ptr;
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ void *Heap::Allok(int k)
|
|||
force_inline
|
||||
void *Heap::AllocSz(size_t& sz)
|
||||
{
|
||||
LLOG("Alloc " << asString(sz));
|
||||
Stat(sz);
|
||||
if(sz <= 384) {
|
||||
if(sz == 0)
|
||||
|
|
@ -307,16 +308,17 @@ force_inline
|
|||
Heap *ThreadHeap()
|
||||
{
|
||||
#ifdef COMPILER_MINGW
|
||||
thread_local byte sHeap[sizeof(Heap)];
|
||||
static FastMingwTls<Heap *> heap_tls;
|
||||
Heap *heap = heap_tls;
|
||||
if(!heap)
|
||||
heap_tls = heap = (Heap *)sHeap;
|
||||
return heap;
|
||||
#else
|
||||
thread_local Heap heap[1];
|
||||
return heap;
|
||||
thread_local Heap *heap_tls;
|
||||
#endif
|
||||
Heap *heap = heap_tls;
|
||||
if(!heap) { // we definitely need a lock here because some Shutdown can be in progress
|
||||
Mutex::Lock __(Heap::mutex);
|
||||
thread_local byte sHeap[sizeof(Heap)];
|
||||
heap_tls = heap = (Heap *)sHeap;
|
||||
}
|
||||
return heap;
|
||||
}
|
||||
|
||||
void MemoryFreek__(int klass, void *ptr)
|
||||
|
|
|
|||
|
|
@ -876,7 +876,7 @@ void FileSel::LIThread()
|
|||
Image result;
|
||||
if(path.GetCount())
|
||||
li(path, result);
|
||||
if(!IsNull(result) && result.GetWidth() > DPI(16) || result.GetHeight() > DPI(16))
|
||||
if(!IsNull(result) && max(result.GetWidth(), result.GetHeight()) > DPI(16))
|
||||
result = Rescale(result, DPI(16), DPI(16));
|
||||
{
|
||||
Mutex::Lock __(li_mutex);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue