11#include <assert.h>
22#include <pthread.h>
33#include <stdatomic.h>
4+ #include <stdio.h>
45#include <stdlib.h>
56#include <unistd.h>
67
1617
1718static void enque_event_exit (struct log_consumer * logc )
1819{
19- assert (!pthread_mutex_lock (& logc -> event .queue_in_lock ));
20+ int _r = pthread_mutex_lock (& logc -> event .queue_in_lock );
21+ assert (_r == 0 ); (void )_r ;
2022 logc -> exit = true; /* ensure this is the last */
2123 for (;;) {
2224 struct msg_head * head = fifo_reserve (logc -> event .queue , msg_cmd_size ());
@@ -31,15 +33,19 @@ static void enque_event_exit(struct log_consumer *logc)
3133 fifo_commit (logc -> event .queue , head );
3234 break ;
3335 }
34- assert (!pthread_mutex_unlock (& logc -> event .queue_in_lock ));
36+ _r = pthread_mutex_unlock (& logc -> event .queue_in_lock );
37+ assert (_r == 0 ); (void )_r ;
3538}
3639
3740static void enque_signal (struct log_consumer * logc )
3841{
39- assert (!pthread_mutex_lock (& logc -> event .siglock ));
42+ int _r = pthread_mutex_lock (& logc -> event .siglock );
43+ assert (_r == 0 ); (void )_r ;
4044 logc -> event .sig_send ++ ;
41- assert (!pthread_cond_signal (& logc -> event .cond ));
42- assert (!pthread_mutex_unlock (& logc -> event .siglock ));
45+ _r = pthread_cond_signal (& logc -> event .cond );
46+ assert (_r == 0 ); (void )_r ;
47+ _r = pthread_mutex_unlock (& logc -> event .siglock );
48+ assert (_r == 0 ); (void )_r ;
4349}
4450
4551static void handle_log (struct log_consumer * logc , struct msg_head * head , bool * exit )
@@ -66,10 +72,13 @@ static void handle_log(struct log_consumer *logc, struct msg_head *head, bool *e
6672 * exit = true;
6773 return ;
6874 } else if (cmd -> cmd == MSG_CMD_FLUSH ) {
69- assert (!pthread_mutex_lock (& logc -> flush .siglock ));
75+ int _r = pthread_mutex_lock (& logc -> flush .siglock );
76+ assert (_r == 0 ); (void )_r ;
7077 logc -> flush .done = true;
71- assert (!pthread_cond_signal (& logc -> flush .cond ));
72- assert (!pthread_mutex_unlock (& logc -> flush .siglock ));
78+ _r = pthread_cond_signal (& logc -> flush .cond );
79+ assert (_r == 0 ); (void )_r ;
80+ _r = pthread_mutex_unlock (& logc -> flush .siglock );
81+ assert (_r == 0 ); (void )_r ;
7382 }
7483 offset += msg_cmd_size ();
7584 break ;
@@ -119,24 +128,29 @@ static void *logc_func(void *arg)
119128 pthread_mutex_unlock (& logc -> event .siglock );
120129 /* has data */
121130
122- for (struct msg_head * head = fifo_peek (logc -> event .queue ); head ;
131+ /* pending: number of committed/discarded messages still to consume
132+ * in this wakeup. sig_recv is only incremented when a message is
133+ * actually dequeued, so it never overshoots sig_send. */
134+ unsigned int pending = sig_send_cache - logc -> event .sig_recv ;
135+ unsigned long reserved_spins = 0 ;
136+ for (struct msg_head * head = fifo_peek (logc -> event .queue );
137+ head && pending > 0 ;
123138 head = fifo_peek (logc -> event .queue )) {
124- logc -> event .sig_recv ++ ;
125-
126139 unsigned flag = atomic_load_explicit (& head -> flags , memory_order_acquire );
127140 if (flag == MSG_HEAD_FLAG_RESERVED ) {
128- if (logc -> event .sig_recv == sig_send_cache ) {
129- /* goto wait til fist commited */
130- break ;
131- }
141+ /* spin-wait for the producer to finish committing */
142+ reserved_spins ++ ;
132143 continue ;
133144 }
145+ reserved_spins = 0 ;
134146
147+ pending -- ;
148+ logc -> event .sig_recv ++ ;
135149 if (flag == MSG_HEAD_FLAG_COMMITED ) {
136150 handle_log (logc , head , & exit );
137151 } else if (flag == MSG_HEAD_FLAG_DISCARDED ) {
138152 } else {
139- assert (1 );
153+ assert (0 ); /* unexpected flag value */
140154 }
141155 fifo_out (logc -> event .queue , head );
142156 }
@@ -342,7 +356,8 @@ void log_consumer_queue_commit_signal(struct log_consumer *logc, struct msg_head
342356
343357void log_consumer_queue_flush (struct log_consumer * logc )
344358{
345- assert (!pthread_mutex_lock (& logc -> event .queue_in_lock ));
359+ int _r = pthread_mutex_lock (& logc -> event .queue_in_lock );
360+ assert (_r == 0 ); (void )_r ;
346361 for (;;) {
347362 struct msg_head * head = fifo_reserve (logc -> event .queue , msg_cmd_size ());
348363 if (!head ) {
@@ -357,7 +372,8 @@ void log_consumer_queue_flush(struct log_consumer *logc)
357372 fifo_commit (logc -> event .queue , head );
358373 break ;
359374 }
360- assert (!pthread_mutex_unlock (& logc -> event .queue_in_lock ));
375+ _r = pthread_mutex_unlock (& logc -> event .queue_in_lock );
376+ assert (_r == 0 ); (void )_r ;
361377 enque_signal (logc );
362378
363379 pthread_mutex_lock (& logc -> flush .siglock );
0 commit comments