queue implement

queue implement reminder.




#ifndef __FF_QUEUE_TEMPLATE__
#define __FF_QUEUE_TEMPLATE__


#include <stdio.h>
#include <errno.h>
#include <assert.h>


#include <SDL/SDL.h>
#include <SDL/SDL_mutex.h>
#include <SDL/SDL_thread.h>


#if 0
#define LOCK_TRACE(tag) av_log(NULL, AV_LOG_DEBUG, "[%s-%d]%s.\n", __func__, __LINE__, tag)
#else
#define LOCK_TRACE(arg...) ((void)0)
#endif


#ifdef __NOTE__   //note only
#define _queue_peek_readable
#define _queue_init 
#define _queue_flush 
#define _queue_abort 
#define _queue_destory 
#define _queue_nb_remaining 
#define _queue_push 
#define _queue_pop 
#define _queue_peek_writable 
#endif




#define QUEUE_TEMPLATE(TYPE)            \
typedef struct TYPE ## _QUEUE {         \
    TYPE **frame;                       \
    int rindex;                         \
    int windex;                         \
    int size;                           \
    int max_size;                       \
    int abort_request;                  \
    SDL_mutex *mutex;                   \
    SDL_cond  *cond;                    \
    TYPE *(*alloc_func)(void);              \
    void (*free_func)(void* unit);      \
}TYPE ## _QUEUE;                        \
                                        \
