Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1090906
  • 博文数量: 252
  • 博客积分: 4561
  • 博客等级: 上校
  • 技术积分: 2833
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-15 08:23
文章分类

全部博文(252)

文章存档

2015年(2)

2014年(1)

2013年(1)

2012年(16)

2011年(42)

2010年(67)

2009年(87)

2008年(36)

分类: C/C++

2008-04-09 10:24:54

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BUFFSIZE 100

#define ALIGN (sizeof(unsigned long) - 1)

struct mem_pool_head {
        struct mem_pool *head;
        struct mem_pool *tail;
};

struct mem_pool {
        struct mem_pool *next;
        size_t item_size; /* item size */
        size_t buff_size; /* data buffer size */
        size_t dlen; /* data length */
        size_t offset; /* pointer to next write position */
        char data[0]; /* pointer to buffer address = BUFFSIZE */
};

static struct mem_pool_head head = { .head = NULL, .tail = NULL };

static struct mem_pool_head dhead = { .head = NULL, .tail = NULL };

static struct mem_pool * alloc_item(void)
{
        struct mem_pool *item;
        size_t size;

        size = (sizeof(struct mem_pool) + BUFFSIZE + ALIGN) & ~ALIGN;
        item = (struct mem_pool *) malloc(size);
        if (item) {
                memset(item, '\0', size);
                item->dlen = 0;
                item->offset = 0;
                item->item_size = size;
                item->buff_size = BUFFSIZE;
                item->next = NULL;
        }

        return item;
}

static void item_enpool_tail(struct mem_pool_head *h, struct mem_pool *item)
{
        (h->head) ? (h->tail = h->tail->next = item) : (h->head = h->tail = item);
}

static void init_mem_pool(struct mem_pool_head *h, int poollen)
{
        struct mem_pool *item;

        for (int i = 0; i < poollen; ++i) {
                item = alloc_item();
                if (item)
                        item_enpool_tail(&head, item);
        }
}

static struct mem_pool * get_pool_head(struct mem_pool_head *pool)
{
        return pool->head;
}

static void item_enqueue_data_tail(struct mem_pool_head *dhead, struct mem_pool_head *pool, struct mem_pool *item)
{
        (dhead->head) ? (dhead->tail = dhead->tail->next = item) : (dhead->head = dhead->tail = item);
        (pool->head = pool->head->next) ? (pool->tail = pool->tail) : (pool->tail = NULL);
}

static void handle_input(void)
{
        size_t nread;
        struct mem_pool *item;

        for (;;) {
                item = get_pool_head(&head);
                if (item == NULL) {
                        printf("get_pool_head return NULL.\n");
                        break;
                }

                nread = read(STDIN_FILENO, item->data + item->offset, item->buff_size);
                if (nread == -1) {
                        perror("read");
                        continue;
                } else if (nread == 0) {
                        printf("receive EOF.\n");
                        break;
                }

                item->dlen += nread;
                item->offset += nread;
                item->buff_size -= nread;
                if (item->buff_size == 0)
                        item_enqueue_data_tail(&dhead, &head, item);
        }
}

static void output(struct mem_pool *item)
{
        write(STDOUT_FILENO, item->data, item->dlen);
}

static void reinit_item(struct mem_pool *item)
{
        memset(item, '\0', item->item_size);
        item->buff_size = BUFFSIZE;
        item->offset = 0;
        item->dlen = 0;
        item->next = NULL;
}

static void reset_dhead(struct mem_pool_head *dhead)
{
        (dhead->head = dhead->head->next) ? (dhead->tail = dhead->tail) : (dhead->tail = NULL);
}

static void handle_output(void)
{
        struct mem_pool *item;

        while ((item = get_pool_head(&dhead)) != NULL) {
                output(item);
                reset_dhead(&dhead);
                item_enpool_tail(&head, item); /* insert into buffer pool */
                reinit_item(item);
        }
}

int main(void)
{
        init_mem_pool(&head, 100);

        handle_input();

        handle_output();

        return 0;
}

阅读(990) | 评论(0) | 转发(0) |
0

上一篇:循环链表

下一篇:per-CPU 变量

给主人留下些什么吧!~~