1 /*******************************************************************
2 uLan Communication - uL_DRV - multiplatform uLan driver
4 ul_mem.c - uLan memory management and linked lists
6 (C) Copyright 1996-2004 by Pavel Pisa - project originator
7 http://cmp.felk.cvut.cz/~pisa
8 (C) Copyright 1996-2004 PiKRON Ltd.
10 (C) Copyright 2002-2004 Petr Smolik
13 The uLan driver project can be used and distributed
14 in compliance with any of next licenses
15 - GPL - GNU Public License
16 See file COPYING for details.
17 - LGPL - Lesser GNU Public License
18 - MPL - Mozilla Public License
19 - and other licenses added by project originator
21 Code can be modified and re-distributed under any combination
22 of the above listed licenses. If contributor does not agree with
23 some of the licenses, he/she can delete appropriate line.
24 WARNING: if you delete all lines, you are not allowed to
25 distribute code or sources in any form.
26 *******************************************************************/
28 /*******************************************************************/
29 /* uLan memory management and bidirectional linked lists */
31 int ul_mem_init(ul_drv *udrv, int req_size)
35 pptr=(void **)(udrv->mem_ptr=MALLOC(req_size+2*sizeof(void*)));
38 *(pptr++)=(void *)req_size;
39 udrv->free_blk=bptr=(ul_mem_blk *)pptr;
42 while((req_size-=sizeof(ul_mem_blk))>=sizeof(ul_mem_blk))
49 udrv->prep_bll.first=udrv->prep_bll.last=NULL;
51 udrv->prep_bll.udrv=udrv;
52 udrv->work_bll.first=udrv->work_bll.last=NULL;
54 udrv->work_bll.udrv=udrv;
55 udrv->proc_bll.first=udrv->proc_bll.last=NULL;
57 udrv->proc_bll.udrv=udrv;
58 udrv->opan_bll.first=udrv->opan_bll.last=NULL;
60 udrv->opan_bll.udrv=udrv;
61 udrv->con_message=NULL;
66 int ul_mem_done(ul_drv *udrv)
70 { ptr=*(void **)udrv->mem_ptr;
77 /*** Insert frame blk on list bll ***/
78 void ul_bll_ins(ul_blk_bll *bll, ul_mem_blk *blk)
81 /* ul_drv *udrv=bll->udrv; */
82 UL_BLK_HEAD(blk).bll=bll;
83 /* UL_BLK_HEAD(blk).next=NULL; */
84 /* UL_BLK_HEAD(blk).ref_cnt=1; */
85 /* UL_BLK_HEAD(blk).flg|=UL_BFL_LOCK; */
87 if((UL_BLK_HEAD(blk).prev=bll->last)!=NULL)
88 UL_BLK_HEAD(bll->last).next=blk;
95 /*** Remove frame blk from its bll ***/
96 void ul_bll_del(ul_mem_blk *blk)
101 bll=UL_BLK_HEAD(blk).bll;
105 if((p=UL_BLK_HEAD(blk).next)!=NULL)
106 { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(blk).prev;
107 UL_BLK_HEAD(blk).next=NULL;
108 }else bll->last=UL_BLK_HEAD(blk).prev;
110 if((p=UL_BLK_HEAD(blk).prev)!=NULL)
111 { UL_BLK_HEAD(p).next=UL_BLK_HEAD(blk).next;
112 UL_BLK_HEAD(blk).prev=NULL;
113 }else bll->first=UL_BLK_HEAD(blk).next;
115 UL_BLK_HEAD(blk).bll=NULL;
119 /*** Move one message starting at beg_blk to list new_bll ***/
120 void ul_bll_move_mes(ul_blk_bll *new_bll, ul_mem_blk *beg_blk)
123 /* ul_drv *udrv=bll->udrv; */
129 if(beg_blk==NULL) return;
131 while((UL_BLK_HEAD(end_blk).flg&UL_BFL_TAIL)&&UL_BLK_HEAD(end_blk).next)
132 { end_blk=UL_BLK_HEAD(end_blk).next; cnt_blk++; };
133 UL_BLK_HEAD(end_blk).flg&=~UL_BFL_TAIL;
136 if((old_bll=UL_BLK_HEAD(beg_blk).bll)!=NULL)
138 old_bll->cnt-=cnt_blk;
139 if((p=UL_BLK_HEAD(beg_blk).prev)!=NULL)
140 { UL_BLK_HEAD(p).next=UL_BLK_HEAD(end_blk).next;
141 UL_BLK_HEAD(beg_blk).prev=NULL;
142 } else old_bll->first=UL_BLK_HEAD(end_blk).next;
143 if((p=UL_BLK_HEAD(end_blk).next)!=NULL)
144 { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(beg_blk).prev;
145 UL_BLK_HEAD(end_blk).next=NULL;
146 } else old_bll->last=UL_BLK_HEAD(beg_blk).prev;
151 do UL_BLK_HEAD(p).bll=new_bll;
152 while ((p=UL_BLK_HEAD(p).next)!=NULL);
157 if((UL_BLK_HEAD(beg_blk).prev=new_bll->last)!=NULL)
158 UL_BLK_HEAD(new_bll->last).next=beg_blk;
159 else new_bll->first=beg_blk;
160 new_bll->last=end_blk;
161 new_bll->cnt+=cnt_blk;
166 void ul_free_mes(ul_drv *udrv,ul_mem_blk *beg_blk)
168 ul_mem_blk *blk, *next_blk;
169 if(beg_blk==NULL) return;
170 ul_bll_move_mes(NULL,beg_blk);
173 beg_blk=UL_BLK_HEAD(beg_blk).next;
177 ul_free_blk(udrv,blk);
178 } while(next_blk!=NULL);
179 } while(beg_blk!=NULL);
182 /*** Free one message starting at beg_blk ***/
183 INLINE void ul_bll_free_mes(ul_mem_blk *beg_blk)
185 if(beg_blk==NULL) return;
186 ul_free_mes(UL_BLK_HEAD(beg_blk).bll->udrv,beg_blk);
189 ul_mem_blk *ul_new_frame_head(ul_drv *udrv, uchar dadr,
190 uchar sadr, uchar cmd, unsigned flg)
192 blk=ul_alloc_blk(udrv);
193 if(blk==NULL) return NULL;
194 UL_BLK_HEAD(blk).prev=NULL;
195 UL_BLK_HEAD(blk).next=NULL;
196 UL_BLK_HEAD(blk).bll=NULL;
197 UL_BLK_HEAD(blk).retry_cnt=0;
198 UL_BLK_HEAD(blk).ref_cnt=0;
199 UL_BLK_HEAD(blk).flg=flg;
200 UL_BLK_HEAD(blk).len=0;
201 UL_BLK_HEAD(blk).cmd=cmd;
202 UL_BLK_HEAD(blk).dadr=dadr;
203 UL_BLK_HEAD(blk).sadr=sadr;
204 UL_BLK_HEAD(blk).stamp=0;
208 void ul_tail_frame_head(ul_mem_blk *beg_blk, ul_mem_blk *blk)
210 while(UL_BLK_HEAD(beg_blk).next!=NULL)
211 beg_blk=UL_BLK_HEAD(beg_blk).next;
212 UL_BLK_HEAD(beg_blk).next=blk;
213 UL_BLK_HEAD(blk).prev=beg_blk;
214 UL_BLK_HEAD(beg_blk).flg|=UL_BFL_TAIL;
217 unsigned ul_gen_stamp(void)
220 static unsigned ul_stamp_cnt=0;
224 ul_stamp_cnt&=0x7fffffff;
225 if(!ul_stamp_cnt)ul_stamp_cnt++;
231 int ul_inc_ref_cnt(ul_mem_blk *mes)
236 UL_BLK_HEAD(mes).ref_cnt++;
237 cnt=UL_BLK_HEAD(mes).ref_cnt;
242 int ul_dec_ref_cnt(ul_mem_blk *mes)
247 if(UL_BLK_HEAD(mes).ref_cnt)UL_BLK_HEAD(mes).ref_cnt--;
248 cnt=UL_BLK_HEAD(mes).ref_cnt;
250 if(!cnt)ul_bll_free_mes(mes);