30
30
#include "../libs/tools.h"
31
31
#include "../libs/threading.h"
32
32
#include "../libs/logging.h"
33
+ #include "../libs/list.h"
33
34
34
35
35
36
static void * _worker_thread (void * v_worker );
@@ -53,13 +54,13 @@ us_workers_pool_s *us_workers_pool_init(
53
54
atomic_init (& pool -> stop , false);
54
55
55
56
pool -> n_workers = n_workers ;
56
- US_CALLOC (pool -> workers , pool -> n_workers );
57
57
58
58
US_MUTEX_INIT (pool -> free_workers_mutex );
59
59
US_COND_INIT (pool -> free_workers_cond );
60
60
61
61
for (uint index = 0 ; index < pool -> n_workers ; ++ index ) {
62
- us_worker_s * const wr = & pool -> workers [index ];
62
+ us_worker_s * wr ;
63
+ US_CALLOC (wr , 1 );
63
64
64
65
wr -> number = index ;
65
66
US_ASPRINTF (wr -> name , "%s-%u" , wr_prefix , index );
@@ -73,6 +74,8 @@ us_workers_pool_s *us_workers_pool_init(
73
74
74
75
US_THREAD_CREATE (wr -> tid , _worker_thread , (void * )wr );
75
76
pool -> free_workers += 1 ;
77
+
78
+ US_LIST_APPEND (pool -> workers , wr );
76
79
}
77
80
return pool ;
78
81
}
@@ -81,9 +84,7 @@ void us_workers_pool_destroy(us_workers_pool_s *pool) {
81
84
US_LOG_INFO ("Destroying workers pool %s ..." , pool -> name );
82
85
83
86
atomic_store (& pool -> stop , true);
84
- for (uint index = 0 ; index < pool -> n_workers ; ++ index ) {
85
- us_worker_s * const wr = & pool -> workers [index ];
86
-
87
+ US_LIST_ITERATE (pool -> workers , wr , { // cppcheck-suppress constStatement
87
88
US_MUTEX_LOCK (wr -> has_job_mutex );
88
89
atomic_store (& wr -> has_job , true); // Final job: die
89
90
US_MUTEX_UNLOCK (wr -> has_job_mutex );
@@ -93,83 +94,56 @@ void us_workers_pool_destroy(us_workers_pool_s *pool) {
93
94
US_MUTEX_DESTROY (wr -> has_job_mutex );
94
95
US_COND_DESTROY (wr -> has_job_cond );
95
96
96
- free (wr -> name );
97
-
98
97
pool -> job_destroy (wr -> job );
99
- }
98
+
99
+ free (wr -> name );
100
+ free (wr );
101
+ });
100
102
101
103
US_MUTEX_DESTROY (pool -> free_workers_mutex );
102
104
US_COND_DESTROY (pool -> free_workers_cond );
103
105
104
- free (pool -> workers );
105
106
free (pool );
106
107
}
107
108
108
109
us_worker_s * us_workers_pool_wait (us_workers_pool_s * pool ) {
109
- us_worker_s * ready_wr = NULL ;
110
-
111
110
US_MUTEX_LOCK (pool -> free_workers_mutex );
112
111
US_COND_WAIT_FOR (pool -> free_workers , pool -> free_workers_cond , pool -> free_workers_mutex );
113
112
US_MUTEX_UNLOCK (pool -> free_workers_mutex );
114
113
115
- if (pool -> oldest_wr && !atomic_load (& pool -> oldest_wr -> has_job )) {
116
- ready_wr = pool -> oldest_wr ;
117
- ready_wr -> job_timely = true;
118
- } else {
119
- for (uint index = 0 ; index < pool -> n_workers ; ++ index ) {
120
- us_worker_s * const wr = & pool -> workers [index ];
121
- if (
122
- !atomic_load (& wr -> has_job ) && (
123
- ready_wr == NULL
124
- || ready_wr -> job_start_ts < wr -> job_start_ts
125
- )
126
- ) {
127
- ready_wr = wr ;
128
- break ;
129
- }
114
+ us_worker_s * found = NULL ;
115
+ US_LIST_ITERATE (pool -> workers , wr , {
116
+ if (!atomic_load (& wr -> has_job ) && (found == NULL || found -> job_start_ts <= wr -> job_start_ts )) {
117
+ found = wr ;
130
118
}
131
- assert (ready_wr != NULL );
132
- ready_wr -> job_timely = false; // Освободился воркер, получивший задание позже (или самый первый при самом первом захвате)
119
+ });
120
+ assert (found != NULL );
121
+ US_LIST_REMOVE (pool -> workers , found );
122
+ US_LIST_APPEND (pool -> workers , found ); // Перемещаем в конец списка
123
+
124
+ found -> job_timely = (found -> job_start_ts > pool -> job_timely_ts );
125
+ if (found -> job_timely ) {
126
+ pool -> job_timely_ts = found -> job_start_ts ;
133
127
}
134
- return ready_wr ;
128
+ return found ;
135
129
}
136
130
137
- void us_workers_pool_assign (us_workers_pool_s * pool , us_worker_s * ready_wr /*, void *job*/ ) {
138
- if (pool -> oldest_wr == ready_wr ) {
139
- pool -> oldest_wr = pool -> oldest_wr -> next_wr ;
140
- }
141
- if (pool -> oldest_wr == NULL ) {
142
- pool -> oldest_wr = ready_wr ;
143
- pool -> latest_wr = pool -> oldest_wr ;
144
- } else {
145
- if (ready_wr -> next_wr != NULL ) {
146
- ready_wr -> next_wr -> prev_wr = ready_wr -> prev_wr ;
147
- }
148
- if (ready_wr -> prev_wr != NULL ) {
149
- ready_wr -> prev_wr -> next_wr = ready_wr -> next_wr ;
150
- }
151
- ready_wr -> prev_wr = pool -> latest_wr ;
152
- pool -> latest_wr -> next_wr = ready_wr ;
153
- pool -> latest_wr = ready_wr ;
154
- }
155
- pool -> latest_wr -> next_wr = NULL ;
156
-
157
- US_MUTEX_LOCK (ready_wr -> has_job_mutex );
158
- //ready_wr->job = job;
159
- atomic_store (& ready_wr -> has_job , true);
160
- US_MUTEX_UNLOCK (ready_wr -> has_job_mutex );
161
- US_COND_SIGNAL (ready_wr -> has_job_cond );
131
+ void us_workers_pool_assign (us_workers_pool_s * pool , us_worker_s * wr ) {
132
+ US_MUTEX_LOCK (wr -> has_job_mutex );
133
+ atomic_store (& wr -> has_job , true);
134
+ US_MUTEX_UNLOCK (wr -> has_job_mutex );
135
+ US_COND_SIGNAL (wr -> has_job_cond );
162
136
163
137
US_MUTEX_LOCK (pool -> free_workers_mutex );
164
138
pool -> free_workers -= 1 ;
165
139
US_MUTEX_UNLOCK (pool -> free_workers_mutex );
166
140
}
167
141
168
- ldf us_workers_pool_get_fluency_delay (us_workers_pool_s * pool , const us_worker_s * ready_wr ) {
169
- const ldf approx_job_time = pool -> approx_job_time * 0.9 + ready_wr -> last_job_time * 0.1 ;
142
+ ldf us_workers_pool_get_fluency_delay (us_workers_pool_s * pool , const us_worker_s * wr ) {
143
+ const ldf approx_job_time = pool -> approx_job_time * 0.9 + wr -> last_job_time * 0.1 ;
170
144
171
145
US_LOG_VERBOSE ("Correcting pool's %s approx_job_time: %.3Lf -> %.3Lf (last_job_time=%.3Lf)" ,
172
- pool -> name , pool -> approx_job_time , approx_job_time , ready_wr -> last_job_time );
146
+ pool -> name , pool -> approx_job_time , approx_job_time , wr -> last_job_time );
173
147
174
148
pool -> approx_job_time = approx_job_time ;
175
149
@@ -203,7 +177,6 @@ static void *_worker_thread(void *v_worker) {
203
177
wr -> job_start_ts = job_start_ts ;
204
178
wr -> last_job_time = us_get_now_monotonic () - wr -> job_start_ts ;
205
179
}
206
- //wr->job = NULL;
207
180
atomic_store (& wr -> has_job , false);
208
181
}
209
182
0 commit comments