Skip to content

Instantly share code, notes, and snippets.

@seppo0010
Last active August 29, 2015 14:17
Show Gist options
  • Save seppo0010/edd15abb46ec0b9ddc8f to your computer and use it in GitHub Desktop.
Save seppo0010/edd15abb46ec0b9ddc8f to your computer and use it in GitHub Desktop.
multithreaded task-queue
#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