blob: f8e00927ae0b76d6cd3b4a188e4a4c9796f02214 [file] [log] [blame]
/*
* Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
* Copyright (c) 2017 Intel Corporation
* Copyright (c) 2019, Infosys Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "thread_pool.h"
#include "tpool_queue.h"
/* allocates memory for node and initialize it */
static struct node *createnode(void *data)
{
struct node *entry;
entry = (struct node *)malloc(sizeof(struct node));
if(entry == NULL) {
#ifdef DEBUG
log_msg(LOG_ERROR, "failed to allocate memory\n");
#endif
return NULL;
}
entry->data = data;
entry->next = NULL;
return entry;
}
/* push data to queue tail */
int queue_push_tail(struct Queue *queue, void *data)
{
struct node *entry;
if(queue == NULL)
return -1;
entry = createnode(data);
if(entry == NULL) {
return -ENOMEM;
}
/* For empty queue */
if(queue->head == NULL)
queue->head = entry;
else
queue->tail->next = entry;
queue->tail = entry;
/* atomic increment */
__sync_fetch_and_add(&queue->length, 1);
return 0;
}
/* removes head and return its data */
void *queue_pop_head(struct Queue *queue)
{
void *data;
struct node *entry;
if(queue == NULL || queue->length == 0)
return NULL;
if(queue->head == NULL) {
return NULL;
}
entry = queue->head;
queue->head = queue->head->next;
data = entry->data;
/* atomic decrement */
__sync_fetch_and_sub(&queue->length, 1);
free(entry);
return data;
}
int queue_get_length(struct Queue *queue)
{
if (queue == NULL)
return 0;
return queue->length;
}
struct Queue *queue_new()
{
struct Queue *queue;
queue = (struct Queue *)malloc(sizeof(struct Queue));
if(queue == NULL) {
#ifdef DEBUG
log_msg(LOG_ERROR, "failed to allocate memory\n");
#endif
return NULL;
}
queue->length = 0;
queue->head = NULL;
queue->tail = NULL;
return queue;
}
void queue_destroy(struct Queue *queue, QueueDataFreeFunc function)
{
struct node *tmp;
if(queue == NULL || queue->length == 0)
{
free(queue);
return;
}
if(queue->head == NULL)
free(queue);
else {
tmp = queue->head;
while(queue->head != NULL) {
tmp = queue->head->next;
if (function != NULL)
function(queue->head->data);
free(queue->head);
queue->head=tmp;
}
}
}