@@ -101,10 +101,23 @@ template <bool InvertInbox> struct Process {
101
101
return InvertInbox ? !i : i;
102
102
}
103
103
104
- // / Determines if this process needs to wait for ownership of the buffer
104
+ // / Determines if this process needs to wait for ownership of the buffer.
105
105
LIBC_INLINE static bool buffer_unavailable (uint32_t in, uint32_t out) {
106
106
return in != out;
107
107
}
108
+
109
+ // / Attempt to claim the lock at index. Return true on lock taken.
110
+ // / The lock is held when the zeroth bit of the uint32_t at lock[index]
111
+ // / is set, and available when that bit is clear. Bits [1, 32) are zero.
112
+ // / Or with one is a no-op when the lock is already held.
113
+ LIBC_INLINE bool try_lock (uint64_t index) {
114
+ return lock[index ].fetch_or (1 , cpp::MemoryOrder::RELAXED) == 0 ;
115
+ }
116
+
117
+ // Unlock the lock at index.
118
+ LIBC_INLINE void unlock (uint64_t index) {
119
+ lock[index ].store (0 , cpp::MemoryOrder::RELAXED);
120
+ }
108
121
};
109
122
110
123
// / The port provides the interface to communicate between the multiple
@@ -130,9 +143,7 @@ template <bool T> struct Port {
130
143
return process.buffer [index ].opcode ;
131
144
}
132
145
133
- LIBC_INLINE void close () {
134
- process.lock [index ].store (0 , cpp::MemoryOrder::RELAXED);
135
- }
146
+ LIBC_INLINE void close () { process.unlock (index ); }
136
147
137
148
private:
138
149
Process<T> &process;
@@ -258,7 +269,7 @@ LIBC_INLINE void Port<T>::recv_n(A alloc) {
258
269
LIBC_INLINE cpp::optional<Client::Port> Client::try_open (uint16_t opcode) {
259
270
constexpr uint64_t index = 0 ;
260
271
// Attempt to acquire the lock on this index.
261
- if (lock[ index ]. fetch_or ( 1 , cpp::MemoryOrder::RELAXED ))
272
+ if (! try_lock ( index ))
262
273
return cpp::nullopt;
263
274
264
275
// The mailbox state must be read with the lock held.
@@ -271,7 +282,7 @@ LIBC_INLINE cpp::optional<Client::Port> Client::try_open(uint16_t opcode) {
271
282
// state.
272
283
273
284
if (buffer_unavailable (in, out)) {
274
- lock[ index ]. store ( 0 , cpp::MemoryOrder::RELAXED );
285
+ unlock ( index );
275
286
return cpp::nullopt;
276
287
}
277
288
@@ -300,7 +311,7 @@ LIBC_INLINE cpp::optional<Server::Port> Server::try_open() {
300
311
return cpp::nullopt;
301
312
302
313
// Attempt to acquire the lock on this index.
303
- if (lock[ index ]. fetch_or ( 1 , cpp::MemoryOrder::RELAXED ))
314
+ if (! try_lock ( index ))
304
315
return cpp::nullopt;
305
316
306
317
// The mailbox state must be read with the lock held.
@@ -310,7 +321,7 @@ LIBC_INLINE cpp::optional<Server::Port> Server::try_open() {
310
321
out = outbox[index ].load (cpp::MemoryOrder::RELAXED);
311
322
312
323
if (buffer_unavailable (in, out)) {
313
- lock[ index ]. store ( 0 , cpp::MemoryOrder::RELAXED );
324
+ unlock ( index );
314
325
return cpp::nullopt;
315
326
}
316
327
0 commit comments