13 #ifndef __UT_TASKSTATE_H_INCLUDED__
14 #define __UT_TASKSTATE_H_INCLUDED__
63 : myArenaAndGroupRefCount(0)
66 "This is just to check that the union is putting the two pointers "
67 "in the same place.");
73 UT_ASSERT_P(myArenaAndGroupRefCount.relaxedLoad() == 0);
74 UT_ASSERT_P(myArenaAndGroup.relaxedLoad() ==
nullptr || myWaitingTasks.relaxedLoad() == plugged());
82 myStatus.relaxedStore(FREE);
83 UT_ASSERT_P(myArenaAndGroupRefCount.relaxedLoad() == 0);
87 myArenaAndGroup.relaxedStore(
nullptr);
93 auto state = myStatus.relaxedLoad();
94 return state == DONE_NO_ARENA || state == DONE_WITH_ARENA;
102 auto state = myStatus.relaxedLoad();
103 if (state == DONE_WITH_ARENA || state == DONE_NO_ARENA || state == BUSY_NO_ARENA)
113 myArenaAndGroupRefCount.add(1);
117 state = myStatus.compare_swap(FREE, run_in_task_arena ? BUSY_WITH_ARENA : BUSY_NO_ARENA);
119 if (state == DONE_NO_ARENA || state == BUSY_NO_ARENA || (!run_in_task_arena && state == FREE))
120 myArenaAndGroupRefCount.add(-1);
121 else if (state == DONE_WITH_ARENA)
131 UT_ASSERT_MSG(0,
"This is untested code. Note that calling code in the build is now unused."
132 " If myArenaAndGroup was used before, it must be used on subsequent executes.");
133 if (myStatus.compare_swap(DONE_NO_ARENA, BUSY_NO_ARENA) == DONE_NO_ARENA)
139 UT_ASSERT(myArenaAndGroupRefCount.relaxedLoad() == 0);
140 myArenaAndGroup.relaxedStore(
nullptr);
143 return BUSY_NO_ARENA;
150 UT_ASSERT_P(myStatus.relaxedLoad() == BUSY_NO_ARENA || myStatus.relaxedLoad() == DONE_NO_ARENA);
157 old = myWaitingTasks;
158 if (old == plugged())
174 while (myWaitingTasks.compare_swap(old, proxy) != old);
190 while (proxy !=
nullptr)
197 myStatus.exchange(DONE_NO_ARENA);
202 myStatus.exchange(run_in_task_arena ? DONE_WITH_ARENA : DONE_NO_ARENA);
212 UT_VERIFY(myWaitingTasks.exchange(plugged()) ==
nullptr);
215 myStatus.exchange(DONE_NO_ARENA);
229 UT_ASSERT_P(myArenaAndGroupRefCount.relaxedLoad() > 0 &&
230 (myStatus.relaxedLoad() == BUSY_WITH_ARENA || myStatus.relaxedLoad() == DONE_WITH_ARENA));
231 myArenaAndGroup.relaxedStore(p);
235 UT_ASSERT_P(myArenaAndGroupRefCount.relaxedLoad() > 0 &&
236 (myStatus.relaxedLoad() == BUSY_WITH_ARENA || myStatus.relaxedLoad() == DONE_WITH_ARENA));
237 return myArenaAndGroup.relaxedLoad();
243 UT_ASSERT_P(myStatus.relaxedLoad() == DONE_WITH_ARENA);
244 if (myArenaAndGroupRefCount.add(-1) == 0)
251 auto *arena_group = myArenaAndGroup.exchange(
nullptr);
264 #endif // __UT_TASKSTATE_H_INCLUDED__
Thread has acquired responsibility to evaluate node.
void markAsDoneNoThread()
Non-threaded version of marking as done.
#define SYS_STATIC_ASSERT_MSG(expr, msg)
A task node for managing which thread is currently working on a given task.
ArenaAndGroup * getArenaGroup() const
void markAsDone(UT_Task *parent_task, bool run_in_task_arena)
SYS_AtomicPtr< UT_TaskStateProxy > myWaitingTasks
#define UT_ASSERT_MSG(ZZ,...)
TaskStatus tryMarkAsBusy(bool run_in_task_arena=false)
void spawnChild(UT_Task &task)
bool isDone() const
Test whether the task state is marked as DONE.
void setAndRetainArenaGroup(ArenaAndGroup *p)
Another thread is busy evaluating the node without an arena.
Another thread is busy evaluating the node with an arena.
std::pair< UT_TaskArena, UT_TaskGroup > ArenaAndGroup
void addWaitingTask(UT_Task &parent_task)
SYS_AtomicPtr< ArenaAndGroup > myArenaAndGroup
TaskStatus relaxedLoadStatus() const
This does a fast (non-atomic) check of the status.
TaskStatus tryMarkAsBusyFromDone()