Closed Taymindis closed 6 years ago
Hi Taymindis,
Thanks your report. I add memory barrier in this code can prevent this bug.
This memory barrier must in outside lfq_dequeue. I trying to add memory barrier into lfq_dequeue will no helpful.
I'll add a macro in header file make it easy to use.
/*Dequeue*/
//while ( (int_data = lfq_dequeue(&ctx)) != 0);
do {
int_data = lfq_dequeue(&ctx);
__sync_synchronize();
} while(int_data == 0);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
#include <sys/time.h>
#include "lfq.h"
struct lfq_ctx ctx;
struct timeval tv1, tv2;
// lfstack_t results;
void *worker(void *);
void *worker(void *arg)
{
long long i = 0;
int *int_data;
while (i < 1000000) {
int_data = (int*) malloc(sizeof(int));
assert(int_data != NULL);
*int_data = i++;
/*Enqueue*/
while (lfq_enqueue(&ctx, int_data) != 0);
/*Dequeue*/
//while ( (int_data = lfq_dequeue(&ctx)) != 0);
do {
int_data = lfq_dequeue(&ctx);
__sync_synchronize();
} while(int_data == 0);
// printf("%d\n", *int_data);
free(int_data);
}
return NULL;
}
int main(void)
{
int nthreads = sysconf(_SC_NPROCESSORS_ONLN); // Linux
int i;
lfq_init(&ctx, nthreads);
/* Spawn threads. */
pthread_t threads[nthreads];
printf("Using %d thread%s.\n", nthreads, nthreads == 1 ? "" : "s");
gettimeofday(&tv1, NULL);
for (i = 0; i < nthreads; i++)
pthread_create(threads + i, NULL, worker, NULL);
for (i = 0; i < nthreads; i++)
pthread_join(threads[i], NULL);
gettimeofday(&tv2, NULL);
printf ("Total time = %f seconds\n",
(double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
(double) (tv2.tv_sec - tv1.tv_sec));
lfq_clean(&ctx);
return 0;
}
==14613== Memcheck, a memory error detector ==14613== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==14613== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==14613== Command: ./a.out ==14613== Using 16 threads. Total time = 90.838795 seconds ==14613== ==14613== HEAP SUMMARY: ==14613== in use at exit: 64,000,000 bytes in 16,000,000 blocks ==14613== total heap usage: 32,000,020 allocs, 16,000,020 frees, 576,010,048 bytes allocated ==14613== ==14613== 12 bytes in 3 blocks are possibly lost in loss record 1 of 2 ==14613== at 0x4C29C23: malloc (vg_replace_malloc.c:299) ==14613== by 0x40091F: worker (in /home/booking/cground/lfqueue/a.out) ==14613== by 0x4E3DDD4: start_thread (in /usr/lib64/libpthread-2.17.so) ==14613== by 0x5150B3C: clone (in /usr/lib64/libc-2.17.so) ==14613== ==14613== 63,999,988 bytes in 15,999,997 blocks are definitely lost in loss record 2 of 2 ==14613== at 0x4C29C23: malloc (vg_replace_malloc.c:299) ==14613== by 0x40091F: worker (in /home/booking/cground/lfqueue/a.out) ==14613== by 0x4E3DDD4: start_thread (in /usr/lib64/libpthread-2.17.so) ==14613== by 0x5150B3C: clone (in /usr/lib64/libc-2.17.so) ==14613== ==14613== LEAK SUMMARY: ==14613== definitely lost: 63,999,988 bytes in 15,999,997 blocks ==14613== indirectly lost: 0 bytes in 0 blocks ==14613== possibly lost: 12 bytes in 3 blocks ==14613== still reachable: 0 bytes in 0 blocks ==14613== suppressed: 0 bytes in 0 blocks ==14613== ==14613== For counts of detected and suppressed errors, rerun with: -v ==14613== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Test program