static inline int TYPE ##_queue_init(TYPE ## _QUEUE *q, int max_size, TYPE *(*alloc_func)(), void (*free_func)(void* unit))        \
{                                                       \
    int i;                                              \
    memset(q, 0, sizeof(TYPE ## _QUEUE));               \
    if (!(q->mutex = SDL_CreateMutex()))                \
        return -ENOMEM;                                 \
    if (!(q->cond = SDL_CreateCond()))                  \
        return -ENOMEM;                                 \
    q->max_size = max_size;                             \
    q->alloc_func = alloc_func;                         \
    q->free_func  = free_func;                          \
    q->frame = (TYPE**)malloc(sizeof(TYPE*)*max_size);   \
    if (!q->frame)                                      \
        return -ENOMEM;                                 \
    for (i=0; i<max_size; i++){                         \
        q->frame[i] = alloc_func ? (alloc_func()) : (TYPE*)malloc(sizeof(TYPE));\
        if (!q->frame[i])                               \
            return -ENOMEM;                             \
    }                                                   \
    return 0;                                           \
}                                                       \
                                                        \
                                                        \
static inline void TYPE ##_queue_flush(TYPE ## _QUEUE *q)      \
{                                                       \
    SDL_LockMutex(q->mutex);                            \
            LOCK_TRACE("Lock");                                       \
    q->size = 0;                                        \
    q->rindex = 0;                                      \
    q->windex = 0;                                      \
    SDL_UnlockMutex(q->mutex);                          \
            LOCK_TRACE("UNLock");                                       \
}                                                       \
                                                        \
static inline void TYPE ##_queue_abort(TYPE ## _QUEUE *q)      \
{                                                       \
            LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    q->abort_request = 1;                               \
    SDL_CondSignal(q->cond);                            \
    SDL_UnlockMutex(q->mutex);                          \
            LOCK_TRACE("UNLock");                                       \
}                                                       \
                                                        \
static inline void TYPE ##_queue_destory(TYPE ## _QUEUE *q)           \
{                                                       \
    int i;                                              \
    LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    for (i = 0; i < q->max_size; i++) {                 \
        if (q->free_func)                               \
            q->free_func(q->frame[i]);                  \
        else                                            \
            free(q->frame[i]);                          \
    }                                                   \
    free(q->frame);                                     \
    SDL_UnlockMutex(q->mutex);                          \
            LOCK_TRACE("UNLock");                                       \
    SDL_DestroyMutex(q->mutex);                         \
    SDL_DestroyCond(q->cond);                           \
}                                                       \
                                                        \
static inline int TYPE ##_queue_nb_remaining(TYPE ## _QUEUE *q)         \
    {return q->size;}                                    \
                                                        \
static inline void TYPE ##_queue_signal(TYPE ## _QUEUE *q)                 \
{                                                       \
    SDL_LockMutex(q->mutex);                            \
            LOCK_TRACE("Lock");                                       \
    SDL_CondSignal(q->cond);                            \
    SDL_UnlockMutex(q->mutex);                            \
            LOCK_TRACE("UNLock");                                       \
}                                                       \
                                                        \
static inline void TYPE ##_queue_push(TYPE ## _QUEUE *q)                   \
{                                                       \
    if (++q->windex == q->max_size)                     \
        q->windex = 0;                                  \
        LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    q->size++;                                          \
    SDL_CondSignal(q->cond);                            \
    SDL_UnlockMutex(q->mutex);                          \
        LOCK_TRACE("UNLock");                                       \
}                                                       \
                                                        \
static inline void *TYPE ##_queue_peek_writable(TYPE ## _QUEUE *q, int block)     \
{                                                       \
        LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    while (q->size >= q->max_size && !q->abort_request) \
    {                                                   \
        if (block){                                     \
            LOCK_TRACE("Wait");                         \
            SDL_CondWait(q->cond, q->mutex);            \
        }                                               \
        else{                                           \
            SDL_UnlockMutex(q->mutex);                  \
            LOCK_TRACE("UNLock");                       \
            return NULL;                                \
        }                                               \
    }                                                   \
    SDL_UnlockMutex(q->mutex);                          \
    LOCK_TRACE("UNLock");                                       \
    return (q->abort_request) ? NULL : q->frame[q->windex];     \
}                                                       \
                                                        \
static inline void TYPE ##_queue_pop(TYPE ## _QUEUE *q)                            \
{                                                       \
    if (++q->rindex == q->max_size)                     \
        q->rindex = 0;                                  \
        LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    q->size--;                                          \
        LOCK_TRACE("Signal");                         \
    SDL_CondSignal(q->cond);                            \
    SDL_UnlockMutex(q->mutex);                          \
        LOCK_TRACE("UNLock");                                       \
}                                                       \
                                                        \
static inline void *TYPE ##_queue_peek_readable(TYPE ## _QUEUE *q, int block) \
{                                                       \
        LOCK_TRACE("Lock");                                       \
    SDL_LockMutex(q->mutex);                            \
    while (q->size <= 0 && !q->abort_request)           \
    {                                                   \
        if (block){                                     \
            LOCK_TRACE("Wait");                         \
            SDL_CondWait(q->cond, q->mutex);            \
        }                                               \
        else{                                           \
            SDL_UnlockMutex(q->mutex);                  \
            LOCK_TRACE("UNLock");                       \
            return NULL;                                \
        }                                               \
    }                                                   \
    SDL_UnlockMutex(q->mutex);                          \
            LOCK_TRACE("UNLock");                                       \
    return (q->abort_request) ? NULL : q->frame[q->rindex];     \
}






#ifdef __TEST__QUEUE__
typedef int MINT;


MINT *alloc_mint()
{
    MINT *ptr = (MINT*)malloc(sizeof(MINT));
    memset(ptr, 0, sizeof(MINT));
    return ptr;
}


void free_mint(void *mint)
{
    free((int *)mint);
}




QUEUE_TEMPLATE(MINT);


MINT_QUEUE myqueue;


#define MAX_QUEUE_SIZE 32


int main(int argc, char *argv[])
{
    int i=0;
    int size = 0;
    MINT *unit;
    //MINT_queue_init(&myqueue, 8, NULL, NULL);
    MINT_queue_init(&myqueue, MAX_QUEUE_SIZE, alloc_mint, free_mint);
    assert(MINT_queue_nb_remaining(&myqueue) == 0);


    for (i=0;i<MAX_QUEUE_SIZE/2;i++)
    {
        if ((unit = MINT_queue_peek_writable(&myqueue, 0)) != NULL)
        {
            *unit = i;
            MINT_queue_push(&myqueue);
            assert((MINT_queue_nb_remaining(&myqueue) == (i+1)) ||
                (printf("nb[%d]=%d.\n", MINT_queue_nb_remaining(&myqueue), i+1), 0));
        }
    }
    assert(MINT_queue_nb_remaining(&myqueue) == MAX_QUEUE_SIZE/2);


    size = MINT_queue_nb_remaining(&myqueue);
    for (i=0;i<MAX_QUEUE_SIZE/2;i++)
    {
        if ((unit = MINT_queue_peek_readable(&myqueue, 0)) != NULL)
        {
            assert((*unit == i) ||
                (printf("unit[%d]=%d.\n", *unit, i), 0));
            MINT_queue_pop(&myqueue);
            assert(MINT_queue_nb_remaining(&myqueue) == size-1-i);
        }
    }
    assert(MINT_queue_nb_remaining(&myqueue) == 0);


    MINT_queue_flush(&myqueue);
    assert(MINT_queue_nb_remaining(&myqueue) == 0);


    printf("nb after flush: %d.\n", MINT_queue_nb_remaining(&myqueue));
    MINT_queue_destory(&myqueue);




    return 0;
}
#endif




#endif


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值