From b29407a1f3cf9ec72b44a38f9ff3fa307c0e81fe Mon Sep 17 00:00:00 2001 From: cxl Date: Wed, 4 May 2016 11:34:36 +0000 Subject: [PATCH] MINGW heap fix git-svn-id: svn://ultimatepp.org/upp/trunk@9796 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Callback.h | 37 ++++++++++++------ uppsrc/Core/sheap.cpp | 88 +++++++++++++++--------------------------- uppsrc/Core/todo.txt | 2 - 3 files changed, 58 insertions(+), 69 deletions(-) diff --git a/uppsrc/Core/Callback.h b/uppsrc/Core/Callback.h index 00d2f0e0a..f21055e10 100644 --- a/uppsrc/Core/Callback.h +++ b/uppsrc/Core/Callback.h @@ -39,6 +39,11 @@ class Function : Moveable> { if(ptr) AtomicInc(ptr->refcount); } + + void Pick(Function&& src) { + ptr = src.ptr; + src.ptr = NULL; + } public: Function() { ptr = NULL; } @@ -48,13 +53,17 @@ public: Function(const Function& src) { Copy(src); } Function& operator=(const Function& src) { auto b = ptr; Copy(src); Free(b); return *this; } - Function(Function&& src) { ptr = src.ptr; src.ptr = NULL; } + Function(Function&& src) { Pick(pick(src)); } Function& operator=(Function&& src) { if(&src != this) { Free(ptr); ptr = src.ptr; src.ptr = NULL; } return *this; } Function Proxy() const { return [=] (ArgTypes... args) { return (*this)(args...); }; } template - Function& operator<<(F fn) { if(!ptr) { Copy(fn); return *this; } + Function& operator<<(const F& fn) { if(!ptr) { Copy(fn); return *this; } + WrapperBase *b = ptr; ptr = new Wrapper2(*this, pick(fn)); Free(b); return *this; } + + template + Function& operator<<(F&& fn) { if(!ptr) { Pick(pick(fn)); return *this; } WrapperBase *b = ptr; ptr = new Wrapper2(*this, pick(fn)); Free(b); return *this; } Res operator()(ArgTypes... args) const { return ptr ? ptr->Execute(args...) : Res(); } @@ -90,15 +99,18 @@ public: Event& operator=(Event&& src) { fn = pick(src.fn); return *this; } Event& operator=(CNULLer) { fn.Clear(); return *this; } Event Proxy() const { return Event(fn.Proxy(), 1); } - +/* Event& operator<<(const Event& b) { fn << b.fn; return *this; } Event& operator<<(const Fn& b) { fn << b; return *this; } Event& operator<<(Event&& b) { fn << pick(b.fn); return *this; } Event& operator<<(Fn&& b) { fn << pick(b); return *this; } - +*/ template - Event& operator<<(F f) { fn << f; return *this; } + Event& operator<<(const F& f) { fn << f; return *this; } + + template + Event& operator<<(F&& f) { fn << pick(f); return *this; } void operator()(ArgTypes... args) const { return fn(args...); } @@ -131,21 +143,24 @@ public: EventGate& operator=(CNULLer) { fn.Clear(); return *this; } EventGate& operator=(bool b) { Set(b); return *this; } EventGate Proxy() const { return fn.Proxy(); } - +/* EventGate& operator<<(const EventGate& b) { fn << b.fn; return *this; } EventGate& operator<<(const Fn& b) { fn << b; return *this; } EventGate& operator<<(EventGate&& b) { fn << pick(b.fn); return *this; } EventGate& operator<<(Fn&& b) { fn << pick(b); return *this; } +*/ + template + EventGate& operator<<(const F& f) { fn << f; return *this; } template - EventGate& operator<<(F f) { fn << f; return *this; } + EventGate& operator<<(F&& f) { fn << pick(f); return *this; } - bool operator()(ArgTypes... args) const { return fn(args...); } + bool operator()(ArgTypes... args) const { return fn(args...); } - operator Fn() const { return fn; } - operator bool() const { return fn; } - void Clear() { fn.Clear(); } + operator Fn() const { return fn; } + operator bool() const { return fn; } + void Clear() { fn.Clear(); } friend EventGate Proxy(const EventGate& a) { return a.Proxy(); } friend void Swap(EventGate& a, EventGate& b) { UPP::Swap(a.fn, b.fn); } diff --git a/uppsrc/Core/sheap.cpp b/uppsrc/Core/sheap.cpp index 696a18940..c0ad2326b 100644 --- a/uppsrc/Core/sheap.cpp +++ b/uppsrc/Core/sheap.cpp @@ -294,44 +294,46 @@ void Heap::Free48(void *ptr) Free(ptr, KLASS_48); } -thread_local byte sHeap[sizeof(Heap)]; // Mingw has issues with class thread_local -thread_local Heap *heap = (Heap *)sHeap; +force_inline +Heap *ThreadHeap() +{ +#if defined(COMPILER_GCC) && defined(PLATFORM_WIN32) // Workaround for MINGW bug + thread_local byte sHeap[sizeof(Heap)]; + thread_local Heap *heap; + if(!heap) + heap = (Heap *)sHeap; + return heap; +#else + thread_local Heap heap[1]; + return heap; +#endif +} void MemoryFreek__(int klass, void *ptr) { - if(!heap) - heap = (Heap *)sHeap; - heap->Free((void *)ptr, klass); + ThreadHeap()->Free((void *)ptr, klass); } void *MemoryAllok__(int klass) { - if(!heap) - heap = (Heap *)sHeap; - return heap->Allok(klass); + return ThreadHeap()->Allok(klass); } #if defined(HEAPDBG) void *MemoryAlloc_(size_t sz) { - if(!heap) - heap = (Heap *)sHeap; - return heap->AllocSz(sz); + return ThreadHeap()->AllocSz(sz); } void MemoryFree_(void *ptr) { - if(!heap) - heap = (Heap *)sHeap; - heap->Free(ptr); + ThreadHeap()->Free(ptr); } size_t GetMemoryBlockSize_(void *ptr) { - if(!heap) - heap = (Heap *)sHeap; - return heap->GetBlockSize(ptr); + return ThreadHeap()->GetBlockSize(ptr); } #else @@ -341,104 +343,78 @@ size_t GetMemoryBlockSize_(void *ptr) void *MemoryAlloc(size_t sz) { LTIMING("MemoryAlloc"); - if(!heap) - heap = (Heap *)sHeap; - return heap->AllocSz(sz); + return ThreadHeap()->AllocSz(sz); } void *MemoryAllocSz(size_t& sz) { LTIMING("MemoryAllocSz"); - if(!heap) - heap = (Heap *)sHeap; - return heap->AllocSz(sz); + return ThreadHeap()->AllocSz(sz); } void MemoryFree(void *ptr) { LTIMING("MemoryFree"); - if(!heap) - heap = (Heap *)sHeap; - heap->Free(ptr); + ThreadHeap()->Free(ptr); } size_t GetMemoryBlockSize(void *ptr) { - if(!heap) - heap = (Heap *)sHeap; - return heap->GetBlockSize(ptr); + return ThreadHeap()->GetBlockSize(ptr); } bool TryRealloc(void *ptr, size_t size) { - if(!heap) - heap = (Heap *)sHeap; - return heap->TryRealloc(ptr, size); + return ThreadHeap()->TryRealloc(ptr, size); } void *MemoryAlloc32() { LTIMING("MemoryAlloc32"); - if(!heap) - heap = (Heap *)sHeap; - return heap->Alloc32(); + return ThreadHeap()->Alloc32(); } void MemoryFree32(void *ptr) { LTIMING("MemoryFree32"); - if(!heap) - heap = (Heap *)sHeap; - heap->Free32(ptr); + ThreadHeap()->Free32(ptr); } void *MemoryAlloc48() { LTIMING("MemoryAlloc48"); - if(!heap) - heap = (Heap *)sHeap; - return heap->Alloc48(); + return ThreadHeap()->Alloc48(); } void MemoryFree48(void *ptr) { LTIMING("MemoryFree48"); - if(!heap) - heap = (Heap *)sHeap; - heap->Free48(ptr); + ThreadHeap()->Free48(ptr); } #endif void MemoryFreeThread() { - if(!heap) - heap = (Heap *)sHeap; - heap->Shutdown(); + ThreadHeap()->Shutdown(); } void MemoryCheck() { - if(!heap) - heap = (Heap *)sHeap; - heap->Check(); + ThreadHeap()->Check(); } MemoryProfile::MemoryProfile() { - if(!heap) - heap = (Heap *)sHeap; - heap->Make(*this); + ThreadHeap()->Make(*this); } static MemoryProfile *sPeak; void DoPeakProfile() { - if(!heap) - heap = (Heap *)sHeap; if(sPeak) - heap->Make(*sPeak); + ThreadHeap()->Make(*sPeak); } MemoryProfile *PeakMemoryProfile() diff --git a/uppsrc/Core/todo.txt b/uppsrc/Core/todo.txt index c117f6b30..99a1fc8d8 100644 --- a/uppsrc/Core/todo.txt +++ b/uppsrc/Core/todo.txt @@ -1,5 +1,3 @@ -CLANG11 autotest/RangeInsertTest : ERROR -CLANG11 reference/CallbackPickClone : ERROR CLANG11 upptst/idetest : ERROR uppbox