2#include "pedigree/kernel/LockGuard.h"
3#include "pedigree/kernel/process/Thread.h"
4#include "pedigree/kernel/utilities/assert.h"
6#include "trace-context.h"
8TraceCloneAdmission::~TraceCloneAdmission() {
10 m_Context->finishThreadCreation();
13TraceEnrollmentAdmission::~TraceEnrollmentAdmission() {
15 m_Context->cancelEnrollment();
19 assert(!admission.m_Context);
21 if (!m_Attached || !valid())
22 return TraceStatus::Missing;
23 if (m_EnrollmentPending || hasIncoming() || m_ThreadCreations == ~
size_t(0))
24 return TraceStatus::Busy;
26 admission.m_Context =
this;
27 return TraceStatus::Success;
30void PosixTraceContext::finishThreadCreation() {
36TraceStatus PosixTraceContext::reserveEnrollment(
Thread& thread,
38 assert(!admission.m_Context && !admission.m_Tracer && !admission.m_Tracee);
40 if (!m_Attached || !valid() || thread.
getParent()->
getId() != m_ProcessId ||
42 return TraceStatus::Missing;
43 if (m_EnrollmentPending || m_ThreadCreations)
44 return TraceStatus::Busy;
46 return TraceStatus::Denied;
48 return TraceStatus::Unsupported;
50 if (!tracee || !m_Creator || !m_Creator->live())
51 return TraceStatus::Missing;
52 admission.m_Tracer = m_Creator;
53 admission.m_Tracee = tracee;
54 admission.m_Context =
this;
55 m_EnrollmentPending =
true;
56 return TraceStatus::Success;
59void PosixTraceContext::cancelEnrollment() {
61 assert(m_EnrollmentPending);
62 m_EnrollmentPending =
false;
67 assert(admission.m_Context ==
this);
68 if (!relation || !relation->valid() || relation->tracer() != admission.m_Tracer ||
69 relation->tracee() != admission.m_Tracee)
70 return TraceStatus::Denied;
72 assert(m_EnrollmentPending);
73 if (!valid() || !ownsTokenUnlocked(admission.m_Tracee) || !admission.m_Tracer->live())
74 return TraceStatus::Missing;
75 assert(!m_ThreadCreations);
78 return TraceStatus::Denied;
81 if (!relation->activate())
82 return TraceStatus::Missing;
83 m_Incoming = relation;
84 m_EnrollmentPending =
false;
85 admission.m_Context =
nullptr;
86 return TraceStatus::Success;
89TraceStatus PosixTraceContext::registerTracee(
const TraceTaskRef& tracer,
91 if (!tracer || !relation || !relation->valid() || relation->tracer() != tracer)
92 return TraceStatus::Denied;
95 return TraceStatus::NoMemory;
96 entry.get()->relation = relation;
98 if (!m_Attached || !valid() || !ownsTokenUnlocked(tracer))
99 return TraceStatus::Missing;
100 for (
auto* existing = m_Outgoing; existing; existing = existing->next) {
101 if (existing->relation == relation)
102 return TraceStatus::Success;
104 entry.get()->next = m_Outgoing;
105 m_Outgoing = entry.releaseOwnership();
106 return TraceStatus::Success;
112 OwnedRelation* retired =
nullptr;
115 auto** position = &m_Outgoing;
116 while (*position && (*position)->relation.get() != relation)
117 position = &(*position)->next;
120 *position = retired->next;
@ Continue
No unwind necessary, carry on as normal.
UnwindType getUnwindState()
Process * getParent() const