⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ubuffer.c

📁 nandflash文件系统源代码
💻 C
字号:
/*
    Copyright (C) 2005-2008  Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/
/** 
 * \file ubuffer.c
 * \brief Implement static, low cost, hight performance and fixed size buffer manager.
 *
 *	\author	Created by Ricky Zheng
 */
 
/******************************************************************************************
*	include files 
*******************************************************************************************/
#include "uffs/ubuffer.h"
#include "uffs/uffs_os.h"
#include <string.h>

/*

usage:

  #define NODE_SIZE	32
  #define NODE_NUMS	1024

  static int my_data_buf[NODE_SIZE * NODE_NUMS / sizeof(int)];
  static struct ubufm dis;

  dis.node_pool = &my_data_buf;
  dis.node_size = NODE_SIZE;
  dis.node_nums = NODE_NUMS;

  uBufInit(&dis);

  void * p;
  p = uBufGet(&dis);
  ...
  uBufPut(p, &dis);

notice:
	NODE_SIZE's lowest 2 bit must be 0, and NODE_SIZE must be large then or equal to 4.
	NODE_NUM must be larger than 1.

*/

static int uBufInitLock(struct ubufm *dis)
{
	if (!dis->lock) {
		dis->lock = uffs_SemCreate(1);
	}
	return 0;
}

static int uBufReleaseLock(struct ubufm *dis)
{
	if (dis->lock) {
		if (uffs_SemDelete(dis->lock) < 0) {
			return -1;
		}
		else {
			dis->lock = 0;
		}
	}	
	return 0;
}

static int uBufLock(struct ubufm *dis)
{
	return uffs_SemWait(dis->lock);
}

static int uBufUnlock(struct ubufm *dis)
{
	return uffs_SemSignal(dis->lock);
}

/* init ubuffer data structure with given descriptor */
int uBufInit(struct ubufm *dis)
{
	unsigned int i;
	int *p1, *p2;

	if(dis == NULL) return -1;
	if(dis->node_nums < 1) return -1;

	uBufInitLock(dis);
	uBufLock(dis);
	//initialize freeList. 
	dis->freeList = dis->node_pool;
	p1 = p2 = (int *)(dis->node_pool);
	for(i = 1; i < dis->node_nums; i++) {
		p2 = (int *)((char *)(dis->node_pool) + i * dis->node_size);
		*p1 = (int)p2;
		p1 = p2;
	}
	*p2 = (int)NULL;	//end of freeList
	uBufUnlock(dis);

	return 0;
}

/** release descriptor, delete lock **/
int uBufRelease(struct ubufm *dis)
{
	uBufReleaseLock(dis);
	return 0;
}


/* get buffer from pool */
void * uBufGet(struct ubufm *dis)
{
	void *p;

	p = dis->freeList;
	if(p) {
		dis->freeList = (void *)(*((int *)(dis->freeList)));
	}
	return p;
}

/* get buffer from pool
 * this is Critical protect version,
 * you should use this version when multi-therad 
 * access the same buffer pool
 */
void * uBufGetCt(struct ubufm *dis)
{
	void *p;

	uBufLock(dis);
	p = dis->freeList;
	if(p) {
		dis->freeList = (void *)(*((int *)(dis->freeList)));
	}
	uBufUnlock(dis);

	return p;
}

/* put buffer to pool */
int uBufPut(void *p, struct ubufm *dis)
{
	if(p) {
		*((int *)p) = (int)(dis->freeList);
		dis->freeList = p;
		return 0;
	}
	return -1;
}

/* put buffer to pool, 
 * this is critical protect version,
 * you should use this version when multithread
 * access the same buffer pool
 */
int uBufPutCt(void *p, struct ubufm *dis)
{
	if(p) {
		uBufLock(dis);
		*((int *)p) = (int)(dis->freeList);
		dis->freeList = p;
		uBufUnlock(dis);
		return 0;
	}
	return -1;
}

/* get buffer pointer by index(offset) */
void * uBufGetBufByIndex(unsigned int idx, struct ubufm *dis)
{
	return (char *)(dis->node_pool) + idx * dis->node_size;
}

/* get index by pointer */
int uBufGetIndex(void *p, struct ubufm *dis)
{
	return ((char *)p - (char *)(dis->node_pool)) / dis->node_size;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -