📄 que.c
字号:
/* * This piece of code is totally free. If any pitfalls found, * please feel free to contact me at jetmotor@21cn.com * THANKS A LOT! */#include <string.h>#include "que.h"int32_t pool_init(pool_t *p){ pthread_mutex_init(&p->mutex, NULL); p->count = 0; INIT_LIST_HEAD(&p->link); return 0;}int32_t softq_init(softq_t *sq){ pthread_mutex_init(&sq->mutex, NULL); sq->count = 0; sq->size = 0; INIT_LIST_HEAD(&sq->link); return 0;}/* return: 0, if OK. -1, if enque fails, which means the calling thread may drop the sdu. */int32_t softq_enque_tail(softq_t *sq, wxbuff_t *wxb){ pthread_mutex_lock(&sq->mutex); if ( sq->count == 0xffffffff ) { pthread_mutex_unlock(&sq->mutex); return -1; } list_add_tail(&wxb->junior, &sq->link); sq->count++; sq->size += wxb->len; pthread_mutex_unlock(&sq->mutex); return 0;}/* return: 0, if OK. * -1, if enque fails, which means the calling thread may drop the sdu. * */int32_t softq_enque_head(softq_t *sq, wxbuff_t *wxb){ pthread_mutex_lock(&sq->mutex); if ( sq->count == 0xffffffff ) { pthread_mutex_unlock(&sq->mutex); return -1; } list_add(&wxb->junior, &sq->link); sq->count++; sq->size += wxb->len; pthread_mutex_unlock(&sq->mutex); return 0;}/* return: the first sdu in the corresponding softque. * NULL, if softque has been already empty, but this scenario is almost impossible. */wxbuff_t * softq_deque(softq_t *sq){ wxbuff_t *wxb; pthread_mutex_lock(&sq->mutex); if ( sq->count == 0 ) { pthread_mutex_unlock(&sq->mutex); return NULL; } wxb = list_entry(sq->link.next, wxbuff_t, junior); list_del(sq->link.next); sq->count--; sq->size -= wxb->len; pthread_mutex_unlock(&sq->mutex); return wxb;}/* return: the whole mbuffer list that the corresponding softque holds. * NULL, if softque has already been empty. */wxbuff_t * softq_dump(softq_t *sq)/*清空softq 队列*/{ wxbuff_t *wxblist; pthread_mutex_lock(&sq->mutex); if ( sq->count == 0 ) { pthread_mutex_unlock(&sq->mutex); return NULL; } wxblist = list_entry(sq->link.next, wxbuff_t, junior); list_del_init(&sq->link); sq->count = 0; sq->size = 0; pthread_mutex_unlock(&sq->mutex); return wxblist;}int32_t ringq_init(ringq_t *rq){ if ( sem_init(&rq->resource, 0, 0) < 0 ) return -1; pthread_mutex_init(&rq->mutex, NULL); rq->count = 0; INIT_LIST_HEAD(&rq->link); return 0;}int32_t ringq_enque(ringq_t *rq, struct list_head *new){ pthread_mutex_lock(&rq->mutex); if ( rq->count == 0xffffffff ) { pthread_mutex_unlock(&rq->mutex); return -1; } rq->count++; list_add_tail(new, &rq->link); pthread_mutex_unlock(&rq->mutex); sem_post(&rq->resource); return 0;}struct list_head * ringq_deque(ringq_t *rq){ struct list_head *entry; sem_wait(&rq->resource); pthread_mutex_lock(&rq->mutex); rq->count--; entry = rq->link.next; list_del(entry); pthread_mutex_unlock(&rq->mutex); return entry;}/* `ring_enque_simple' and `ring_dump' are especially for `task_[du]l_sched' and `task_phy_tx' thread. * No semaphore, No mutex. * * The synchronization bwteen `task_dl_sched' and `task_phy_tx' is a little tedious. * 1. `task_phy_tx' receives a timer interrupt from PHY, that is, it's the time of sending * the downlink bursts for this frame now. * 2. After sending all the downlink bursts to PHY, `task_phy_tx' infoms `task_dl_sched' & * `task_ul_sched' that it's the time to perform scheduling for the next frame; and * you two guys must act ASAP, because you get only no more than XXms. * 3. After `task_dl_sched' and `task_ul_sched' finishing scheduling job, the bursts for * the next frame will be inserted into the ringque. But they don't inform `task_phy_tx' * of this, because it's that timer that tell him when to send. */int32_t ringq_enque_simple(ringq_t *rq, struct list_head *new){ if ( rq->count == 0xffffffff ) return -1; rq->count++; list_add_tail(new, &rq->link); return 0;}struct list_head * ringq_dump(ringq_t *rq){ struct list_head *entry; if ( rq->count == 0 ) return NULL; entry = rq->link.next; list_del_init(&rq->link); rq->count = 0; return entry;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -