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
68typedef unsigned int uint32_t ;
79typedef 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
2256typedef struct FlushQueueEntry
@@ -33,7 +67,7 @@ typedef struct FlushQueue
3367} FlushQueue ;
3468
3569static FlushQueue flush_queue ;
36- static ScePthreadMutex flush_queue_mutex ;
70+ static atomic_mutex flush_queue_mutex = ATOMIC_MUTEX_INIT ;
3771
3872typedef struct ThreadLoggingState
3973{
@@ -68,9 +102,6 @@ void flush_queue_add(ThreadLoggingState *input, FlushQueue *queue)
68102__thread ThreadLoggingState logging_state ;
69103
70104int sceRtcGetCurrentTick (uint64_t * tick );
71- int scePthreadMutexTrylock (ScePthreadMutex * mutex );
72- int scePthreadMutexLock (ScePthreadMutex * mutex );
73- int scePthreadMutexUnlock (ScePthreadMutex * mutex );
74105unsigned int sceKernelSleep (unsigned int seconds );
75106int sceKernelOpen (const char * , int , uint64_t );
76107long 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