📄 ul_mem.c
字号:
/******************************************************************* uLan Communication - uL_DRV - multiplatform uLan driver ul_mem.c - uLan memory management and linked lists (C) Copyright 1996-2004 by Pavel Pisa - project originator http://cmp.felk.cvut.cz/~pisa (C) Copyright 1996-2004 PiKRON Ltd. http://www.pikron.com (C) Copyright 2002-2004 Petr Smolik The uLan driver project can be used and distributed in compliance with any of next licenses - GPL - GNU Public License See file COPYING for details. - LGPL - Lesser GNU Public License - MPL - Mozilla Public License - and other licenses added by project originator Code can be modified and re-distributed under any combination of the above listed licenses. If contributor does not agree with some of the licenses, he/she can delete appropriate line. WARNING: if you delete all lines, you are not allowed to distribute code or sources in any form. *******************************************************************//*******************************************************************//* uLan memory management and bidirectional linked lists */int ul_mem_init(ul_drv *udrv, int req_size){ void **pptr; ul_mem_blk *bptr; pptr=(void **)(udrv->mem_ptr=MALLOC(req_size+2*sizeof(void*))); if(!pptr) return -1; *(pptr++)=0; *(pptr++)=(void *)req_size; udrv->free_blk=bptr=(ul_mem_blk *)pptr; udrv->free_blk_cnt=1; while((req_size-=sizeof(ul_mem_blk))>=sizeof(ul_mem_blk)) { bptr->next=bptr+1; bptr++; udrv->free_blk_cnt++; }; bptr->next=NULL; udrv->prep_bll.first=udrv->prep_bll.last=NULL; udrv->prep_bll.cnt=0; udrv->prep_bll.udrv=udrv; udrv->work_bll.first=udrv->work_bll.last=NULL; udrv->work_bll.cnt=0; udrv->work_bll.udrv=udrv; udrv->proc_bll.first=udrv->proc_bll.last=NULL; udrv->proc_bll.cnt=0; udrv->proc_bll.udrv=udrv; udrv->opan_bll.first=udrv->opan_bll.last=NULL; udrv->opan_bll.cnt=0; udrv->opan_bll.udrv=udrv; udrv->con_message=NULL; return 0;};int ul_mem_done(ul_drv *udrv){ void *ptr; if(udrv->mem_ptr) { ptr=*(void **)udrv->mem_ptr; FREE(udrv->mem_ptr); udrv->mem_ptr=0; }; return 0;};/*** Insert frame blk on list bll ***/void ul_bll_ins(ul_blk_bll *bll, ul_mem_blk *blk){ UL_DRV_LOCK_FINI /* ul_drv *udrv=bll->udrv; */ UL_BLK_HEAD(blk).bll=bll; /* UL_BLK_HEAD(blk).next=NULL; */ /* UL_BLK_HEAD(blk).ref_cnt=1; */ /* UL_BLK_HEAD(blk).flg|=UL_BFL_LOCK; */ UL_DRV_LOCK; if((UL_BLK_HEAD(blk).prev=bll->last)!=NULL) UL_BLK_HEAD(bll->last).next=blk; else bll->first=blk; bll->last=blk; bll->cnt++; UL_DRV_UNLOCK;};/*** Remove frame blk from its bll ***/void ul_bll_del(ul_mem_blk *blk){ UL_DRV_LOCK_FINI ul_blk_bll *bll; ul_mem_blk *p; bll=UL_BLK_HEAD(blk).bll; UL_DRV_LOCK; bll->cnt--; if((p=UL_BLK_HEAD(blk).next)!=NULL) { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(blk).prev; UL_BLK_HEAD(blk).next=NULL; }else bll->last=UL_BLK_HEAD(blk).prev; if((p=UL_BLK_HEAD(blk).prev)!=NULL) { UL_BLK_HEAD(p).next=UL_BLK_HEAD(blk).next; UL_BLK_HEAD(blk).prev=NULL; }else bll->first=UL_BLK_HEAD(blk).next; UL_BLK_HEAD(blk).bll=NULL; UL_DRV_UNLOCK;};/*** Move one message starting at beg_blk to list new_bll ***/void ul_bll_move_mes(ul_blk_bll *new_bll, ul_mem_blk *beg_blk){ UL_DRV_LOCK_FINI /* ul_drv *udrv=bll->udrv; */ ul_mem_blk *end_blk; int cnt_blk=1; ul_blk_bll *old_bll; ul_mem_blk *p; if(beg_blk==NULL) return; end_blk=beg_blk; while((UL_BLK_HEAD(end_blk).flg&UL_BFL_TAIL)&&UL_BLK_HEAD(end_blk).next) { end_blk=UL_BLK_HEAD(end_blk).next; cnt_blk++; }; UL_BLK_HEAD(end_blk).flg&=~UL_BFL_TAIL; UL_DRV_LOCK; if((old_bll=UL_BLK_HEAD(beg_blk).bll)!=NULL) { old_bll->cnt-=cnt_blk; if((p=UL_BLK_HEAD(beg_blk).prev)!=NULL) { UL_BLK_HEAD(p).next=UL_BLK_HEAD(end_blk).next; UL_BLK_HEAD(beg_blk).prev=NULL; } else old_bll->first=UL_BLK_HEAD(end_blk).next; if((p=UL_BLK_HEAD(end_blk).next)!=NULL) { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(beg_blk).prev; UL_BLK_HEAD(end_blk).next=NULL; } else old_bll->last=UL_BLK_HEAD(beg_blk).prev; }; UL_DRV_UNLOCK; p=beg_blk; do UL_BLK_HEAD(p).bll=new_bll; while ((p=UL_BLK_HEAD(p).next)!=NULL); if(new_bll) { UL_DRV_LOCK; if((UL_BLK_HEAD(beg_blk).prev=new_bll->last)!=NULL) UL_BLK_HEAD(new_bll->last).next=beg_blk; else new_bll->first=beg_blk; new_bll->last=end_blk; new_bll->cnt+=cnt_blk; UL_DRV_UNLOCK; };};void ul_free_mes(ul_drv *udrv,ul_mem_blk *beg_blk){ ul_mem_blk *blk, *next_blk; if(beg_blk==NULL) return; ul_bll_move_mes(NULL,beg_blk); do { next_blk=beg_blk; beg_blk=UL_BLK_HEAD(beg_blk).next; do { blk=next_blk; next_blk=blk->next; ul_free_blk(udrv,blk); } while(next_blk!=NULL); } while(beg_blk!=NULL);};/*** Free one message starting at beg_blk ***/INLINE void ul_bll_free_mes(ul_mem_blk *beg_blk){ if(beg_blk==NULL) return; ul_free_mes(UL_BLK_HEAD(beg_blk).bll->udrv,beg_blk);};ul_mem_blk *ul_new_frame_head(ul_drv *udrv, uchar dadr, uchar sadr, uchar cmd, unsigned flg){ ul_mem_blk *blk; blk=ul_alloc_blk(udrv); if(blk==NULL) return NULL; UL_BLK_HEAD(blk).prev=NULL; UL_BLK_HEAD(blk).next=NULL; UL_BLK_HEAD(blk).bll=NULL; UL_BLK_HEAD(blk).retry_cnt=0; UL_BLK_HEAD(blk).ref_cnt=0; UL_BLK_HEAD(blk).flg=flg; UL_BLK_HEAD(blk).len=0; UL_BLK_HEAD(blk).cmd=cmd; UL_BLK_HEAD(blk).dadr=dadr; UL_BLK_HEAD(blk).sadr=sadr; UL_BLK_HEAD(blk).stamp=0; return blk;};void ul_tail_frame_head(ul_mem_blk *beg_blk, ul_mem_blk *blk){ while(UL_BLK_HEAD(beg_blk).next!=NULL) beg_blk=UL_BLK_HEAD(beg_blk).next; UL_BLK_HEAD(beg_blk).next=blk; UL_BLK_HEAD(blk).prev=beg_blk; UL_BLK_HEAD(beg_blk).flg|=UL_BFL_TAIL;};unsigned ul_gen_stamp(void){ UL_DRV_LOCK_FINI static unsigned ul_stamp_cnt=0; unsigned stamp; UL_DRV_LOCK; ul_stamp_cnt++; ul_stamp_cnt&=0x7fffffff; if(!ul_stamp_cnt)ul_stamp_cnt++; stamp=ul_stamp_cnt; UL_DRV_UNLOCK; return stamp; };int ul_inc_ref_cnt(ul_mem_blk *mes){ int cnt; UL_DRV_LOCK_FINI UL_DRV_LOCK; UL_BLK_HEAD(mes).ref_cnt++; cnt=UL_BLK_HEAD(mes).ref_cnt; UL_DRV_UNLOCK; return cnt;};int ul_dec_ref_cnt(ul_mem_blk *mes){ int cnt; UL_DRV_LOCK_FINI UL_DRV_LOCK; if(UL_BLK_HEAD(mes).ref_cnt)UL_BLK_HEAD(mes).ref_cnt--; cnt=UL_BLK_HEAD(mes).ref_cnt; UL_DRV_UNLOCK; if(!cnt)ul_bll_free_mes(mes); return cnt;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -