Skip to content

Commit 9629cc3

Browse files
committed
use atomics for locking
spinlock will hopefully stop the system from complaining about calls to trylock also, noticed i wasn't initializing the mutex correctly, idk how it worked
1 parent 41923b6 commit 9629cc3

File tree

1 file changed

+45
-30
lines changed
  • goldhen_plugins/plugin_src/extern_traces/source

1 file changed

+45
-30
lines changed

goldhen_plugins/plugin_src/extern_traces/source/logging.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,56 @@
11
#include "logging.h"
2+
#include <stdatomic.h>
3+
#include <stdbool.h>
24
#include <string.h>
35

4-
int printf(const char*, ...);
6+
int printf(const char *, ...);
57

68
typedef unsigned int uint32_t;
79
typedef unsigned long uint64_t;
810

11+
typedef struct
12+
{
13+
atomic_flag locked;
14+
} atomic_mutex;
15+
16+
// Static initialization of an atomic_mutex instance
17+
#define ATOMIC_MUTEX_INIT \
18+
{ \
19+
.locked = ATOMIC_FLAG_INIT \
20+
}
21+
22+
void atomic_mutex_init(atomic_mutex *mutex)
23+
{
24+
atomic_flag_clear(&mutex->locked);
25+
}
26+
27+
void atomic_mutex_lock(atomic_mutex *mutex)
28+
{
29+
while (atomic_flag_test_and_set_explicit(&mutex->locked, memory_order_acquire))
30+
{
31+
// Active waiting
32+
}
33+
}
34+
35+
bool atomic_mutex_trylock(atomic_mutex *mutex)
36+
{
37+
// Try to acquire the lock without blocking
38+
// Returns false if the lock is already held, true if lock acquisition is successful
39+
return !atomic_flag_test_and_set_explicit(&mutex->locked, memory_order_acquire);
40+
}
41+
42+
void atomic_mutex_unlock(atomic_mutex *mutex)
43+
{
44+
atomic_flag_clear_explicit(&mutex->locked, memory_order_release);
45+
}
46+
947
#define HIGH_WATER_MARK_BYTES (64 * 1024)
1048
#define MAX_BUFFERED_BYTES (128 * 1024)
1149

1250
_Static_assert(
1351
HIGH_WATER_MARK_BYTES < MAX_BUFFERED_BYTES,
1452
"high water mark must be smaller than max buffer size");
1553

16-
// Not sure of the exact size of the mutex, so blocking off more bytes than we
17-
// probably need.
18-
typedef char ScePthreadMutex[1024];
19-
2054
#define MAX_FLUSH_QUEUE_ENTRIES 1024
2155

2256
typedef struct FlushQueueEntry
@@ -33,7 +67,7 @@ typedef struct FlushQueue
3367
} FlushQueue;
3468

3569
static FlushQueue flush_queue;
36-
static ScePthreadMutex flush_queue_mutex;
70+
static atomic_mutex flush_queue_mutex = ATOMIC_MUTEX_INIT;
3771

3872
typedef struct ThreadLoggingState
3973
{
@@ -68,9 +102,6 @@ void flush_queue_add(ThreadLoggingState *input, FlushQueue *queue)
68102
__thread ThreadLoggingState logging_state;
69103

70104
int sceRtcGetCurrentTick(uint64_t *tick);
71-
int scePthreadMutexTrylock(ScePthreadMutex *mutex);
72-
int scePthreadMutexLock(ScePthreadMutex *mutex);
73-
int scePthreadMutexUnlock(ScePthreadMutex *mutex);
74105
unsigned int sceKernelSleep(unsigned int seconds);
75106
int sceKernelOpen(const char *, int, uint64_t);
76107
long sceKernelWrite(int, const void *, unsigned long);
@@ -97,17 +128,12 @@ void extern_logf(const char *msg)
97128
if (logging_state.buffer_idx >= HIGH_WATER_MARK_BYTES || (current_time - logging_state.start_time) >= 1 * 1000 * 1000)
98129
{
99130
// if past the high water mark or more than 1 second since the buffer init, attempt to flush
100-
int ret = scePthreadMutexTrylock(&flush_queue_mutex);
101-
if (!ret)
131+
bool locked = atomic_mutex_trylock(&flush_queue_mutex);
132+
if (locked)
102133
{
103134
// locked, add to flush queue
104135
flush_queue_add(&logging_state, &flush_queue);
105-
int ret = scePthreadMutexUnlock(&flush_queue_mutex);
106-
if (ret)
107-
{
108-
// error occured
109-
printf("extern_traces: scePThreadMutexUnlock non-ok value %x\n", ret);
110-
}
136+
atomic_mutex_unlock(&flush_queue_mutex);
111137
}
112138
else
113139
{
@@ -138,13 +164,7 @@ void *flush_thread_start_routine(void *args)
138164
while (1)
139165
{
140166
printf("extern_traces: flush thread: flushing\n");
141-
int ret = scePthreadMutexLock(&flush_queue_mutex);
142-
if (ret)
143-
{
144-
printf("extern_traces: flush thread: failed to acquire lock %x\n", ret);
145-
continue;
146-
}
147-
167+
atomic_mutex_lock(&flush_queue_mutex);
148168
printf("extern_traces: flush thread: locked\n");
149169

150170
for (; flush_queue.read_head_idx != flush_queue.write_head_idx; flush_queue.read_head_idx = (flush_queue.read_head_idx + 1) % MAX_FLUSH_QUEUE_ENTRIES)
@@ -161,12 +181,7 @@ void *flush_thread_start_routine(void *args)
161181
printf("extern_traces: flush thread: wrote entry %d\n", flush_queue.read_head_idx);
162182
}
163183

164-
ret = scePthreadMutexUnlock(&flush_queue_mutex);
165-
if (ret)
166-
{
167-
printf("extern_traces: flush thread: failed to release lock %x\n", ret);
168-
continue;
169-
}
184+
atomic_mutex_unlock(&flush_queue_mutex);
170185
printf("extern_traces: flush thread: unlocked\n");
171186

172187
sceKernelSleep(1);

0 commit comments

Comments
 (0)