@@ -46,6 +46,7 @@ void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
46
46
case cpu_flag::stop: return " STOP" ;
47
47
case cpu_flag::exit : return " EXIT" ;
48
48
case cpu_flag::wait : return " w" ;
49
+ case cpu_flag::unmem: return " un" ;
49
50
case cpu_flag::temp: return " t" ;
50
51
case cpu_flag::pause : return " p" ;
51
52
case cpu_flag::suspend: return " s" ;
@@ -498,10 +499,10 @@ void cpu_thread::operator()()
498
499
cpu_thread* _cpu = get_current_cpu_thread ();
499
500
500
501
// Wait flag isn't set asynchronously so this should be thread-safe
501
- if (progress == 0 && _cpu->state .none_of (cpu_flag::wait + cpu_flag::temp))
502
+ if (progress == 0 && _cpu->state .none_of (cpu_flag::unmem + cpu_flag::temp + cpu_flag:: wait ))
502
503
{
503
504
// Operation just started and syscall is imminent
504
- _cpu->state += cpu_flag::wait + cpu_flag::temp;
505
+ _cpu->state += cpu_flag::unmem + cpu_flag::temp;
505
506
wait_set = true ;
506
507
return ;
507
508
}
@@ -661,12 +662,12 @@ bool cpu_thread::check_state() noexcept
661
662
662
663
if (flags & cpu_flag::pause && s_tls_thread_slot != umax)
663
664
{
664
- // Save value before state is saved and cpu_flag::wait is observed
665
+ // Save value before state is saved and cpu_flag::unmem is observed
665
666
if (s_tls_sctr == umax)
666
667
{
667
668
u64 ctr = g_suspend_counter;
668
669
669
- if (flags & cpu_flag::wait )
670
+ if (flags & ( cpu_flag::unmem + cpu_flag:: wait ) )
670
671
{
671
672
if ((ctr & 3 ) == 2 )
672
673
{
@@ -695,7 +696,6 @@ bool cpu_thread::check_state() noexcept
695
696
{
696
697
// Sticky flag, indicates check_state() is not allowed to return true
697
698
flags -= cpu_flag::temp;
698
- flags -= cpu_flag::wait ;
699
699
cpu_can_stop = false ;
700
700
store = true ;
701
701
}
@@ -756,19 +756,39 @@ bool cpu_thread::check_state() noexcept
756
756
return store;
757
757
}
758
758
759
- if (flags & cpu_flag::wait )
759
+ if (flags & ( cpu_flag::wait + cpu_flag::unmem) )
760
760
{
761
- flags -= cpu_flag::wait ;
761
+ flags -= ( cpu_flag::wait + cpu_flag::unmem) ;
762
762
store = true ;
763
763
}
764
764
765
765
retval = false ;
766
766
}
767
767
else
768
768
{
769
- if (cpu_can_stop && !(flags & cpu_flag:: wait ) )
769
+ if (cpu_can_stop)
770
770
{
771
- flags += cpu_flag::wait ;
771
+ if (flags & (cpu_flag::yield + cpu_flag::preempt))
772
+ {
773
+ flags -= (cpu_flag::yield + cpu_flag::preempt);
774
+ store = true ;
775
+ }
776
+
777
+ if (::is_stopped (flags) == !(flags & cpu_flag::wait ))
778
+ {
779
+ flags ^= cpu_flag::wait ;
780
+ store = true ;
781
+ }
782
+
783
+ if (!(flags & cpu_flag::unmem))
784
+ {
785
+ flags += cpu_flag::unmem;
786
+ store = true ;
787
+ }
788
+ }
789
+ else if (flags & (cpu_flag::wait + cpu_flag::unmem))
790
+ {
791
+ flags -= (cpu_flag::wait + cpu_flag::unmem);
772
792
store = true ;
773
793
}
774
794
@@ -780,7 +800,7 @@ bool cpu_thread::check_state() noexcept
780
800
return store;
781
801
}).first ;
782
802
783
- if (state0 & cpu_flag::preempt && cpu_can_stop )
803
+ if (( state0 - state1) & cpu_flag::preempt)
784
804
{
785
805
if (cpu_flag::wait - state0)
786
806
{
@@ -1116,7 +1136,7 @@ std::string cpu_thread::dump_misc() const
1116
1136
bool cpu_thread::suspend_work::push (cpu_thread* _this) noexcept
1117
1137
{
1118
1138
// Can't allow pre-set wait bit (it'd be a problem)
1119
- ensure (!_this || !(_this->state & cpu_flag::wait ));
1139
+ ensure (!_this || !(_this->state & ( cpu_flag::unmem + cpu_flag:: wait ) ));
1120
1140
1121
1141
do
1122
1142
{
@@ -1168,7 +1188,7 @@ bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
1168
1188
1169
1189
copy = cpu_counter::for_all_cpu (copy, [&](cpu_thread* cpu, u32 /* index*/ )
1170
1190
{
1171
- if (cpu->state .fetch_add (cpu_flag::pause ) & cpu_flag::wait )
1191
+ if (cpu->state .fetch_add (cpu_flag::pause ) & ( cpu_flag::unmem + cpu_flag:: wait ) )
1172
1192
{
1173
1193
// Clear bits as long as wait flag is set
1174
1194
return false ;
@@ -1182,7 +1202,7 @@ bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
1182
1202
// Check only CPUs which haven't acknowledged their waiting state yet
1183
1203
copy = cpu_counter::for_all_cpu (copy, [&](cpu_thread* cpu, u32 /* index*/ )
1184
1204
{
1185
- if (cpu->state & cpu_flag::wait )
1205
+ if (cpu->state & ( cpu_flag::unmem + cpu_flag:: wait ) )
1186
1206
{
1187
1207
return false ;
1188
1208
}
0 commit comments