@@ -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
482484inline 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+
486570Array<String> __hxcpp_get_call_stack (bool inSkipLast);
487571Array<String> __hxcpp_get_exception_stack ();
488572#define HXCPP_HAS_CLASSLIST
0 commit comments