1
1
/* *****************************************************
2
2
Copyright (c) 2011-2013 Percona LLC and/or its affiliates.
3
+ Copyright (c) 2022, MariaDB Corporation.
3
4
4
5
Compressing datasink implementation for XtraBackup.
5
6
@@ -32,11 +33,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
32
33
typedef struct {
33
34
pthread_t id;
34
35
uint num;
35
- pthread_mutex_t ctrl_mutex;
36
- pthread_cond_t ctrl_cond;
37
36
pthread_mutex_t data_mutex;
38
37
pthread_cond_t data_cond;
39
- my_bool started ;
38
+ pthread_cond_t done_cond ;
40
39
my_bool data_avail;
41
40
my_bool cancelled;
42
41
const char *from;
@@ -208,14 +207,13 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
208
207
209
208
thd = threads + i;
210
209
211
- pthread_mutex_lock (&thd->ctrl_mutex );
210
+ pthread_mutex_lock (&thd->data_mutex );
212
211
213
212
chunk_len = (len > COMPRESS_CHUNK_SIZE) ?
214
213
COMPRESS_CHUNK_SIZE : len;
215
214
thd->from = ptr;
216
215
thd->from_len = chunk_len;
217
216
218
- pthread_mutex_lock (&thd->data_mutex );
219
217
thd->data_avail = TRUE ;
220
218
pthread_cond_signal (&thd->data_cond );
221
219
pthread_mutex_unlock (&thd->data_mutex );
@@ -234,32 +232,30 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
234
232
thd = threads + i;
235
233
236
234
pthread_mutex_lock (&thd->data_mutex );
237
- while (thd->data_avail == TRUE ) {
238
- pthread_cond_wait (&thd->data_cond ,
235
+ while (! thd->to_len ) {
236
+ pthread_cond_wait (&thd->done_cond ,
239
237
&thd->data_mutex );
240
238
}
241
239
242
- xb_a (threads[i].to_len > 0 );
243
-
244
240
bool fail = ds_write (dest_file, " NEWBNEWB" , 8 ) ||
245
241
write_uint64_le (dest_file,
246
242
comp_file->bytes_processed );
247
- comp_file->bytes_processed += threads[i]. from_len ;
243
+ comp_file->bytes_processed += thd-> from_len ;
248
244
249
245
if (!fail) {
250
- fail = write_uint32_le (dest_file, threads[i]. adler ) ||
251
- ds_write (dest_file, threads[i]. to ,
252
- threads[i]. to_len );
246
+ fail = write_uint32_le (dest_file, thd-> adler ) ||
247
+ ds_write (dest_file, thd-> to ,
248
+ thd-> to_len );
253
249
}
254
250
255
- pthread_mutex_unlock (&threads[i].data_mutex );
251
+ thd->to_len = 0 ;
252
+ pthread_mutex_unlock (&thd->data_mutex );
256
253
257
254
if (fail) {
258
255
msg (" compress: write to the destination stream "
259
256
" failed." );
260
257
return 1 ;
261
258
}
262
- pthread_mutex_unlock (&threads[i].ctrl_mutex );
263
259
}
264
260
}
265
261
@@ -329,6 +325,24 @@ write_uint64_le(ds_file_t *file, ulonglong n)
329
325
return ds_write (file, tmp, sizeof (tmp));
330
326
}
331
327
328
+ static
329
+ void
330
+ destroy_worker_thread (comp_thread_ctxt_t *thd)
331
+ {
332
+ pthread_mutex_lock (&thd->data_mutex );
333
+ thd->cancelled = TRUE ;
334
+ pthread_cond_signal (&thd->data_cond );
335
+ pthread_mutex_unlock (&thd->data_mutex );
336
+
337
+ pthread_join (thd->id , NULL );
338
+
339
+ pthread_cond_destroy (&thd->data_cond );
340
+ pthread_cond_destroy (&thd->done_cond );
341
+ pthread_mutex_destroy (&thd->data_mutex );
342
+
343
+ my_free (thd->to );
344
+ }
345
+
332
346
static
333
347
comp_thread_ctxt_t *
334
348
create_worker_threads (uint n)
@@ -337,60 +351,36 @@ create_worker_threads(uint n)
337
351
uint i;
338
352
339
353
threads = (comp_thread_ctxt_t *)
340
- my_malloc (sizeof ( comp_thread_ctxt_t ) * n , MYF (MY_FAE));
354
+ my_malloc (n * sizeof *threads , MYF (MY_ZEROFILL| MY_FAE));
341
355
342
356
for (i = 0 ; i < n; i++) {
343
357
comp_thread_ctxt_t *thd = threads + i;
344
358
345
359
thd->num = i + 1 ;
346
- thd->started = FALSE ;
347
- thd->cancelled = FALSE ;
348
- thd->data_avail = FALSE ;
349
-
350
360
thd->to = (char *) my_malloc (COMPRESS_CHUNK_SIZE +
351
361
MY_QLZ_COMPRESS_OVERHEAD,
352
362
MYF (MY_FAE));
353
363
354
- /* Initialize the control mutex and condition var */
355
- if (pthread_mutex_init (&thd->ctrl_mutex , NULL ) ||
356
- pthread_cond_init (&thd->ctrl_cond , NULL )) {
357
- goto err;
358
- }
359
-
360
364
/* Initialize and data mutex and condition var */
361
365
if (pthread_mutex_init (&thd->data_mutex , NULL ) ||
362
- pthread_cond_init (&thd->data_cond , NULL )) {
366
+ pthread_cond_init (&thd->data_cond , NULL ) ||
367
+ pthread_cond_init (&thd->done_cond , NULL )) {
363
368
goto err;
364
369
}
365
370
366
- pthread_mutex_lock (&thd->ctrl_mutex );
367
-
368
371
if (pthread_create (&thd->id , NULL , compress_worker_thread_func,
369
372
thd)) {
370
373
msg (" compress: pthread_create() failed: "
371
374
" errno = %d" , errno);
372
- pthread_mutex_unlock (&thd->ctrl_mutex );
373
375
goto err;
374
376
}
375
377
}
376
378
377
- /* Wait for the threads to start */
378
- for (i = 0 ; i < n; i++) {
379
- comp_thread_ctxt_t *thd = threads + i;
380
-
381
- while (thd->started == FALSE )
382
- pthread_cond_wait (&thd->ctrl_cond , &thd->ctrl_mutex );
383
- pthread_mutex_unlock (&thd->ctrl_mutex );
384
- }
385
-
386
379
return threads;
387
380
388
381
err:
389
- while (i > 0 ) {
390
- comp_thread_ctxt_t *thd;
391
- i--;
392
- thd = threads + i;
393
- pthread_mutex_unlock (&thd->ctrl_mutex );
382
+ for (; i; i--) {
383
+ destroy_worker_thread (threads + i);
394
384
}
395
385
396
386
my_free (threads);
@@ -404,21 +394,7 @@ destroy_worker_threads(comp_thread_ctxt_t *threads, uint n)
404
394
uint i;
405
395
406
396
for (i = 0 ; i < n; i++) {
407
- comp_thread_ctxt_t *thd = threads + i;
408
-
409
- pthread_mutex_lock (&thd->data_mutex );
410
- threads[i].cancelled = TRUE ;
411
- pthread_cond_signal (&thd->data_cond );
412
- pthread_mutex_unlock (&thd->data_mutex );
413
-
414
- pthread_join (thd->id , NULL );
415
-
416
- pthread_cond_destroy (&thd->data_cond );
417
- pthread_mutex_destroy (&thd->data_mutex );
418
- pthread_cond_destroy (&thd->ctrl_cond );
419
- pthread_mutex_destroy (&thd->ctrl_mutex );
420
-
421
- my_free (thd->to );
397
+ destroy_worker_thread (threads + i);
422
398
}
423
399
424
400
my_free (threads);
@@ -430,26 +406,16 @@ compress_worker_thread_func(void *arg)
430
406
{
431
407
comp_thread_ctxt_t *thd = (comp_thread_ctxt_t *) arg;
432
408
433
- pthread_mutex_lock (&thd->ctrl_mutex );
434
-
435
409
pthread_mutex_lock (&thd->data_mutex );
436
410
437
- thd->started = TRUE ;
438
- pthread_cond_signal (&thd->ctrl_cond );
439
-
440
- pthread_mutex_unlock (&thd->ctrl_mutex );
441
-
442
411
while (1 ) {
443
- thd->data_avail = FALSE ;
444
- pthread_cond_signal (&thd->data_cond );
445
-
446
412
while (!thd->data_avail && !thd->cancelled ) {
447
413
pthread_cond_wait (&thd->data_cond , &thd->data_mutex );
448
414
}
449
415
450
416
if (thd->cancelled )
451
417
break ;
452
-
418
+ thd-> data_avail = FALSE ;
453
419
thd->to_len = qlz_compress (thd->from , thd->to , thd->from_len ,
454
420
&thd->state );
455
421
@@ -464,6 +430,7 @@ compress_worker_thread_func(void *arg)
464
430
465
431
thd->adler = adler32 (0x00000001 , (uchar *) thd->to ,
466
432
(uInt)thd->to_len );
433
+ pthread_cond_signal (&thd->done_cond );
467
434
}
468
435
469
436
pthread_mutex_unlock (&thd->data_mutex );
0 commit comments