The Pedigree Project 0.1
trace-context.h
1/* Copyright (c) 2026, Pedigree Developers. */
2#ifndef PEDIGREE_POSIX_TRACE_CONTEXT_H
3#define PEDIGREE_POSIX_TRACE_CONTEXT_H
4
5#include "pedigree/kernel/process/Mutex.h"
6#include "pedigree/kernel/process/Process.h"
7
8#include "trace-state.h"
9
10class EXPORTED_PUBLIC PreparedTraceTask {
11 public:
12 PreparedTraceTask() = default;
13 ~PreparedTraceTask() = default;
14
15 private:
16 friend class PosixTraceContext;
17 friend class ParentDeathSignals;
18 PreparedTraceTask(const PreparedTraceTask&) = delete;
19 PreparedTraceTask& operator=(const PreparedTraceTask&) = delete;
20 TraceTaskRef m_Token;
21 PreparedTraceTask* m_Next = nullptr;
22 PreparedTraceTask* m_ParentDeathNext = nullptr;
23 PreparedTraceTask* m_ParentDeathPrevious = nullptr;
24};
25
26// Declare inside the existing Process::ThreadCreationScope lifetime.
27class EXPORTED_PUBLIC TraceCloneAdmission {
28 public:
29 TraceCloneAdmission() = default;
31
32 private:
33 friend class PosixTraceContext;
35 TraceCloneAdmission& operator=(const TraceCloneAdmission&) = delete;
36 PosixTraceContext* m_Context = nullptr;
37};
38
39// Caller defers events through enrollment and core frame-flag publication.
40class EXPORTED_PUBLIC TraceEnrollmentAdmission {
41 public:
42 TraceEnrollmentAdmission() = default;
44 const TraceTaskRef& tracer() const {
45 return m_Tracer;
46 }
47 const TraceTaskRef& tracee() const {
48 return m_Tracee;
49 }
50
51 private:
52 friend class PosixTraceContext;
54 TraceEnrollmentAdmission& operator=(const TraceEnrollmentAdmission&) = delete;
55 PosixTraceContext* m_Context = nullptr;
56 TraceTaskRef m_Tracer, m_Tracee;
57};
58
59class EXPORTED_PUBLIC PosixTraceContext {
60 public:
61 PosixTraceContext() = default;
63 bool valid() const;
64 void attach(Process&);
65 TraceStatus prepareTask(UniquePointer<PreparedTraceTask>&);
66 TraceStatus publishTask(UniquePointer<PreparedTraceTask>&, Thread&);
67 bool taskToken(const Thread&, TraceTaskRef&) const;
68 void setCreator(const TraceTaskRef&);
69 TraceTaskRef creator() const;
70 bool setParentDeathSignal(const Thread&, int);
71 void promoteExec(const Thread&);
72 void retireTask(const Thread&);
73 void close();
74
75 TraceStatus reserveThreadCreation(TraceCloneAdmission&);
76 TraceStatus reserveEnrollment(Thread&, TraceEnrollmentAdmission&);
77 TraceStatus commitEnrollment(TraceEnrollmentAdmission&, const TraceRelationRef&);
78 TraceStatus registerTracee(const TraceTaskRef& tracer, const TraceRelationRef&);
79 void unregisterTracee(const PosixTraceRelation*);
80 void clearIncoming(const PosixTraceRelation*);
81 // Output must be empty and declared outside any parent child-state guard.
82 // Only a short spin guard is taken; release the reference after that guard.
83 bool acquireIncoming(TraceRelationRef& empty) const;
84 bool selectStop(size_t parentPid, bool stopped, bool continued, bool consume, PosixWait::Report&);
85
86 private:
87 friend class TraceCloneAdmission;
88 friend class TraceEnrollmentAdmission;
89 PosixTraceContext(const PosixTraceContext&) = delete;
90 PosixTraceContext& operator=(const PosixTraceContext&) = delete;
92 TraceRelationRef relation;
93 OwnedRelation* next = nullptr;
94 };
95 TraceTaskRef tokenUnlocked(size_t localId) const;
96 bool ownsTokenUnlocked(const TraceTaskRef&) const;
97 void finishThreadCreation();
98 void cancelEnrollment();
99 bool hasIncoming() const;
100 mutable Mutex m_AdmissionLock;
101 mutable Spinlock m_RelationLock;
102 bool m_Attached = false, m_Closed = false;
103 size_t m_ProcessId = 0, m_ThreadCreations = 0;
104 bool m_EnrollmentPending = false;
105 PreparedTraceTask* m_Tasks = nullptr;
106 OwnedRelation* m_Outgoing = nullptr;
107 TraceTaskRef m_Creator;
108 TraceRelationRef m_Incoming;
109};
110
111// No lock from either context/token may be held by callers. Output starts empty.
112EXPORTED_PUBLIC TraceStatus posix_trace_acquire_task(const TraceTaskRef&, Process::ThreadLease&);
113#endif
Definition Mutex.h:56