@@ -103,8 +103,7 @@ struct counting_semaphore_t {
103103 // Release n permits (default 1)
104104 // Wakes up waiting coroutines if possible
105105 void release (int n = 1 ) {
106- waiter_node* nodes_to_resume[32 ]; // Batch resume for efficiency
107- int resume_count = 0 ;
106+ waiter_node* nodes_to_resume = nullptr ; // Head of resume list
108107
109108 {
110109 std::lock_guard<MUTEX> lock (mutex_);
@@ -114,13 +113,12 @@ struct counting_semaphore_t {
114113 waiter_node* prev = nullptr ;
115114 waiter_node* node = head_;
116115
117- while (node && resume_count < 32 ) {
116+ while (node) {
118117 if (counter_ >= node->desired ) {
119118 // This waiter can be satisfied
120119 counter_ -= node->desired ;
121- nodes_to_resume[resume_count++] = node;
122120
123- // Remove from list
121+ // Remove from waiting list
124122 if (prev) {
125123 prev->next = node->next ;
126124 } else {
@@ -132,6 +130,11 @@ struct counting_semaphore_t {
132130 }
133131
134132 waiter_node* next = node->next ;
133+
134+ // Add to resume list (prepend for O(1))
135+ node->next = nodes_to_resume;
136+ nodes_to_resume = node;
137+
135138 node = next;
136139 } else {
137140 prev = node;
@@ -141,15 +144,17 @@ struct counting_semaphore_t {
141144 }
142145
143146 // Resume all satisfied waiters outside the lock
144- for (int i = 0 ; i < resume_count; i++) {
145- auto * waiter = nodes_to_resume[i];
147+ waiter_node* waiter = nodes_to_resume;
148+ while (waiter) {
149+ waiter_node* next = waiter->next ;
146150 if (waiter->exec ) {
147151 waiter->exec ->dispatch ([handle = waiter->handle ]() {
148152 handle.resume ();
149153 });
150154 } else {
151155 waiter->handle .resume ();
152156 }
157+ waiter = next;
153158 }
154159 }
155160
0 commit comments