#include #include #include #include #include namespace lart::nontermination { struct State { __lart_termsec_kind kind = __lart_termsec_kind_none; void *key = nullptr; void *thr = nullptr; bool set() const { return kind != __lart_termsec_kind_none; } bool match( __lart_termsec_kind kind, void *key, void *thr ) const { if ( this->kind != kind ) return false; return this->key == key && this->thr == thr; } }; State st; [[gnu::noinline, gnu::weak]] extern "C" __invisible __weakmem_direct State *__lart_termsec_state() noexcept { return &st; } _LART_INTERFACE void __lart_termsec_init() noexcept { new ( __lart_termsec_state() ) State(); } _LART_INTERFACE void __lart_termsec_begin_impl( __lart_termsec_kind kind, void *obj, void *thr ) noexcept { // nondeterministically choose if this is the checked instance of termsecite section assert( obj != nullptr ); if ( !__lart_termsec_state()->set() && __vm_choose( 2 ) ) { __dios_trace_f( "termsec check begin: %s %p %p", show_kind( kind ), obj, thr ); __lart_termsec_state()->kind = kind; __lart_termsec_state()->key = obj; __lart_termsec_state()->thr = thr; } } _LART_INTERFACE void __lart_termsec_end_impl( __lart_termsec_kind kind, void *obj, void *thr ) noexcept { assert( obj != nullptr ); // we are done here if ( __lart_termsec_state()->match( kind, obj, thr ) ) { __dios_trace_f( "termsec check end: %s %p %p", show_kind( kind ), obj, thr ); __lart_termsec_state()->kind = __lart_termsec_kind_none; __dios_exit_process( 0 ); } } _LART_INTERFACE __invisible __weakmem_direct void __lart_termsec_reschedule_cond_acc_hook() noexcept { if ( __lart_termsec_state()->set() ) __vm_ctl_flag( 0, _VM_CF_Accepting ); } _LART_INTERFACE __invisible __weakmem_direct void __lart_termsec_reschedule_acc_hook() noexcept { __vm_ctl_flag( 0, _VM_CF_Accepting ); } } // namespace lart::termsec