Last active
August 29, 2015 14:17
-
-
Save seppo0010/edd15abb46ec0b9ddc8f to your computer and use it in GitHub Desktop.
multithreaded task-queue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <pthread.h> | |
struct queue_obj { struct queue_obj *next; void *obj_to_free; }; | |
struct queue_obj* firstElement; | |
struct queue_obj* lastElement; | |
long goal; | |
void *consumer(void *arg) { | |
long freed = 0; | |
while (freed < goal) { | |
if (firstElement->obj_to_free != NULL) { | |
freed++; | |
} | |
free(firstElement->obj_to_free); | |
firstElement->obj_to_free = NULL; | |
if (firstElement->next) { | |
struct queue_obj* oldFirstElement = firstElement; | |
firstElement = firstElement->next; | |
free(oldFirstElement); | |
} else { | |
usleep(5000); | |
} | |
} | |
free(firstElement); | |
return NULL; | |
} | |
// produce must always be called from the same thread | |
void produce(void *obj_to_free) { | |
struct queue_obj* new_obj = malloc(sizeof(*new_obj)); | |
new_obj->next = NULL; | |
new_obj->obj_to_free = obj_to_free; | |
lastElement->next = new_obj; | |
lastElement = new_obj; | |
} | |
int main(int argc, char *argv[]) { | |
goal = strtol(argv[1], NULL, 10); | |
pthread_t thread; | |
pthread_create(&thread, NULL, consumer, NULL); | |
firstElement = lastElement = malloc(sizeof(*firstElement)); | |
firstElement->next = NULL; | |
firstElement->obj_to_free = NULL; | |
long i; | |
void *garbage; | |
for (i = 0; i < goal; i++) { | |
garbage = malloc(1); | |
produce(garbage); | |
} | |
pthread_join(thread, NULL); | |
return 0; | |
} | |
// $ cc main.c -o main && valgrind --leak-check=full --show-reachable=yes ./main 10000 | |
// ==7359== Memcheck, a memory error detector | |
// ==7359== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. | |
// ==7359== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info | |
// ==7359== Command: ./main 10000 | |
// ==7359== | |
// --7359-- run: /usr/bin/dsymutil "./main" | |
// warning: no debug symbols in executable (-arch x86_64) | |
// ==7359== | |
// ==7359== HEAP SUMMARY: | |
// ==7359== in use at exit: 25,602 bytes in 373 blocks | |
// ==7359== total heap usage: 20,450 allocs, 20,077 frees, 201,562 bytes allocated | |
// ==7359== | |
// ==7359== LEAK SUMMARY: | |
// ==7359== definitely lost: 0 bytes in 0 blocks | |
// ==7359== indirectly lost: 0 bytes in 0 blocks | |
// ==7359== possibly lost: 0 bytes in 0 blocks | |
// ==7359== still reachable: 0 bytes in 0 blocks | |
// ==7359== suppressed: 25,602 bytes in 373 blocks | |
// ==7359== | |
// ==7359== For counts of detected and suppressed errors, rerun with: -v | |
// ==7359== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 15) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment