Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hx/Telemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,8 @@ void hx::Telemetry::HXTAllocation(void* obj, size_t inSize, const char* type)
// for every external call, hashes for every SDL event (Lime's
// ExternalInterface.external_handler()), etc
#ifndef HXCPP_PROFILE_EXTERNS
if (stack->getCurrentStackFrame()->position->className==hx::EXTERN_CLASS_NAME) {
alloc_mutex.unlock();
// alloc_mutex is not locked yet, and an empty stack has no current frame.
if (stack->getDepth() > 0 && stack->getCurrentStackFrame()->position->className==hx::EXTERN_CLASS_NAME) {
return;
}
#endif
Expand Down
46 changes: 46 additions & 0 deletions test/telemetry/TestAllocations.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import sys.thread.Lock;
import sys.thread.Thread;
import utest.Assert;
import utest.Test;

class TestAllocations extends Test
{
// Keeps what the worker thread allocates reachable, so it is never
// reclaimed after that thread's telemetry has been deleted
static var tracked:Array<Dynamic> = [];

// HXTAllocation skips allocations made inside a CFFI call. Skipping one
// must leave alloc_mutex usable, or the next thread to lock it blocks.
function testExternAllocationLeavesAllocationLockUsable()
{
var allocated = new Lock();
Thread.create(function() {
untyped __global__.__hxcpp_hxt_start_telemetry(true, true);
tracked.push(allocateInExternFrame());
tracked.push([4, 5, 6]);
allocated.release();
});
Assert.isTrue(allocated.wait(10.0));

// Stashing locks alloc_mutex, even without allocation tracking
var stashed = new Lock();
Thread.create(function() {
untyped __global__.__hxcpp_hxt_stash_telemetry();
stashed.release();
});
Assert.isTrue(stashed.wait(10.0));
}

// Primitives loaded with cpp.Lib.load run inside a frame like this one
// (see ExternalPrimitive in src/hx/Lib.cpp), so what they allocate takes
// the extern path in HXTAllocation
static function allocateInExternFrame():Array<Int>
{
var result:Array<Int> = null;
untyped __cpp__('{
HX_STACK_FRAME(::hx::EXTERN_CLASS_NAME, "cffi", 0, "extern::cffi", __FILE__, __LINE__, 0)
{0} = ::Array_obj< int >::__new(3, 3);
}', result);
return result;
}
}
2 changes: 1 addition & 1 deletion test/telemetry/TestMain.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package;
class TestMain {

static function main(){
utest.UTest.run([ new TestBasic() ]);
utest.UTest.run([ new TestBasic(), new TestAllocations() ]);
}
}
Loading