Skip to content

Commit 98d5191

Browse files
authored
Merge branch 'HaxeFoundation:master' into patch-3
2 parents 94846db + be7ef02 commit 98d5191

4 files changed

Lines changed: 124 additions & 17 deletions

File tree

include/hx/StdLibs.h

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Array<unsigned char> __hxcpp_resource_bytes(String inName);
4343
// System access
4444
Array<String> __get_args();
4545
double __time_stamp();
46+
::cpp::Int64 __time_stamp_ms();
4647

4748
HXCPP_EXTERN_CLASS_ATTRIBUTES void __hxcpp_print_string(const String &inV);
4849
HXCPP_EXTERN_CLASS_ATTRIBUTES void __hxcpp_println_string(const String &inV);
@@ -472,16 +473,102 @@ inline void* _hx_atomic_compare_exchange_ptr(volatile void **a, void *expected,
472473
#elif defined(HX_MSVC_ATOMICS)
473474
return _InterlockedCompareExchangePointer((void *volatile *)a, replacement, expected);
474475
#else
475-
void *old = *a;
476-
*a = replacement;
477-
return old;
476+
void *old = *a;
477+
if (old == expected) {
478+
*a = replacement;
479+
}
480+
return old;
478481
#endif
479482
}
480483

481484
inline void* _hx_atomic_compare_exchange_cast_ptr(void *a, void *expected, void *replacement) {
482485
return _hx_atomic_compare_exchange_ptr((volatile void **)a, expected, replacement);
483486
}
484487

488+
#include <atomic>
489+
490+
struct AtomicObject: hx::Object {
491+
std::atomic< ::hx::Object *> aPtr;
492+
493+
AtomicObject(Dynamic val) { aPtr = val.mPtr; }
494+
495+
void __Mark(hx::MarkContext *__inCtx) {
496+
Dynamic ptr = load();
497+
HX_MARK_MEMBER(ptr);
498+
}
499+
500+
#ifdef HXCPP_VISIT_ALLOCS
501+
void __Visit(hx::VisitContext *__inCtx) {
502+
hx::Object *obj = aPtr.load();
503+
HX_VISIT_MEMBER(obj);
504+
aPtr.store(obj);
505+
}
506+
#endif
507+
508+
Dynamic store(Dynamic val) {
509+
aPtr.store(val.mPtr);
510+
HX_OBJ_WB_GET(this, val.mPtr);
511+
return val;
512+
}
513+
514+
Dynamic load() {
515+
return aPtr.load();
516+
}
517+
518+
Dynamic exchange(Dynamic val) {
519+
Dynamic ret = aPtr.exchange(val.mPtr);
520+
HX_OBJ_WB_GET(this, val.mPtr);
521+
return ret;
522+
}
523+
524+
Dynamic compareExchange(Dynamic expected, Dynamic replacement) {
525+
// Note: using Dynamic instead of hx::Object* is important
526+
// Dynamic has an overloaded == operator, a raw pointer to hx::Object does not.
527+
Dynamic original = aPtr.load();
528+
while (original == expected) {
529+
if (aPtr.compare_exchange_weak(original.mPtr, replacement.mPtr)) {
530+
HX_OBJ_WB_GET(this, replacement.mPtr);
531+
return original;
532+
} else {
533+
continue;
534+
}
535+
}
536+
return original;
537+
}
538+
};
539+
540+
inline Dynamic __hxcpp_atomic_object_create(Dynamic value) {
541+
return new AtomicObject(value);
542+
}
543+
544+
inline Dynamic __hxcpp_atomic_object_store(Dynamic dynObj, Dynamic val) {
545+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
546+
if (!obj)
547+
throw HX_INVALID_OBJECT;
548+
return obj->store(val);
549+
}
550+
551+
inline Dynamic __hxcpp_atomic_object_load(Dynamic dynObj) {
552+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
553+
if (!obj)
554+
throw HX_INVALID_OBJECT;
555+
return obj->load();
556+
}
557+
558+
inline Dynamic __hxcpp_atomic_object_exchange(Dynamic dynObj, Dynamic newVal) {
559+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
560+
if (!obj)
561+
throw HX_INVALID_OBJECT;
562+
return obj->exchange(newVal);
563+
}
564+
565+
inline Dynamic __hxcpp_atomic_object_compare_exchange(Dynamic dynObj, Dynamic expected, Dynamic replacement) {
566+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
567+
if (!obj)
568+
throw HX_INVALID_OBJECT;
569+
return obj->compareExchange(expected, replacement);
570+
}
571+
485572
Array<String> __hxcpp_get_call_stack(bool inSkipLast);
486573
Array<String> __hxcpp_get_exception_stack();
487574
#define HXCPP_HAS_CLASSLIST

src/hx/StdLibs.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,17 @@ int __hxcpp_irand(int inMax)
242242
return (lo | (mid<<12) | (hi<<24) ) % inMax;
243243
}
244244

245+
#ifdef HX_WINDOWS
246+
LARGE_INTEGER qpcFrequency;
247+
#endif
248+
245249
void __hxcpp_stdlibs_boot()
246250
{
251+
#ifdef HX_WINDOWS
252+
// MSDN states that QueryPerformanceFrequency will always succeed on XP and above, so I'm ignoring the result.
253+
QueryPerformanceFrequency(&qpcFrequency);
254+
#endif
255+
247256
#if defined(_MSC_VER) && !defined(HX_WINRT)
248257
HMODULE kernel32 = LoadLibraryA("kernel32");
249258
if (kernel32)
@@ -327,10 +336,7 @@ double __time_stamp()
327336
if (t0==0)
328337
{
329338
t0 = now;
330-
__int64 freq;
331-
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
332-
if (freq!=0)
333-
period = 1.0/freq;
339+
period = 1.0/qpcFrequency.QuadPart;
334340
}
335341
if (period!=0)
336342
return (now-t0)*period;
@@ -349,6 +355,26 @@ double __time_stamp()
349355
#endif
350356
}
351357

358+
::cpp::Int64 __time_stamp_ms()
359+
{
360+
#ifdef HX_WINDOWS
361+
// MSDN states that QueryPerformanceCounter will always succeed on XP and above, so I'm ignoring the result.
362+
auto now = LARGE_INTEGER{ 0 };
363+
QueryPerformanceCounter(&now);
364+
365+
return now.QuadPart * LONGLONG{ 1000 } / qpcFrequency.QuadPart;
366+
#else
367+
auto time = timespec();
368+
369+
if (clock_gettime(CLOCK_MONOTONIC, &time))
370+
{
371+
throw ::Dynamic(HX_CSTRING("Failed to get the monotonic clock time"));
372+
}
373+
374+
return time.tv_sec * 1000 + (time.tv_nsec / 1000000);
375+
#endif
376+
}
377+
352378
#if defined(HX_WINDOWS) && !defined(HX_WINRT)
353379

354380
/*

src/hx/gc/Immix.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,13 @@ static bool sGcVerifyGenerational = false;
198198
#else
199199
enum { MAX_GC_THREADS = 2 };
200200
#endif
201+
202+
// You can uncomment this for better call stacks if it crashes while collecting
203+
#define HX_MULTI_THREAD_MARKING
201204
#else
202205
enum { MAX_GC_THREADS = 1 };
203206
#endif
204207

205-
#if (MAX_GC_THREADS>1)
206-
// You can uncomment this for better call stacks if it crashes while collecting
207-
#define HX_MULTI_THREAD_MARKING
208-
#endif
209-
210208
#ifdef PROFILE_THREAD_USAGE
211209
static int sThreadMarkCountData[MAX_GC_THREADS+1];
212210
static int sThreadArrayMarkCountData[MAX_GC_THREADS+1];
@@ -1952,7 +1950,7 @@ class MarkContext
19521950
if (obj)
19531951
{
19541952
obj->__Mark(this);
1955-
#if HX_MULTI_THREAD_MARKING
1953+
#ifdef HX_MULTI_THREAD_MARKING
19561954
// Load balance
19571955
if (sLazyThreads && marking->count>32)
19581956
{

src/hx/libs/zlib/Build.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
<compilerflag value="-DSTDC" unless="windows" />
1414
<compilerflag value="-DHAVE_UNISTD_H" unless="windows" />
1515

16-
<compilerflag value="-Wno-unknown-warning" unless="MSVC_VER" />
17-
<compilerflag value="-Wno-unknown-warning-option" unless="MSVC_VER" />
18-
<compilerflag value="-Wno-deprecated-non-prototype" unless="MSVC_VER" />
19-
2016
<file name="ZLib.cpp"/>
2117

2218
<!-- HXCPP_LINK_NO_ZLIB may be set too late, so use filterout as well. -->

0 commit comments

Comments
 (0)