Skip to content

Commit fd3e074

Browse files
Add AtomicObject implementation (#1242)
1 parent 05b5e3a commit fd3e074

File tree

1 file changed

+87
-3
lines changed

1 file changed

+87
-3
lines changed

include/hx/StdLibs.h

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,16 +473,100 @@ inline void* _hx_atomic_compare_exchange_ptr(volatile void **a, void *expected,
473473
#elif defined(HX_MSVC_ATOMICS)
474474
return _InterlockedCompareExchangePointer((void *volatile *)a, replacement, expected);
475475
#else
476-
void *old = *a;
477-
*a = replacement;
478-
return old;
476+
void *old = *a;
477+
if (old == expected) {
478+
*a = replacement;
479+
}
480+
return old;
479481
#endif
480482
}
481483

482484
inline void* _hx_atomic_compare_exchange_cast_ptr(void *a, void *expected, void *replacement) {
483485
return _hx_atomic_compare_exchange_ptr((volatile void **)a, expected, replacement);
484486
}
485487

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+
hx::Object *original = aPtr.load();
526+
while (original == expected) {
527+
if (aPtr.compare_exchange_weak(original, replacement.mPtr)) {
528+
HX_OBJ_WB_GET(this, replacement.mPtr);
529+
return original;
530+
} else {
531+
continue;
532+
}
533+
}
534+
return original;
535+
}
536+
};
537+
538+
inline Dynamic __hxcpp_atomic_object_create(Dynamic value) {
539+
return new AtomicObject(value);
540+
}
541+
542+
inline Dynamic __hxcpp_atomic_object_store(Dynamic dynObj, Dynamic val) {
543+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
544+
if (!obj)
545+
throw HX_INVALID_OBJECT;
546+
return obj->store(val);
547+
}
548+
549+
inline Dynamic __hxcpp_atomic_object_load(Dynamic dynObj) {
550+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
551+
if (!obj)
552+
throw HX_INVALID_OBJECT;
553+
return obj->load();
554+
}
555+
556+
inline Dynamic __hxcpp_atomic_object_exchange(Dynamic dynObj, Dynamic newVal) {
557+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
558+
if (!obj)
559+
throw HX_INVALID_OBJECT;
560+
return obj->exchange(newVal);
561+
}
562+
563+
inline Dynamic __hxcpp_atomic_object_compare_exchange(Dynamic dynObj, Dynamic expected, Dynamic replacement) {
564+
AtomicObject *obj = dynamic_cast<AtomicObject *>(dynObj.mPtr);
565+
if (!obj)
566+
throw HX_INVALID_OBJECT;
567+
return obj->compareExchange(expected, replacement);
568+
}
569+
486570
Array<String> __hxcpp_get_call_stack(bool inSkipLast);
487571
Array<String> __hxcpp_get_exception_stack();
488572
#define HXCPP_HAS_CLASSLIST

0 commit comments

Comments
 (0)