improve queue interface

This commit is contained in:
c9s 2014-05-24 10:24:57 +08:00
parent 9c6902ed57
commit def79a810b
3 changed files with 42 additions and 33 deletions

View file

@ -25,10 +25,10 @@ typedef struct {
} queue; } queue;
// create and return the queue // create and return the queue
queue * queue_create(void); queue * queue_new(void);
// destory the queue (free all the memory associate with the que even the data) // destory the queue (free all the memory associate with the que even the data)
void queue_destroy(queue * que); void queue_free(queue * que);
// queue_push the data into queue // queue_push the data into queue

View file

@ -4,26 +4,32 @@
* *
* Distributed under terms of the MIT license. * Distributed under terms of the MIT license.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "r3_queue.h" #include "r3_queue.h"
#include "zmalloc.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/** /**
* create and return a new queue * Create and return a new queue
**/ **/
queue * queue_create() queue * queue_new()
{ {
queue * new_queue = malloc(sizeof(queue)); queue * q = zmalloc(sizeof(queue));
if(new_queue == NULL) { if(q == NULL) {
fprintf(stderr, "Malloc failed creating the que\n"); fprintf(stderr, "Malloc failed creating the que\n");
return NULL; return NULL;
} }
new_queue->first = NULL; q->first = NULL;
new_queue->last = NULL; q->last = NULL;
return new_queue; return q;
} }
void queue_destroy(queue * que) void queue_free(queue * que)
{ {
if(que == NULL) { if(que == NULL) {
return; return;
@ -32,26 +38,26 @@ void queue_destroy(queue * que)
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
if(que->first == NULL) { if(que->first == NULL) {
// ("que->first == NULL .... \n"); // ("que->first == NULL .... \n");
free(que); zfree(que);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
return; return;
} }
// ("que is there lets try to free it...\n"); // ("que is there lets try to free it...\n");
queue_node * _node = que->first; queue_node * qn = que->first;
while(_node != NULL) { while(qn != NULL) {
// freeing the data coz it's on the heap and no one to free it // freeing the data coz it's on the heap and no one to free it
// except for this one // except for this one
// ("freeing : %s\n", (char *)_node->data); // ("freeing : %s\n", (char *)qn->data);
free(_node->data); zfree(qn->data);
queue_node *tmp = _node->next; queue_node *tmp = qn->next;
free(_node); zfree(qn);
_node = tmp; qn = tmp;
} }
free(que); zfree(que);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
@ -62,8 +68,8 @@ void queue_destroy(queue * que)
*/ */
int queue_push(queue * que, void * data) int queue_push(queue * que, void * data)
{ {
queue_node * new_node = malloc(sizeof(queue_node)); queue_node * new_node = zmalloc(sizeof(queue_node));
if(new_node == NULL) { if (new_node == NULL) {
fprintf(stderr, "Malloc failed creating a queue_node\n"); fprintf(stderr, "Malloc failed creating a queue_node\n");
return -1; return -1;
} }
@ -81,7 +87,6 @@ int queue_push(queue * que, void * data)
que->last = new_node; que->last = new_node;
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
@ -102,20 +107,22 @@ void * queue_pop(queue * que)
} }
void * data; void * data;
queue_node * _node = que->first; queue_node * qn = que->first;
if (que->first == que->last) { if (que->first == que->last) {
que->first = NULL; que->first = NULL;
que->last = NULL; que->last = NULL;
} else { } else {
que->first = _node->next; que->first = qn->next;
} }
data = _node->data; data = qn->data;
// print("Freeing _node@ %p", _node); // print("Freeing qn@ %p", qn);
free(_node); zfree(qn);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
// print("Exiting queue_pop\n"); // print("Exiting queue_pop\n");
return data; return data;
} }

View file

@ -11,6 +11,9 @@
#include <pthread.h> #include <pthread.h>
#include <check.h> #include <check.h>
#include "r3.h"
#include "zmalloc.h"
#define number_of_threads 6 #define number_of_threads 6
#define number_of_threads_d 5 #define number_of_threads_d 5
@ -32,7 +35,7 @@ void * producer_thread(void * arg)
int i; int i;
srand(time(NULL)); srand(time(NULL));
for(i = 0; i < number; i++) { for(i = 0; i < number; i++) {
char * message = malloc(16); char * message = zmalloc(16);
snprintf(message, 15, "rand: %d", rand()); snprintf(message, 15, "rand: %d", rand());
queue_push(q, (void *)message); queue_push(q, (void *)message);
} }
@ -44,18 +47,17 @@ void * producer_thread(void * arg)
void * consumer_thread(void * args) void * consumer_thread(void * args)
{ {
queue * q = (queue *) args; queue * q = (queue *) args;
void * data; void * data;
while((data = queue_pop(q)) != NULL) { while((data = queue_pop(q)) != NULL) {
char * string = (char *)data; char * string = (char *)data;
free(data); zfree(data);
} }
return NULL; return NULL;
} }
START_TEST (test_queue) START_TEST (test_queue)
{ {
queue * q = queue_create(); queue * q = queue_new();
queue_push(q, (void*) 1); queue_push(q, (void*) 1);
int i = (int) queue_pop(q); int i = (int) queue_pop(q);
ck_assert_int_eq(i, 1); ck_assert_int_eq(i, 1);
@ -64,7 +66,7 @@ END_TEST
START_TEST (test_queue_threads) START_TEST (test_queue_threads)
{ {
queue * q = queue_create(); queue * q = queue_new();
pthread_t threads[number_of_threads]; pthread_t threads[number_of_threads];
pthread_t thread_d[number_of_threads_d]; pthread_t thread_d[number_of_threads_d];
@ -88,7 +90,7 @@ START_TEST (test_queue_threads)
for(i = 0; i < number_of_threads_d; i++) { for(i = 0; i < number_of_threads_d; i++) {
pthread_join(*(thread_d+i), NULL); pthread_join(*(thread_d+i), NULL);
} }
queue_destroy(q); queue_free(q);
} }
END_TEST END_TEST