The Pedigree Project 0.1
Ps2CaptureState.h
1/*
2 * Copyright (c) 2026, Pedigree Developers
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted.
6 */
7
8#ifndef PEDIGREE_KERNEL_MACHINE_PS2CAPTURESTATE_H
9#define PEDIGREE_KERNEL_MACHINE_PS2CAPTURESTATE_H
10#include "pedigree/kernel/processor/types.h"
11
12#include <config.h>
13
14static_assert(__atomic_always_lock_free(sizeof(size_t), nullptr),
15 "PS/2 hard-stage and debugger-state words must be lock-free");
16
25 public:
26 Ps2DebuggerPollingState() : m_Active(0) {}
27
28 void set(bool active) {
29 __atomic_store_n(&m_Active, active ? static_cast<size_t>(1) : static_cast<size_t>(0),
30 __ATOMIC_RELEASE);
31 }
32
33 bool active() const {
34 return __atomic_load_n(&m_Active, __ATOMIC_ACQUIRE) != 0;
35 }
36
37 private:
38 size_t m_Active;
39};
40
43 Ps2CapturedByte() : value(0), secondPort(false) {}
44
45 Ps2CapturedByte(uint8_t capturedValue, bool fromSecondPort)
46 : value(capturedValue), secondPort(fromSecondPort) {}
47
48 uint8_t value;
49 bool secondPort;
50};
51
57 public:
58 static constexpr size_t Capacity = 256;
59
60 Ps2CaptureQueue() : m_Records(), m_WriteSequence(0), m_ReadSequence(0) {}
61
62 bool tryPush(const Ps2CapturedByte& record) {
63 const size_t write = __atomic_load_n(&m_WriteSequence, __ATOMIC_RELAXED);
64 const size_t read = __atomic_load_n(&m_ReadSequence, __ATOMIC_ACQUIRE);
65 if ((write - read) >= Capacity) {
66 return false;
67 }
68
69 m_Records[write % Capacity] = record;
70 __atomic_store_n(&m_WriteSequence, write + 1, __ATOMIC_RELEASE);
71 return true;
72 }
73
75 bool hasCapacity() const {
76 const size_t write = __atomic_load_n(&m_WriteSequence, __ATOMIC_RELAXED);
77 const size_t read = __atomic_load_n(&m_ReadSequence, __ATOMIC_ACQUIRE);
78 return (write - read) < Capacity;
79 }
80
81 bool pop(Ps2CapturedByte& record) {
82 const size_t read = __atomic_load_n(&m_ReadSequence, __ATOMIC_RELAXED);
83 const size_t write = __atomic_load_n(&m_WriteSequence, __ATOMIC_ACQUIRE);
84 if (read == write) {
85 return false;
86 }
87
88 record = m_Records[read % Capacity];
89 __atomic_store_n(&m_ReadSequence, read + 1, __ATOMIC_RELEASE);
90 return true;
91 }
92
93 size_t pending() const {
94 const size_t write = __atomic_load_n(&m_WriteSequence, __ATOMIC_ACQUIRE);
95 const size_t read = __atomic_load_n(&m_ReadSequence, __ATOMIC_ACQUIRE);
96 return write - read;
97 }
98
100 void reset() {
101 __atomic_store_n(&m_WriteSequence, static_cast<size_t>(0), __ATOMIC_RELEASE);
102 __atomic_store_n(&m_ReadSequence, static_cast<size_t>(0), __ATOMIC_RELEASE);
103 }
104
105 private:
106 Ps2CapturedByte m_Records[Capacity];
107 size_t m_WriteSequence;
108 size_t m_ReadSequence;
109};
110
113 public:
114 Ps2IoAdmissionGate() : m_Owned(0) {}
115
116 bool tryAcquire() {
117 size_t expected = 0;
118 return __atomic_compare_exchange_n(&m_Owned, &expected, static_cast<size_t>(1), false,
119 __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
120 }
121
122 void release() {
123 __atomic_store_n(&m_Owned, static_cast<size_t>(0), __ATOMIC_RELEASE);
124 }
125
126 bool owned() const {
127 return __atomic_load_n(&m_Owned, __ATOMIC_ACQUIRE) != 0;
128 }
129
130 private:
131 size_t m_Owned;
132};
133
134#endif
bool hasCapacity() const