#include "./workqueue/uplat_zynq7000/cache2data/list.h"
#include
#include
#include
#include
#include
#include
#include
#include
struct task_queue {
// TODO: Mutex from other thread
char taskName[32];
pthread_mutex_t mutex;
pthread_cond_t cond;
bool empty;
void *task_args;
void *deal_callback_args;
int32_t (*deal_callback)(void *, size_t);
int32_t (*task)(void *, int32_t (*deal_callback)(void *, size_t), void *);
struct LIST_NODE node;
};
static inline int32_t setupTaskQueue(struct task_queue *task) {
if (task == 0) {
return -2;
}
task->empty = true;
task->node.next = &task->node;
task->node.prev = &task->node;
pthread_mutex_init(&task->mutex, 0);
pthread_cond_init(&task->cond, 0);
return 0;
}
// NOTE: add mutex lock
static inline int32_t taskQueuePush(
struct task_queue *task, const char *taskName, void *task_args,
void *deal_callback_args,
int32_t (*task_cb)(void *, int32_t (*deal_callback)(void *, size_t),
void *),
int32_t (*deal_callback)(void *, size_t)) {
if (task == 0) {
return -1;
}
struct task_queue *new_task = calloc(sizeof(struct task_queue), 1);
if (new_task == 0) {
return -3;
}
task->empty = false;
bzero(new_task->taskName, sizeof(new_task->taskName));
strcpy(new_task->taskName, taskName);
new_task->task_args = task_args;
new_task->deal_callback_args = deal_callback_args;
new_task->task = task_cb;
list_add(&new_task->node, &task->node);
pthread_mutex_lock(&task->mutex);
pthread_cond_broadcast(&task->cond);
pthread_mutex_unlock(&task->mutex);
return 0;
}
static inline int32_t taskQueueDeal(struct task_queue *task) {
if (task == 0) {
return -1;
}
struct task_queue *cur;
struct LIST_NODE *node;
struct LIST_NODE *safe_node;
while (true) {
while (task->empty) {
pthread_mutex_lock(&task->mutex);
pthread_cond_wait(&task->cond, &task->mutex);
pthread_mutex_unlock(&task->mutex);
}
node = task->node.next;
while (node != &task->node) {
cur = container_of(node, struct task_queue, node);
if (cur != 0) {
if (cur->task != 0) {
cur->task(cur->task_args, cur->deal_callback,
cur->deal_callback_args);
}
}
list_del(node);
node = node->next;
free(cur);
cur = 0;
}
task->empty = true;
}
return 0;
}
static inline int32_t isTaskQueueEmpty(struct task_queue *task) {
if (task == 0) {
return -1;
}
return task->empty;
}
int32_t task_1(void *args, int32_t (*deal_callback)(void *, size_t),
void *_args) {
printf("%s\n", __func__);
return 0;
}
int32_t task_2(void *args, int32_t (*deal_callback)(void *, size_t),
void *_args) {
printf("%s\n", __func__);
return 0;
}
void *all(void *p) {
struct task_queue *q = p;
while (1) {
usleep(500);
taskQueuePush(q, "task 111", 0, 0, task_1, 0);
taskQueuePush(q, "task 112", 0, 0, task_2, 0);
}
}
int32_t threading(struct task_queue *q) {
pthread_t tid;
return pthread_create(&tid, 0, all, q);
}
int main(void) {
struct task_queue queue;
setupTaskQueue(&queue);
threading(&queue);
taskQueueDeal(&queue);
return 0;
}
生产的速度要小于,消化的速度
消化不良就溢出了
我链表的释放时没有问题的,忽略了生产消化的问题
增加处理上限,超过门限,等待处理完毕,才能继续加入队列
或者自动添加一个延时
#include "./workqueue/uplat_zynq7000/cache2data/list.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct task_queue {
// TODO: Mutex from other thread
clock_t start;
char taskName[32];
pthread_mutex_t mutex;
pthread_cond_t cond;
bool empty;
bool busy;
void *task_args;
void *deal_callback_args;
int32_t (*deal_callback)(void *, size_t);
int32_t (*task)(void *, int32_t (*deal_callback)(void *, size_t), void *);
clock_t end;
struct LIST_NODE node;
};
static inline int32_t setupTaskQueue(struct task_queue *task) {
if (task == 0) {
return -2;
}
task->empty = true;
task->start = 0;
task->end = 1;
task->node.next = &task->node;
task->node.prev = &task->node;
pthread_mutex_init(&task->mutex, 0);
pthread_cond_init(&task->cond, 0);
return 0;
}
// NOTE: add mutex lock
static inline int32_t taskQueuePush(
struct task_queue *task, const char *taskName, void *task_args,
void *deal_callback_args,
int32_t (*task_cb)(void *, int32_t (*deal_callback)(void *, size_t),
void *),
int32_t (*deal_callback)(void *, size_t)) {
if (task == 0) {
return -1;
}
usleep(abs((int)(task->end - task->start)) * 100);
struct task_queue *new_task = calloc(sizeof(struct task_queue), 1);
if (new_task == 0) {
return -3;
}
task->empty = false;
bzero(new_task->taskName, sizeof(new_task->taskName));
strcpy(new_task->taskName, taskName);
new_task->task_args = task_args;
new_task->deal_callback_args = deal_callback_args;
new_task->task = task_cb;
list_add(&new_task->node, &task->node);
pthread_mutex_lock(&task->mutex);
pthread_cond_broadcast(&task->cond);
pthread_mutex_unlock(&task->mutex);
return 0;
}
static inline int32_t taskQueueDeal(struct task_queue *task) {
if (task == 0) {
return -1;
}
struct task_queue *cur;
struct LIST_NODE *node;
struct LIST_NODE *safe_node;
while (true) {
while (task->empty) {
pthread_mutex_lock(&task->mutex);
pthread_cond_wait(&task->cond, &task->mutex);
pthread_mutex_unlock(&task->mutex);
}
node = task->node.next;
while (node != &task->node) {
cur = container_of(node, struct task_queue, node);
if (cur != 0) {
task->start = clock();
if (cur->task != 0) {
cur->task(cur->task_args, cur->deal_callback,
cur->deal_callback_args);
}
task->end = clock();
}
list_del(node);
node = node->next;
free(cur);
cur = 0;
}
task->empty = true;
}
return 0;
}
static inline int32_t isTaskQueueEmpty(struct task_queue *task) {
if (task == 0) {
return -1;
}
return task->empty;
}
int32_t task_1(void *args, int32_t (*deal_callback)(void *, size_t),
void *_args) {
printf("%s\n", __func__);
return 0;
}
int32_t task_2(void *args, int32_t (*deal_callback)(void *, size_t),
void *_args) {
printf("%s\n", __func__);
return 0;
}
void *all(void *p) {
struct task_queue *q = p;
while (1) {
taskQueuePush(q, "task 111", 0, 0, task_1, 0);
taskQueuePush(q, "task 112", 0, 0, task_2, 0);
}
}
int32_t threading(struct task_queue *q) {
pthread_t tid;
return pthread_create(&tid, 0, all, q);
}
int main(void) {
struct task_queue queue;
setupTaskQueue(&queue);
threading(&queue);
taskQueueDeal(&queue);
return 0;
}