MCPcopy Create free account
hub / github.com/BernardoGiordano/Checkpoint / reapThread

Function reapThread

3ds/source/thread.cpp:41–80  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

39 DataMutex<std::pair<SmallVector<Thread, Threads::MAX_THREADS>, SmallVector<Handle, MIN_HANDLES + Threads::MAX_THREADS>>> threads;
40
41 void reapThread(void* arg)
42 {
43 while (true) {
44 s32 signaledHandle;
45 {
46 u32 size;
47 const Handle* handles;
48 // Letting the lock expire is fine because the only thing that could happen between
49 // then and the use is adding a handle, which won't change anything since we only
50 // use the original size
51 // In an ideal world, svcWaitSynchronizationN would atomically release and regain
52 // the lock, but we can't have nice things
53 {
54 auto lockedThreadData = threads.lock();
55 const auto& [lockedThreads, reaperThreadHandles] = *lockedThreadData;
56 size = lockedThreads.size();
57 handles = reaperThreadHandles.data();
58 }
59 svcWaitSynchronizationN(&signaledHandle, handles, MIN_HANDLES + size, false, U64_MAX);
60 }
61 switch (signaledHandle) {
62 case 0: {
63 auto lockedThreads = threads.lock();
64 for (size_t i = 0; i < lockedThreads->first.size(); i++) {
65 svcWaitSynchronization(lockedThreads->second[MIN_HANDLES + i], U64_MAX);
66 threadFree(lockedThreads->first[i]);
67 }
68 return;
69 }
70 case 1:
71 continue;
72 default: {
73 auto lockedThreads = threads.lock();
74 threadFree(lockedThreads->first[signaledHandle - 2]);
75 lockedThreads->first.erase(lockedThreads->first.begin() + signaledHandle - 2);
76 lockedThreads->second.erase(lockedThreads->second.begin() + signaledHandle);
77 } break;
78 }
79 }
80 }
81
82 struct Task {
83 void (*entrypoint)(void*);

Callers

nothing calls this directly

Calls 5

lockMethod · 0.45
sizeMethod · 0.45
dataMethod · 0.45
eraseMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected