MINGW heap fix

git-svn-id: svn://ultimatepp.org/upp/trunk@9796 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2016-05-04 11:34:36 +00:00
parent cd8d07e4a9
commit b29407a1f3
3 changed files with 58 additions and 69 deletions

View file

@ -39,6 +39,11 @@ class Function<Res(ArgTypes...)> : Moveable<Function<Res(ArgTypes...)>> {
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 <class F>
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<F>(*this, pick(fn)); Free(b); return *this; }
template <class F>
Function& operator<<(F&& fn) { if(!ptr) { Pick(pick(fn)); return *this; }
WrapperBase *b = ptr; ptr = new Wrapper2<F>(*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 <class F>
Event& operator<<(F f) { fn << f; return *this; }
Event& operator<<(const F& f) { fn << f; return *this; }
template <class F>
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 <class F>
EventGate& operator<<(const F& f) { fn << f; return *this; }
template <class F>
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); }

View file

@ -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()

View file

@ -1,5 +1,3 @@
CLANG11 autotest/RangeInsertTest : ERROR
CLANG11 reference/CallbackPickClone : ERROR
CLANG11 upptst/idetest : ERROR
uppbox