comparison src/cs/riviera/rvf/rvf_buffer.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
1 /****************************************************************************/
2 /* */
3 /* Name rvf_buffer.c */
4 /* */
5 /* Function this file contains rvf buffer handling functions */
6 /* */
7 /* Version 0.1 */
8 /* */
9 /* Date Modification */
10 /* ------------------------------------ */
11 /* 3/12/99 Create */
12 /* 10/27/1999 remove all non-nucleus sections (#ifdef) */
13 /* 30/11/1999 compliant to RV coding guidelines */
14 /* 12/23/1999 change buffer management, add memory bank handling and */
15 /* remove useless functions */
16 /* 07/12/2000 implement dynamic memory allocation. */
17 /* */
18 /* Author David Lamy-Charrier (dlamy@tif.ti.com) */
19 /* */
20 /* (C) Copyright 1999 by Texas Instruments Incorporated, All Rights Reserved*/
21 /****************************************************************************/
22
23 #ifndef _WINDOWS
24 #include "config/board.cfg"
25 #endif
26
27 #include "nucleus.h"
28 #include "rvm/rvm_use_id_list.h"
29 #include "rvf/rvf_api.h"
30 #include "rvf/rvf_i.h"
31 #include "support/exception.h"
32 #include "rvf/rvf_pool_size.h"
33
34 #include <string.h>
35 #include <stdio.h>
36
37
38 #if RVF_ENABLE_STATS /* conditional inclusion of stdio.h for sprintf() function */
39 #ifdef _WINDOWS
40 #include <stdio.h>
41 #endif
42 #endif
43
44 #include "rv/rv_defined_swe.h"
45
46 #ifdef RVM_DAR_SWE
47 #include "dar/dar_api.h"
48 #endif
49 #define RVF_INVALID_MD_ID_ERRROR ("RVF: Invalid MB ID")
50
51 #define INC_END_INITIALIZE 2
52 #define RVF_INVALID_INDEX 0xFFFF
53
54 /************* TASK MAILBOXES *******************/
55 /* chained lists for task mailboxes */
56 T_RVF_INTERNAL_BUF *OSTaskQFirst[1][1]; //[MAX_RVF_TASKS][RVF_NUM_TASK_MBOX];
57 T_RVF_INTERNAL_BUF *OSTaskQLast [1][1]; //[MAX_RVF_TASKS][RVF_NUM_TASK_MBOX];
58
59 extern INC_Initialize_State;
60
61 T_RVF_RT_ADDR_ID_DATA* pRtAddrIdTable[MAX_RVF_G_ADDR_ID];
62
63
64 /******** MEMORY POOLS ******************/
65 /* Define the buffer pools */
66 extern T_RVF_POOL _rvf_pools[];
67
68 /*********** MEMORY BANKS ***********/
69 /* array of memory bank */
70 static T_RVF_MB rvf_banks[RVF_MAX_REAL_MB];
71
72 /* array of waiting buffers */
73 static T_RVF_BUFFER * waiting_buffers[RVF_MAX_WAITING_BUF];
74 static UINT16 next_buffer[RVF_MAX_WAITING_BUF];
75 static UINT16 first_free_element;
76
77 /* array of memory bank name and id*/
78 static T_RVF_MB_NAME_ID rvf_name_id[RVF_MAX_TOTAL_MB] = RVF_MB_MAPPING;
79
80
81 /* variable for statistics */
82 #if RVF_ENABLE_STATS
83 static UINT32 required_size = 0;
84 static UINT32 obtained_size = 0;
85 static UINT32 used_size = 0;
86 static UINT32 mem_in_use = 0;
87 #endif
88
89 /* lists of free buffers */
90 static T_RVF_INTERNAL_BUF * lists[RVF_NB_FREE_LISTS];
91
92 /* last split-off buffer */
93 T_RVF_INTERNAL_BUF * last_remainder = NULL;
94
95 /* allocated static buffer pools */
96 extern UINT8 Buf0[];
97 extern UINT8 Buf1[];
98
99 /********Internal windows function used to display memory status *******/
100 #ifdef _WINDOWS
101 extern void AddNewState(void *s,char *name,
102 unsigned long current,unsigned long peak,
103 unsigned long water,unsigned long bank);
104 #endif
105
106
107 /*******************************************************************************
108 **
109 ** Function _rvf_init_free_queue
110 **
111 ** Description Function called at startup to initialize a free
112 ** pool (statically or dynamically allocated).
113 ** It is called once for each free pool.
114 **
115 ** Returns void
116 **
117 *******************************************************************************/
118 void _rvf_init_free_queue (UINT8 id, UINT32 size, void *p_mem)
119 {
120 T_RVF_INTERNAL_BUF *hdr;
121 UINT8 list_idx;
122
123 /* round to up size to a multiple of 4 */
124 size = (size + 3) & ~0x0003;
125
126 /* store pool start address and size */
127 _rvf_pools[id].start_address = p_mem;
128
129 _rvf_pools[id].pool_size = size;
130
131 /* Initialize the pool as a big free buffer */
132 hdr = (T_RVF_INTERNAL_BUF *) p_mem;
133 hdr->buf_size = size - sizeof(T_RVF_INTERNAL_BUF) - sizeof(UINT32); /* last 4 bytes of the pool losts*/
134 hdr->header.p_prev = NULL;
135 RVF_SET_PREV_IN_USE(hdr);
136
137 NEXTCHUNK(hdr)->buf_size = 0;
138
139 ENDSIZE(hdr) = hdr->buf_size;
140
141
142 /* get the corresponding list and insert the buffer */
143 list_idx = RVF_BUF_LIST_INDEX( hdr->buf_size);
144 hdr->p_next = lists[list_idx];
145 lists[list_idx] = hdr;
146
147 last_remainder = hdr;
148
149 }
150
151 void rvf_mbox_buffer_init(T_RVF_RT_ADDR_ID_DATA* pRtAddrIdElement) {
152 UINT8 task_num, mbox_num;
153 /* Initialize all mailboxes queues of all tasks*/
154 for (task_num = 0; task_num < MAX_RVF_TASKS; task_num++) {
155 for (mbox_num = 0; mbox_num < RVF_NUM_TASK_MBOX; mbox_num++) {
156 pRtAddrIdElement->OSTaskQFirst[mbox_num] = NULL;
157 pRtAddrIdElement->OSTaskQLast[mbox_num] = NULL;
158 }
159 }
160 }
161 /*******************************************************************************
162 **
163 ** Function _rvf_buffer_init
164 **
165 ** Description Called once internally by rvf at startup to initialize all
166 ** buffers and free buffer pools.
167 **
168 ** Returns void
169 **
170 *******************************************************************************/
171 void _rvf_buffer_init(void)
172 {
173 UINT8 list_num;
174 UINT16 memory_bank_num;
175
176 /* Initialize all mailboxes queues of all tasks*/
177 /* for (task_num = 0; task_num < MAX_RVF_TASKS; task_num++)
178 {
179 for (mbox_num = 0; mbox_num < RVF_NUM_TASK_MBOX; mbox_num++)
180 {
181 OSTaskQFirst[task_num][mbox_num] = NULL;
182 OSTaskQLast [task_num][mbox_num] = NULL;
183 //pRtAddrIdTable[task_num]->OSTaskQFirst[mbox_num] = NULL; // only if static
184 //pRtAddrIdTable[task_num]->OSTaskQLast[mbox_num] = NULL; // only if static
185 }
186 } */
187
188 /* initialize free lists */
189 for (list_num = 0; list_num < RVF_NB_FREE_LISTS; list_num++)
190 {
191 lists[list_num] = NULL;
192 }
193
194
195 /* initialize buffer pools */
196 _rvf_init_mem_pool();
197
198 /* Initialize real memory banks */
199 for (memory_bank_num = 0; memory_bank_num < RVF_MAX_REAL_MB; memory_bank_num++)
200 {
201 rvf_banks[memory_bank_num].cur_memory_used = 0;
202 rvf_banks[memory_bank_num].watermark = 0;
203 rvf_banks[memory_bank_num].max = 0;
204 rvf_banks[memory_bank_num].first_buffer_index = RVF_INVALID_INDEX;
205 rvf_banks[memory_bank_num].last_buffer_index = RVF_INVALID_INDEX;
206 rvf_banks[memory_bank_num].func = 0;
207 rvf_banks[memory_bank_num].returned_red = FALSE;
208 #if RVF_ENABLE_STATS
209 rvf_banks[memory_bank_num].max_reached = 0;
210 rvf_banks[memory_bank_num].required_size = 0;
211 rvf_banks[memory_bank_num].num_buf = 0;
212 #endif
213 }
214
215 /* Initialize total memory banks */
216 for (memory_bank_num = 0; memory_bank_num < RVF_MAX_TOTAL_MB; memory_bank_num++)
217 {
218 rvf_name_id[memory_bank_num].mb_params.size = 0;
219 rvf_name_id[memory_bank_num].mb_params.watermark = 0;
220 }
221
222
223 /* initialize array of waiting buffers */
224 first_free_element = 0;
225 for( memory_bank_num = 0; memory_bank_num < RVF_MAX_WAITING_BUF; memory_bank_num++)
226 { waiting_buffers[memory_bank_num] = NULL;
227 next_buffer[memory_bank_num] = memory_bank_num + 1;
228 }
229 next_buffer[RVF_MAX_WAITING_BUF-1] = RVF_INVALID_INDEX;
230 }
231
232 /*******************************************************************************
233 **
234 ** Function _rvf_send_msg_to_mbox
235 **
236 ** Description Called by applications to send a buffer to a SWE.
237 ** (Temporary internal use - DO NOT USE IT !)
238 ** (Presently, only for Christophe )
239 ** Returns RVF_OK if successful, else an error code.
240 **
241 *******************************************************************************/
242 T_RVF_RET _rvf_send_msg_to_mbox (T_RVF_G_ADDR_ID addr_id, UINT8 mbox,void *msg){
243 return rvf_adapt_send_msg(addr_id, msg, mbox);
244 }
245
246 /*T_RVF_RET _rvf_send_msg_to_mbox (T_RVF_ADDR_ID addr_id, UINT8 mbox,void *msg)
247 {
248 T_RVF_INTERNAL_BUF *p_hdr;
249 UINT8 task_id = (UINT8)addr_id;
250
251
252 if ((task_id >= MAX_RVF_TASKS) )
253 {
254 rvf_send_trace( "RVF: rvf_send_msg(): invalid taskid", 35, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
255 rvf_free_buf (msg);
256 return RVF_INVALID_PARAMETER;
257 }
258
259 #if RVF_ENABLE_BUF_CORRUPTION_CHECK
260
261 if (_rvf_chk_buf_damage(msg) == TRUE)
262 { rvf_send_trace( "RVF: rvf_send_msg(): buffer corrupted", 37, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
263 }
264 #endif
265
266
267 ((T_RV_HDR *)msg)->dest_addr_id = addr_id;
268 p_hdr = USER2MEM(msg);
269
270 #if RVF_ENABLE_BUF_LINKAGE_CHECK
271
272 if ( RVF_BUF_IS_LINKED( p_hdr) )
273 {
274 rvf_send_trace( "RVF: rvf_send_msg(): buffer already enqueued", 44, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
275 return RVF_MEMORY_ERR;
276 }
277 #endif
278
279 rvf_disable(8);
280
281
282 if (OSTaskQFirst[task_id][mbox])
283 { OSTaskQLast[task_id][mbox]->p_next = p_hdr;
284 }
285 else
286 { OSTaskQFirst[task_id][mbox] = p_hdr;
287 }
288 OSTaskQLast[task_id][mbox] = p_hdr;
289
290 p_hdr->p_next = NULL;
291
292 if (pRtAddrIdTable[task_id]->OSTaskQFirst[mbox]) {
293 pRtAddrIdTable[task_id]->OSTaskQLast[mbox]->p_next = p_hdr;
294 } else {
295 pRtAddrIdTable[task_id]->OSTaskQFirst[mbox] = p_hdr;
296 }
297 pRtAddrIdTable[task_id]->OSTaskQLast[mbox] = p_hdr;
298
299 p_hdr->p_next = NULL;
300
301 #if RVF_ENABLE_BUF_LINKAGE_CHECK
302 RVF_SET_BUF_LINKED(p_hdr);
303 #endif
304
305 rvf_enable();
306
307 rvf_send_event(task_id, (UINT16) (EVENT_MASK(mbox)) );
308 return RVF_OK;
309 }*/
310
311 /*******************************************************************************
312 **
313 ** Function rvf_read_mbox
314 **
315 ** Description Called by applications to read a buffer from one of
316 ** the task mailboxes.
317 **
318 ** Returns NULL if the mailbox was empty, else the address of a buffer
319 **
320 *******************************************************************************/
321 void * rvf_read_mbox (UINT8 mbox) {
322 T_RVF_G_ADDR_ID task_id = rvf_get_taskid();
323
324 return rvf_read_addr_mbox (task_id, mbox) ;
325 }
326 void * rvf_read_addr_mbox (T_RVF_G_ADDR_ID task_id, UINT8 mbox) {
327 void * p_buf = NULL;
328 T_RVF_INTERNAL_BUF * p_hdr;
329
330 mbox=resolveHostAddrId(mbox);
331
332 if ((task_id >= MAX_RVF_TASKS) || (mbox >= RVF_NUM_TASK_MBOX))
333 { rvf_send_trace( "RVF: rvf_read_mbox(): invalid taskid or mbox", 44, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
334 return NULL;
335 }
336
337 rvf_disable(9); /* enter critical section */
338
339 /* if the chained list is not empty */
340 /*if ( OSTaskQFirst[task_id][mbox] )
341 { p_hdr = OSTaskQFirst[task_id][mbox];
342 OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
343
344 p_hdr->p_next = NULL;*/
345 if ( pRtAddrIdTable[task_id]->OSTaskQFirst[mbox] ) {
346 p_hdr = pRtAddrIdTable[task_id]->OSTaskQFirst[mbox];
347 pRtAddrIdTable[task_id]->OSTaskQFirst[mbox] = p_hdr->p_next;
348
349 p_hdr->p_next = NULL;
350
351 #if RVF_ENABLE_BUF_LINKAGE_CHECK
352 RVF_SET_BUF_UNLINKED(p_hdr); /* change buffer status */
353 #endif
354 p_buf = (UINT8 *)p_hdr + sizeof(T_RVF_INTERNAL_BUF);
355 }
356
357 rvf_enable(); /* exit critical section */
358
359 return (p_buf);
360 }
361
362 /*******************************************************************************
363 **
364 ** Function rvf_enqueue
365 **
366 ** Description Enqueue a buffer at the tail of the queue
367 **
368 ** Returns RVF_OK if successful, else an error code.
369 **
370 *******************************************************************************/
371 T_RVF_RET rvf_enqueue (T_RVF_BUFFER_Q *p_q, void *p_buf)
372 {
373 T_RVF_INTERNAL_BUF *p_hdr;
374
375 #if RVF_ENABLE_BUF_CORRUPTION_CHECK
376 if ( _rvf_chk_buf_damage(p_buf) )
377 { rvf_send_trace( "RVF: rvf_enqueue(): buffer corrupted", 36, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
378 }
379 #endif
380
381 /* check if the buffer has been already enqueued */
382 p_hdr = USER2MEM(p_buf);
383
384 #if RVF_ENABLE_BUF_LINKAGE_CHECK
385 if( RVF_BUF_IS_LINKED(p_hdr) )
386 {
387 rvf_send_trace( "RVF: rvf_enqueue(): buffer already enqueued", 43, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
388 return RVF_MEMORY_ERR;
389 }
390 #endif
391
392 rvf_disable(10); /* enter critical section */
393
394 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
395 /* p_q->p_last and p_q->p_first point to the user buffer, since p_hdr->p_next points to the T_RVF_INTERNAL_BUF */
396 if (p_q->p_first) /* if the queue is not empty */
397 {
398 T_RVF_INTERNAL_BUF * p_last_hdr = (T_RVF_INTERNAL_BUF *) ((UINT8 *)p_q->p_last - sizeof(T_RVF_INTERNAL_BUF) );
399 p_last_hdr->p_next = p_hdr;
400 }
401 else
402 p_q->p_first = p_buf;
403
404 p_q->p_last = p_buf;
405 p_q->count++;
406
407 p_hdr->p_next = NULL;
408 #if RVF_ENABLE_BUF_LINKAGE_CHECK
409 RVF_SET_BUF_LINKED(p_hdr); /* change buffer status */
410 #endif
411
412 rvf_enable(); /* exit critical section */
413 return RVF_OK;
414 }
415
416
417
418 /*******************************************************************************
419 **
420 ** Function rvf_dequeue
421 **
422 ** Description Dequeue a buffer from the head of a queue
423 **
424 ** Returns NULL if queue is empty, else buffer
425 **
426 *******************************************************************************/
427 void * rvf_dequeue (T_RVF_BUFFER_Q *p_q)
428 {
429 T_RVF_INTERNAL_BUF *p_hdr;
430
431 if (!p_q->count) /* if the queue is empty */
432 return (NULL);
433
434 rvf_disable(12); /* enter critical section */
435
436 p_hdr = USER2MEM(p_q->p_first );
437
438
439 /* Keep buffers such that RVF header is invisible */
440 if (p_hdr->p_next)
441 p_q->p_first = ((UINT8 *)p_hdr->p_next + sizeof(T_RVF_INTERNAL_BUF));
442 else
443 {
444 p_q->p_first = NULL;
445 p_q->p_last = NULL;
446 }
447
448 p_q->count--;
449
450 p_hdr->p_next = NULL;
451
452 #if RVF_ENABLE_BUF_LINKAGE_CHECK
453 RVF_SET_BUF_UNLINKED(p_hdr); /* change buffer status */
454 #endif
455
456 rvf_enable(); /* exit critical section */
457
458 return (MEM2USER(p_hdr) );
459 }
460
461
462
463 /*******************************************************************************
464 **
465 ** Function rvf_enqueue_head
466 **
467 ** Description Enqueue a buffer at the head of the queue
468 **
469 ** Returns RVF_OK if successful, else an error code.
470 **
471 *******************************************************************************/
472 T_RVF_RET rvf_enqueue_head (T_RVF_BUFFER_Q *p_q, void *p_buf)
473 {
474 T_RVF_INTERNAL_BUF *p_hdr;
475
476 #if RVF_ENABLE_BUF_CORRUPTION_CHECK
477 if ( _rvf_chk_buf_damage(p_buf) )
478 { rvf_send_trace( "RVF: rvf_enqueue_head(): buffer corrupted", 41, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
479 }
480 #endif
481
482 p_hdr = USER2MEM(p_buf);
483
484 #if RVF_ENABLE_BUF_LINKAGE_CHECK
485 if( RVF_BUF_IS_LINKED(p_hdr) )
486 { rvf_send_trace( "RVF: rvf_enqueue_head(): buffer already enqueued", 48, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
487 return RVF_MEMORY_ERR;
488 }
489 #endif
490
491 rvf_disable(11); /* enter critical section */
492
493 if (p_q->p_first) /* if the queue is not empty */
494 { p_hdr->p_next = (T_RVF_INTERNAL_BUF *)((UINT8 *)p_q->p_first - sizeof(T_RVF_INTERNAL_BUF) );
495 p_q->p_first = p_buf;
496 }
497 else
498 { p_q->p_first = p_buf;
499 p_q->p_last = p_buf;
500 p_hdr->p_next = NULL;
501 }
502 p_q->count++;
503
504 #if RVF_ENABLE_BUF_LINKAGE_CHECK
505 RVF_SET_BUF_LINKED(p_hdr); /* change buffer status */
506 #endif
507
508
509 rvf_enable(); /* exit critical section */
510
511 return RVF_OK;
512 }
513
514
515
516 /*******************************************************************************
517 **
518 ** Function rvf_get_buf_size
519 **
520 ** Description Called by an application to get the size of a buffer.
521 **
522 ** Returns the size of the buffer or 0 if the address is invalid.
523 **
524 *******************************************************************************/
525 INLINE UINT32 rvf_get_buf_size (void *bptr)
526 {
527 T_RVF_INTERNAL_BUF *p_hdr;
528
529 p_hdr = (T_RVF_INTERNAL_BUF *)((UINT8 *) bptr - sizeof(T_RVF_INTERNAL_BUF) );
530
531 if ((UINT32)p_hdr & 1) return 0; /* invalid pointer: odd address*/
532
533 return (GETSIZE(p_hdr) - RVF_CORRUPT_OVERHEAD) ;
534 }
535
536
537 /*******************************************************************************
538 **
539 ** Function _rvf_chk_buf_damage
540 **
541 ** Description Called internally by rvf to check for buffer corruption.
542 **
543 ** Returns TRUE if there is a problem, else FALSE
544 **
545 *******************************************************************************/
546 #if RVF_ENABLE_BUF_CORRUPTION_CHECK
547 BOOLEAN _rvf_chk_buf_damage(void *bptr)
548 {
549 UINT32 *lg;
550 T_RVF_INTERNAL_BUF * p_hdr;
551
552 if((UINT32)bptr & 1) /* odd address */
553 { return TRUE;
554 }
555
556 p_hdr = USER2MEM(bptr); /* get the internal header */
557
558 lg = (UINT32*)( (UINT8*)bptr + GETSIZE(p_hdr) - sizeof(UINT32) );
559
560 if (lg == 0)
561 return TRUE;
562
563 if(*lg == GETSIZE(p_hdr) )
564 {
565 return FALSE;
566 }
567 return TRUE;
568 }
569 #endif
570
571
572
573 /*******************************************************************************
574 **
575 ** Function _find_buf
576 **
577 ** Description Internal function which is in charge of finding a free buffer
578 ** of the requested size in one of the lists.
579 **
580 ** Returns A pointer to the buffer header, or NULL if none available
581 **
582 *******************************************************************************/
583 INLINE void * _find_buf (UINT32 size)
584 {
585 T_RVF_INTERNAL_BUF * p_hdr;
586 UINT8 idx;
587
588 if (size == 0) /* if user requires a 0 byte buffer !! */
589 { return (NULL);
590 }
591
592 /* add the overhead for buffer corruption check */
593 size = REQ2SIZE(size);
594
595 /* find the corresponding list */
596 idx = RVF_BUF_LIST_INDEX(size);
597
598 /* 1. try in the bin corresponding to the requested size. */
599 /* 2. try to use the last_remainder chunk. */
600 /* 3. try in the others bins of greater size. */
601
602 if( (lists[idx] == NULL) || ( GETSIZE(lists[idx]) < size) )
603 /* if the first buffer in the appropriate bin is not big enough. */
604 {
605 rvf_disable(4); /* enter critical section */
606
607 if( last_remainder != NULL)
608 {
609 p_hdr = last_remainder;
610
611 /* if the last remainder is big enough */
612 if( GETSIZE(p_hdr) >= size )
613 {
614
615 if( GETSIZE(p_hdr) >= (size + RVF_MIN_USABLE_SIZE ) ) /* if the free part may be used */
616 { /* create a new free buffer and link it in the appropriate list*/
617
618 T_RVF_INTERNAL_BUF * new_buf;
619 UINT8 new_idx;
620
621 new_buf = (T_RVF_INTERNAL_BUF *) ((UINT8*)p_hdr + size + sizeof(T_RVF_INTERNAL_BUF));
622 new_buf->buf_size = GETSIZE(p_hdr) - size - sizeof(T_RVF_INTERNAL_BUF);
623 ENDSIZE(new_buf) = new_buf->buf_size;
624
625 /* remove the used buffer from the list */
626 if( p_hdr->header.p_prev != NULL)
627 { (p_hdr->header.p_prev)->p_next = p_hdr->p_next;
628 }
629 else
630 { lists[ RVF_BUF_LIST_INDEX( GETSIZE(p_hdr) )] = p_hdr->p_next;
631 }
632 if( p_hdr->p_next != NULL)
633 { (p_hdr->p_next)->header.p_prev = p_hdr->header.p_prev;
634 }
635 p_hdr->p_next = NULL;
636
637 SETSIZE(p_hdr, size);
638 ENDSIZE(p_hdr) = size; /* to CHANGE */
639
640 /* insert the new buffer in the appropriate list */
641 new_idx = RVF_BUF_LIST_INDEX(new_buf->buf_size);
642 new_buf->p_next = lists[new_idx];
643 lists[new_idx] = new_buf;
644 new_buf->header.p_prev = NULL;
645 if( new_buf->p_next != NULL)
646 { (new_buf->p_next)->header.p_prev = new_buf;
647 }
648 RVF_SET_PREV_IN_USE(new_buf);
649
650 last_remainder = new_buf;
651
652 rvf_enable(); /* exit critical section */
653 return p_hdr;
654
655 }
656 else /* return the entire buffer */
657 {
658 /* remove the used buffer from the list */
659 if( p_hdr->header.p_prev != NULL)
660 { (p_hdr->header.p_prev)->p_next = p_hdr->p_next;
661 }
662 else
663 { lists[ RVF_BUF_LIST_INDEX( GETSIZE(p_hdr) )] = p_hdr->p_next;
664 }
665 if( p_hdr->p_next != NULL)
666 { (p_hdr->p_next)->header.p_prev = p_hdr->header.p_prev;
667 }
668 p_hdr->p_next = NULL;
669
670 RVF_SET_PREV_IN_USE( NEXTCHUNK(p_hdr) );
671
672 last_remainder = NULL;
673
674 rvf_enable(); /* exit critical section */
675 return p_hdr;
676 }
677 }
678 else /* the last remainder is too small */
679 {
680 /* clear the last remainder */
681 last_remainder = NULL;
682 }
683
684 }
685 rvf_enable(); /* exit critical section */
686 }
687
688 while( idx < RVF_NB_FREE_LISTS )
689 {
690 rvf_disable(4); /* enter critical section */
691
692 if( lists[idx] != NULL ) /*if the list is not empty */
693 { /* remove the first buffer from the list */
694
695 p_hdr = lists[idx];
696 if( GETSIZE(p_hdr) >= size)
697 {
698 if( GETSIZE(p_hdr) >= (size + RVF_MIN_USABLE_SIZE ) ) /* if the free part may be used */
699 { /* create a new free buffer and link it in the appropriate list*/
700
701 T_RVF_INTERNAL_BUF * new_buf;
702 UINT8 new_idx;
703
704 new_buf = (T_RVF_INTERNAL_BUF *) ((UINT8*)p_hdr + size + sizeof(T_RVF_INTERNAL_BUF));
705 new_buf->buf_size = GETSIZE( p_hdr) - size - sizeof(T_RVF_INTERNAL_BUF);
706 ENDSIZE(new_buf) = new_buf->buf_size;
707
708 /* remove the used buffer from the list */
709 lists[idx] = p_hdr->p_next;
710 if( p_hdr->p_next != NULL)
711 { (p_hdr->p_next)->header.p_prev = NULL;
712 }
713 p_hdr->p_next = NULL;
714
715 SETSIZE(p_hdr, size);
716 ENDSIZE(p_hdr) = size;
717
718 /* insert the new buffer in the appropriate list */
719 new_idx = RVF_BUF_LIST_INDEX(new_buf->buf_size);
720 new_buf->p_next = lists[new_idx];
721 lists[new_idx] = new_buf;
722 new_buf->header.p_prev = NULL;
723 if( new_buf->p_next != NULL)
724 { (new_buf->p_next)->header.p_prev = new_buf;
725 }
726 RVF_SET_PREV_IN_USE(new_buf);
727
728 last_remainder = new_buf; /* set this new buffer as the last remainder */
729
730 rvf_enable(); /* exit critical section */
731 return p_hdr;
732
733 }
734 else /* return the entire buffer */
735 { lists[idx] = p_hdr->p_next;
736 if( p_hdr->p_next != NULL)
737 { (p_hdr->p_next)->header.p_prev = NULL;
738 }
739 p_hdr->p_next = NULL;
740 RVF_SET_PREV_IN_USE( NEXTCHUNK(p_hdr) );
741
742 if( last_remainder == p_hdr) /* if it was the last_remainder, clear it. */
743 {
744 last_remainder = NULL;
745 }
746
747 rvf_enable(); /* exit critical section */
748 return p_hdr;
749 }
750 }
751 }
752
753 rvf_enable(); /* exit critical section */
754
755 idx++; /* search in the next list */
756 }
757
758 return NULL;
759 }
760
761
762 /*******************************************************************************
763 **
764 ** Function _release_buf
765 **
766 ** Description Internal function called to release a buffer after use.
767 ** The parameter points to the beginning of the header.
768 **
769 ** Returns BOOLEAN: TRUE if successful, else FALSE
770 **
771 *******************************************************************************/
772 INLINE BOOLEAN _release_buf (T_RVF_INTERNAL_BUF *p_hdr)
773 { UINT8 idx;
774
775 #if RVF_ENABLE_BUF_CORRUPTION_CHECK /* check for buffer corruption:i.e. if user wrote data after the end of the buffer */
776 if ( _rvf_chk_buf_damage( MEM2USER(p_hdr) ) )
777 { rvf_send_trace( "RVF: _release_buf(): buffer corrupted", 37, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
778 return FALSE;
779 }
780
781 /* check if the buffer has been already freed */
782 if ( RVF_IS_PREV_FREE( NEXTCHUNK(p_hdr) ) ) /* check buffer status */
783 { rvf_send_trace( "RVF: _release_buf(): buffer already freed", 41, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
784 return FALSE;
785 }
786
787 #endif
788
789 #if RVF_ENABLE_BUF_LINKAGE_CHECK /* check for buffer linkage */
790 if ( RVF_BUF_IS_LINKED(p_hdr) ) /* check buffer status */
791 { rvf_send_trace( "RVF: _release_buf(): free buf buffer linked", 43, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
792 return FALSE;
793 }
794 #endif
795
796
797 rvf_disable(6); /* enter critical section */
798
799 /* try to coalesce the buffer with its neighbors (left and right) */
800
801 if( RVF_IS_PREV_FREE(p_hdr) )
802 { /* merge the buffer with its left neighbor */
803 UINT32 left_buf_size = *((UINT32*)((UINT8*)p_hdr - sizeof(UINT32) ) );
804 T_RVF_INTERNAL_BUF * left_buf = (T_RVF_INTERNAL_BUF *) ((UINT8 *)p_hdr - left_buf_size - sizeof(T_RVF_INTERNAL_BUF) );
805
806 /* remove the left buffer from its list */
807 if( left_buf->header.p_prev == NULL)
808 { lists[ RVF_BUF_LIST_INDEX(left_buf_size)] = left_buf->p_next;
809 }
810 else
811 { (left_buf->header.p_prev)->p_next = left_buf->p_next;
812 }
813 if( left_buf->p_next != NULL)
814 {
815 (left_buf->p_next)->header.p_prev = left_buf->header.p_prev;
816 }
817 /* set the size of the newly created buffer */
818 SETSIZE(left_buf, (left_buf_size + GETSIZE(p_hdr) + sizeof(T_RVF_INTERNAL_BUF) ) );
819 /* set the current buffer as free to allow check for double free */
820 RVF_SET_PREV_FREE( NEXTCHUNK(p_hdr) );
821
822 p_hdr = left_buf;
823 }
824
825 /* check for pool limits */
826 if( GETSIZE( NEXTCHUNK(p_hdr) ) != 0)
827 { T_RVF_INTERNAL_BUF * right_buf = NEXTCHUNK(p_hdr);
828 /* merge the buffer with its right neighbor */
829
830 if( RVF_IS_PREV_FREE( NEXTCHUNK(right_buf) ) )
831 { /* remove the right buffer from its list */
832 UINT32 right_buf_size = GETSIZE( right_buf);
833
834 if( right_buf->header.p_prev == NULL)
835 { lists[ RVF_BUF_LIST_INDEX(right_buf_size)] = right_buf->p_next;
836 }
837 else
838 { (right_buf->header.p_prev)->p_next = right_buf->p_next;
839 }
840 if( right_buf->p_next != NULL)
841 { (right_buf->p_next)->header.p_prev = right_buf->header.p_prev;
842 }
843
844 right_buf_size += GETSIZE(p_hdr);
845 SETSIZE(p_hdr, (right_buf_size + sizeof(T_RVF_INTERNAL_BUF) ) );
846
847 if( last_remainder == right_buf) /* keep as last_remainder */
848 { last_remainder = p_hdr;
849 }
850 }
851 }
852
853 /* enqueue the free buffer in the appropriate list */
854 idx = RVF_BUF_LIST_INDEX( GETSIZE(p_hdr) );
855 p_hdr->header.p_prev = NULL;
856 p_hdr->p_next = lists[idx];
857 lists[idx] = p_hdr;
858 if( p_hdr->p_next != NULL)
859 { (p_hdr->p_next)->header.p_prev = p_hdr;
860 }
861
862 ENDSIZE(p_hdr) = GETSIZE(p_hdr);
863 RVF_SET_PREV_FREE( NEXTCHUNK(p_hdr) );
864
865 rvf_enable(); /* exit critical section */
866 return TRUE;
867 }
868
869
870 /*******************************************************************************
871 ** Function _str_cmp
872 **
873 ** Description Internal function which compares two null-terminated string.
874 ** Returns TRUE if they are equal, else FALSE.
875 *******************************************************************************/
876 BOOLEAN _str_cmp( char *str1, char * str2)
877 { UINT8 i;
878 for ( i = 0; (str1[i] == str2[i]) && (str1[i] != 0) && (str2[i] != 0) && (i < RVF_MAX_MB_LEN); i++ );
879 if ( i == RVF_MAX_MB_LEN)
880 { return TRUE;
881 }
882
883 if ( (str1[i] == 0) && (str2[i] == 0) )
884 { return TRUE;
885 }
886 return FALSE;
887 }
888
889 /******************************************************************************
890 **
891 ** MEMORY BANK RELATED FUNCTIONS
892 **
893 ******************************************************************************/
894
895 /*******************************************************************************
896 **
897 ** Function _remove_from_list
898 **
899 ** Description Internal function called to remove a buffer from the list of
900 ** buffer waiting to be counted on the memory bank.
901 ** The parameter points to the beginning of the header.
902 **
903 ** Returns BOOLEAN: TRUE if successful, else FALSE
904 **
905 *******************************************************************************/
906 BOOLEAN _remove_from_list (void *bptr, T_RVF_MB * mb)
907 { UINT16 * index;
908 UINT16 free_elem, prec;
909
910 /* check all elements of the list */
911 index = &(mb->first_buffer_index);
912 prec = RVF_INVALID_INDEX;
913
914 while ( (*index != RVF_INVALID_INDEX) && (waiting_buffers[*index]!=bptr) )
915 { prec = *index;
916 index = &(next_buffer[*index]);
917 }
918
919 if (waiting_buffers[*index] == bptr)
920 { free_elem = *index;
921 *index = next_buffer[free_elem]; /* link preceding element to the next one */
922
923 if (next_buffer[free_elem] == RVF_INVALID_INDEX ) /* last element in the list */
924 { mb->last_buffer_index = prec;
925 }
926
927 waiting_buffers[free_elem] = NULL;
928 next_buffer[free_elem] = first_free_element; /* link free elements */
929 first_free_element = free_elem;
930 return TRUE;
931 }
932 return FALSE; /* buffer not found */
933 }
934
935
936 /*******************************************************************************
937 **
938 ** Function _add_to_list
939 **
940 ** Description Internal function called to add a buffer to the list of
941 ** buffer waiting to be counted on the memory bank.
942 ** The parameter points to the beginning of the header.
943 **
944 ** Returns BOOLEAN: TRUE if successful, else FALSE
945 **
946 *******************************************************************************/
947 BOOLEAN _add_to_list (void *bptr, T_RVF_MB * mb)
948 { UINT16 index = first_free_element;
949
950 first_free_element = next_buffer[index];
951
952 waiting_buffers[index] = bptr;
953 next_buffer[index] = RVF_INVALID_INDEX;
954
955 if ( mb->last_buffer_index == RVF_INVALID_INDEX) /* empty list */
956 { mb->first_buffer_index = index;
957 mb->last_buffer_index = index;
958 }
959 else
960 { next_buffer[mb->last_buffer_index] = index;
961 mb->last_buffer_index = index;
962 }
963
964 return TRUE;
965 }
966
967
968 /*******************************************************************************
969 **
970 ** Function rvf_create_mb
971 **
972 ** Description Called by an application to create a memory bank
973 **
974 ** Parameters: memory bank name, memory bank param
975 ** (return) memory bank id
976 **
977 ** Returns T_RVF_RET: RVF_OK if success
978 **
979 *******************************************************************************/
980 T_RVF_RET rvf_create_mb(T_RVF_MB_NAME mb_name, T_RVF_MB_PARAM mb_param, T_RVF_MB_ID *mb_id)
981 { UINT8 num_mb;
982 T_RVF_MB * mb;
983 UINT32 available_mem = 0;
984 UINT32 required_mem = 0;
985
986 /* find the mb name in the array */
987 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
988
989 if ( num_mb == RVF_MAX_TOTAL_MB ) /* mb name not found */
990 {
991 /* DLC added for dynamic memory bank creation*/
992
993 /* search the first available place in the array */
994 T_RVF_MB_ID first_available_mb_id = 0;
995 BOOLEAN mb_id_found = FALSE;
996
997 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (rvf_name_id[num_mb].mb_name[0] != 0) ; num_mb++)
998 { if( rvf_name_id[num_mb].mb_id == first_available_mb_id)
999 { first_available_mb_id ++;
1000 }
1001 }
1002
1003 while( (first_available_mb_id < RVF_MAX_REAL_MB) && (mb_id_found == FALSE) )
1004 {
1005 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (rvf_name_id[num_mb].mb_name[0] != 0) && (rvf_name_id[num_mb].mb_id != first_available_mb_id) ; num_mb++);
1006 if ( rvf_name_id[num_mb].mb_id != first_available_mb_id)
1007 { /* available mb id found */
1008 mb_id_found = TRUE;
1009 }
1010 else
1011 { /* try the next one */
1012 first_available_mb_id++;
1013 }
1014 }
1015
1016 if ( (num_mb == RVF_MAX_TOTAL_MB) || (first_available_mb_id + 1 >= RVF_MAX_REAL_MB ) ) /* no available space in the array */
1017
1018 { *mb_id = RVF_INVALID_MB_ID;
1019 return RVF_INVALID_PARAMETER;
1020 }
1021
1022 if(INC_Initialize_State==INC_END_INITIALIZE) rvf_disable(20); /* enter critical section */
1023
1024 /* create the new mb name and id */
1025 strcpy( rvf_name_id[num_mb].mb_name, mb_name);
1026 rvf_name_id[num_mb].mb_id = first_available_mb_id;
1027
1028 /* initialize the next one */
1029 rvf_name_id[num_mb+1].mb_name[0] = 0;
1030 rvf_name_id[num_mb+1].mb_id = 0;
1031
1032 if(INC_Initialize_State==INC_END_INITIALIZE) rvf_enable(); /* exit critical section */
1033 }
1034
1035 /* check if the memory bank has been already created */
1036 if ( rvf_name_id[ num_mb].mb_params.size != 0)
1037 { *mb_id = RVF_INVALID_MB_ID;
1038 return RVF_INTERNAL_ERR;
1039 }
1040
1041 rvf_get_available_mem( &available_mem, &required_mem);
1042
1043 if ( ( (required_mem + mb_param.size)*100) > ( available_mem * _rvf_get_mem_usage_ratio()) ) /* if there is not enough available memory to create this mb */
1044 { *mb_id = RVF_INVALID_MB_ID; /* In a next version: try to create a dynamic pool */
1045 return RVF_MEMORY_ERR;
1046 }
1047
1048 rvf_disable(20); /* enter critical section */
1049
1050 /* save the mb parameters for deletion */
1051 rvf_name_id[num_mb].mb_params.size = mb_param.size;
1052 rvf_name_id[num_mb].mb_params.watermark = mb_param.watermark;
1053
1054 * mb_id = rvf_name_id[num_mb].mb_id;
1055 mb = &rvf_banks[ *mb_id ];
1056 /* initialize the memory bank structure */
1057 mb->watermark += mb_param.watermark;
1058 mb->max += mb_param.size;
1059
1060 rvf_enable(); /* exit critical section */
1061
1062 return RVF_OK;
1063 }
1064
1065
1066 /*******************************************************************************
1067 **
1068 ** Function rvf_get_mb_id
1069 **
1070 ** Description Called by an application to get the memory bank id from its name
1071 **
1072 ** Parameters: memory bank name
1073 ** (return) memory bank id
1074 **
1075 ** Returns T_RVF_RET: RVF_OK if success
1076 **
1077 *******************************************************************************/
1078 T_RVF_RET rvf_get_mb_id(T_RVF_MB_NAME mb_name, T_RVF_MB_ID *mb_id)
1079 { UINT8 num_mb;
1080
1081
1082 /* find the mb name in the array */
1083 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
1084 if ( num_mb == RVF_MAX_TOTAL_MB ) /* mb name not found */
1085 { *mb_id = RVF_INVALID_MB_ID;
1086 return RVF_INVALID_PARAMETER;
1087 }
1088 if ( rvf_banks[ rvf_name_id[num_mb].mb_id ].max == 0 )
1089 { /* the memory bank has not been created */
1090 *mb_id = RVF_INVALID_MB_ID;
1091 return RVF_NOT_READY;
1092 }
1093 *mb_id = rvf_name_id[num_mb].mb_id;
1094 return RVF_OK;
1095 }
1096
1097
1098 /*******************************************************************************
1099 **
1100 ** Function rvf_delete_mb
1101 **
1102 ** Description Called by an application to delete a memory bank
1103 **
1104 ** Parameters: memory bank name
1105 **
1106 ** Returns T_RVF_RET: RVF_OK if success
1107 **
1108 *******************************************************************************/
1109 T_RVF_RET rvf_delete_mb(T_RVF_MB_NAME mb_name)
1110 { UINT8 num_mb;
1111 T_RVF_MB * mb;
1112
1113 /* find the mb name in the array */
1114 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
1115 if ( num_mb == RVF_MAX_TOTAL_MB ) /* mb name not found */
1116 { return RVF_INVALID_PARAMETER;
1117 }
1118 mb = &rvf_banks[ rvf_name_id[num_mb].mb_id ];
1119
1120 /* check if the mb is used more than once or not */
1121 if ( mb->max == rvf_name_id[num_mb].mb_params.size )
1122 { /* mb is used only once, check if cur_memory_used > 0 */
1123 if ( mb->cur_memory_used > 0)
1124 { rvf_send_trace( "RVF: rvf_delete_mb(): not all buffers have been freed", 53, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
1125 return RVF_MEMORY_ERR;
1126 /* free all buffers ????? -> NOT POSSIBLE */
1127 }
1128 /* initialize mb params */
1129 mb->max = 0;
1130 mb->first_buffer_index = RVF_INVALID_INDEX;
1131 mb->last_buffer_index = RVF_INVALID_INDEX;
1132 mb->watermark = 0;
1133 mb->returned_red = FALSE;
1134 mb->func = 0;
1135 #if RVF_ENABLE_STATS
1136 mb->max_reached = 0;
1137 mb->required_size = 0;
1138 mb->num_buf = 0;
1139 #endif
1140
1141 }
1142 else /* mb is still used by another entity */
1143 { /* change mb params */
1144 mb->max -= rvf_name_id[num_mb].mb_params.size;
1145 mb->watermark -= rvf_name_id[num_mb].mb_params.watermark;
1146 }
1147
1148 rvf_name_id[num_mb].mb_params.size = 0;
1149 rvf_name_id[num_mb].mb_params.watermark = 0;
1150
1151 return RVF_OK;
1152 }
1153
1154 T_RVF_RET rvf_mb_is_used(T_RVF_MB_NAME mb_name, UINT8* isUsed) {
1155 UINT8 num_mb;
1156 T_RVF_MB * mb;
1157
1158 *isUsed=0;
1159
1160 /* find the mb name in the array */
1161 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
1162 if ( num_mb == RVF_MAX_TOTAL_MB ) {/* mb name not found */
1163 return RVF_INVALID_PARAMETER;
1164 }
1165 mb = &rvf_banks[ rvf_name_id[num_mb].mb_id ];
1166
1167 /* check if the mb is used more than once or not */
1168 if ( mb->max == rvf_name_id[num_mb].mb_params.size ) {
1169 /* mb is used only once, check if cur_memory_used > 0 */
1170 if ( mb->cur_memory_used > 0) *isUsed=1;
1171 }
1172 return RVF_OK;
1173 }
1174
1175
1176
1177 /*******************************************************************************
1178 **
1179 ** Function rvf_get_mb_status
1180 **
1181 ** Description Called by an application to get the status of a memory bank
1182 **
1183 ** Parameters: memory bank id
1184 **
1185 ** Returns T_RVF_MB_STATUS: RVF_GREEN if everything is ok,
1186 ** RVF_YELLOW if watermark limit has been reached,
1187 ** RVF_RED if max size has been reached
1188 **
1189 *******************************************************************************/
1190 T_RVF_MB_STATUS rvf_get_mb_status(T_RVF_MB_ID mb_id)
1191 { T_RVF_MB * mb;
1192
1193 /* checking for invalid memory bank IDs */
1194 if (mb_id >= RVF_MAX_REAL_MB)
1195 {
1196 #ifdef RVM_DAR_SWE
1197 dar_diagnose_generate_emergency (RVF_INVALID_MD_ID_ERRROR,
1198 DAR_ASCII_FORMAT,
1199 RVM_USE_ID);
1200 #else
1201 rvf_send_trace (RVF_INVALID_MD_ID_ERRROR,
1202 sizeof (RVF_INVALID_MD_ID_ERRROR) - 1,
1203 NULL_PARAM,
1204 RV_TRACE_LEVEL_ERROR,
1205 RVM_USE_ID);
1206 #endif
1207 return RVF_RED;
1208 }
1209 mb = &rvf_banks[mb_id];
1210
1211 if ( mb->returned_red == TRUE) /* if a previous count buf or get buf has failed */
1212 { return RVF_RED;
1213 }
1214
1215 if ( mb->cur_memory_used < mb->watermark )
1216 { return RVF_GREEN;
1217 }
1218 else
1219 { if ( mb->cur_memory_used < mb->max )
1220 { return RVF_YELLOW;
1221 }
1222 else
1223 { return RVF_RED; /* since max and cur_memory_used are set to 0 for not-created mb, it will return RED*/
1224 }
1225 }
1226 }
1227
1228 /*******************************************************************************
1229 **
1230 ** Function rvf_get_mb_unused_mem
1231 **
1232 ** Description Called by an application to get the number of bytes available
1233 ** until the memory bank size.
1234 **
1235 ** Parameters: memory bank id
1236 **
1237 ** Returns UINT32: number of bytes available
1238 ** returns 0 if the memory bank has not been created.
1239 **
1240 *******************************************************************************/
1241 UINT32 rvf_get_mb_unused_mem(T_RVF_MB_ID mb_id)
1242 { T_RVF_MB * mb;
1243 mb = &rvf_banks[mb_id];
1244
1245 if ( mb->returned_red == TRUE) /* if a previous count buf or get buf has failed */
1246 { return 0;
1247 }
1248
1249 return( mb->max - mb->cur_memory_used);
1250 }
1251
1252 /*******************************************************************************
1253 **
1254 ** Function rvf_get_mb_unused_green_mem
1255 **
1256 ** Description Called by an application to get the number of bytes available
1257 ** until the memory bank watermark.
1258 **
1259 ** Parameters: memory bank id
1260 **
1261 ** Returns UINT32: number of bytes available
1262 ** returns 0 if the memory bank has not been created.
1263 **
1264 *******************************************************************************/
1265 UINT32 rvf_get_mb_unused_green_mem(T_RVF_MB_ID mb_id)
1266 { T_RVF_MB * mb;
1267 mb = &rvf_banks[mb_id];
1268
1269 if ( mb->returned_red == TRUE) /* if a previous count buf or get buf has failed */
1270 { return 0;
1271 }
1272
1273 if( mb->cur_memory_used > mb->watermark)
1274 { return 0;
1275 }
1276
1277 return( mb->watermark - mb->cur_memory_used);
1278 }
1279
1280 /*******************************************************************************
1281 **
1282 ** Function rvf_get_buf
1283 **
1284 ** Description Called by an application to get a buffer from a memory bank
1285 **
1286 ** Parameters: memory bank id, buffer size
1287 ** (return) buffer pointer to the allocated buffer or null if
1288 ** mb status is RVF_RED
1289 **
1290 ** Returns T_RVF_MB_STATUS: RVF_GREEN if everything is ok,
1291 ** RVF_YELLOW if watermark limit has been reached,
1292 ** RVF_RED if max size has been reached (does not return a buffer)
1293 **
1294 *******************************************************************************/
1295 T_RVF_MB_STATUS rvf_get_buf(T_RVF_MB_ID mb_id, UINT32 buffer_size, T_RVF_BUFFER** p_buffer)
1296 { T_RVF_MB * mb;
1297
1298 /* checking for invalid memory bank IDs */
1299 if (mb_id >= RVF_MAX_REAL_MB)
1300 {
1301 #ifdef RVM_DAR_SWE
1302 dar_diagnose_generate_emergency (RVF_INVALID_MD_ID_ERRROR,
1303 DAR_ASCII_FORMAT,
1304 RVM_USE_ID);
1305 #else
1306 rvf_send_trace (RVF_INVALID_MD_ID_ERRROR,
1307 sizeof (RVF_INVALID_MD_ID_ERRROR) - 1,
1308 NULL_PARAM,
1309 RV_TRACE_LEVEL_ERROR,
1310 RVM_USE_ID);
1311 #endif
1312 return RVF_RED;
1313 }
1314 mb = &rvf_banks[ mb_id ];
1315
1316 /* check memory usage */
1317 if ( ( mb->cur_memory_used + buffer_size) > mb->max )
1318 { /* over the limits, return RED and do not allocate a buffer */
1319 mb->returned_red = TRUE;
1320 *p_buffer = NULL;
1321 return RVF_RED;
1322 }
1323
1324 /* find a buffer of the requested size */
1325 *p_buffer = _find_buf( buffer_size );
1326 if ( *p_buffer == NULL ) /* error during allocation, not enough memory */
1327 { //rvf_send_trace( "RVF: rvf_get_buf(): not enough available physical memory", 56, NULL_PARAM, RV_TRACE_LEVEL_ERROR, TRACE_RVF_BUFFER );
1328 mb->returned_red = TRUE;
1329 return RVF_RED;
1330 }
1331
1332 #if RVF_ENABLE_STATS
1333 required_size += buffer_size;
1334 obtained_size += rvf_get_buf_size((UINT8*)(*p_buffer) + sizeof(T_RVF_INTERNAL_BUF));
1335 used_size += rvf_get_buf_size((UINT8*)(*p_buffer) + sizeof(T_RVF_INTERNAL_BUF)) + sizeof(T_RVF_INTERNAL_BUF) + RVF_CORRUPT_OVERHEAD;
1336 mem_in_use += rvf_get_buf_size((UINT8*)(*p_buffer) + sizeof(T_RVF_INTERNAL_BUF)) + sizeof(T_RVF_INTERNAL_BUF) + RVF_CORRUPT_OVERHEAD;
1337 #endif
1338
1339 if(INC_Initialize_State==INC_END_INITIALIZE) rvf_disable(20); /* enter critical section */
1340 #if RVF_ENABLE_BUF_LINKAGE_CHECK
1341 /* set as unlinked */
1342 RVF_SET_BUF_UNLINKED((T_RVF_INTERNAL_BUF*)(*p_buffer));
1343 #endif
1344
1345 /* increase memory use counter */
1346 mb->cur_memory_used += rvf_get_buf_size( (UINT8*)(*p_buffer) + sizeof(T_RVF_INTERNAL_BUF) );
1347 ( (T_RVF_INTERNAL_BUF *) (*p_buffer))->header.external.mb_id = mb_id;
1348 ( (T_RVF_INTERNAL_BUF *) (*p_buffer))->header.external.mb_expected = RVF_INVALID_MB_ID;
1349
1350 *p_buffer = (UINT8*)(*p_buffer) + sizeof(T_RVF_INTERNAL_BUF);
1351
1352 #if RVF_ENABLE_STATS
1353 if ( mb->cur_memory_used > mb->max_reached )
1354 { mb->max_reached = mb->cur_memory_used;
1355 }
1356 mb->required_size += buffer_size;
1357 mb->num_buf++;
1358 #endif
1359
1360 if(INC_Initialize_State==INC_END_INITIALIZE) rvf_enable(); /* exit critical section */
1361
1362 /* return the correct flag */
1363 if ( mb->cur_memory_used > mb->watermark )
1364 { return RVF_YELLOW;
1365 }
1366 else
1367 { return RVF_GREEN;
1368 }
1369 }
1370
1371 /*******************************************************************************
1372 **
1373 ** Function rvf_count_buf
1374 **
1375 ** Description Called by an application to change the memory bank on which a buffer is counted
1376 **
1377 ** Parameters: new memory bank id,
1378 ** pointer to the buffer.
1379 **
1380 ** Returns T_RVF_MB_STATUS: RVF_GREEN if everything is ok,
1381 ** RVF_YELLOW if watermark limit has been reached,
1382 ** RVF_RED if max size has been reached
1383 **
1384 *******************************************************************************/
1385 T_RVF_MB_STATUS rvf_count_buf(T_RVF_MB_ID mb_id, T_RVF_BUFFER * p_buffer)
1386 { T_RVF_INTERNAL_BUF * buf;
1387 UINT32 buf_size;
1388 T_RVF_MB * new_mb;
1389 T_RVF_MB * old_mb;
1390
1391 /* checking for invalid memory bank IDs */
1392 if (mb_id >= RVF_MAX_REAL_MB)
1393 {
1394 #ifdef RVM_DAR_SWE
1395 dar_diagnose_generate_emergency (RVF_INVALID_MD_ID_ERRROR,
1396 DAR_ASCII_FORMAT,
1397 RVM_USE_ID);
1398 #else
1399 rvf_send_trace (RVF_INVALID_MD_ID_ERRROR,
1400 sizeof (RVF_INVALID_MD_ID_ERRROR) - 1,
1401 NULL_PARAM,
1402 RV_TRACE_LEVEL_ERROR,
1403 RVM_USE_ID);
1404 #endif
1405 return RVF_RED;
1406 }
1407 buf = (T_RVF_INTERNAL_BUF *) ( (UINT8 *) p_buffer - sizeof(T_RVF_INTERNAL_BUF) );
1408 new_mb = &rvf_banks[mb_id];
1409 old_mb = &rvf_banks[buf->header.external.mb_id];
1410
1411 /* get the size of the buffer and try to count it on the new mb */
1412 buf_size = rvf_get_buf_size( p_buffer );
1413
1414 if ( ( new_mb->cur_memory_used + buf_size ) < new_mb->max )
1415 { /* there is enough memory in the new mb */
1416
1417 if ( buf->header.external.mb_expected != RVF_INVALID_MB_ID )
1418 { /* remove the buffer from the list of waiting buffers in mb expected */
1419 _remove_from_list( buf, &rvf_banks[buf->header.external.mb_expected] );
1420 buf->header.external.mb_expected = RVF_INVALID_MB_ID;
1421 }
1422
1423 rvf_disable(20); /* enter critical section */
1424
1425 /* decrease the memory used in the old mb */
1426 old_mb->cur_memory_used -= buf_size;
1427
1428 /* increase memory used in the new mb */
1429 new_mb->cur_memory_used += buf_size;
1430
1431 rvf_enable(); /* exit critical section */
1432
1433 /* call the callback function if state of the old mb switches to RVF_GREEN and there is no buffer waiting */
1434 if ( (old_mb->cur_memory_used < old_mb->watermark) && (old_mb->first_buffer_index == RVF_INVALID_INDEX) && (old_mb->returned_red == TRUE) && ( old_mb->func != NULL) )
1435 { old_mb->returned_red = FALSE;
1436 old_mb->func( buf->header.external.mb_id);
1437 }
1438 else
1439 { /* count as many waiting buffers as possible on the old mb */
1440 while( (old_mb->first_buffer_index != RVF_INVALID_INDEX) && (rvf_count_buf( buf->header.external.mb_id, (UINT8 *) (waiting_buffers[old_mb->first_buffer_index]) + sizeof(T_RVF_INTERNAL_BUF)) != RVF_RED) );
1441 if ( (old_mb->cur_memory_used < old_mb->watermark) && (old_mb->first_buffer_index == RVF_INVALID_INDEX) && (old_mb->returned_red == TRUE) && ( old_mb->func != NULL) )
1442 { old_mb->returned_red = FALSE;
1443 old_mb->func( buf->header.external.mb_id);
1444 }
1445 }
1446 /* change mb_id of the buffer */
1447 buf->header.external.mb_id = mb_id;
1448
1449
1450
1451 #if RVF_ENABLE_STATS
1452 if ( new_mb->cur_memory_used > new_mb->max_reached )
1453 { new_mb->max_reached = new_mb->cur_memory_used;
1454 }
1455 #endif
1456
1457 if ( new_mb->cur_memory_used > new_mb->watermark )
1458 { return RVF_YELLOW;
1459 }
1460 else
1461 { return RVF_GREEN;
1462 }
1463 }
1464 else
1465 { /* there is not enough memory in the new mb_id */
1466 if ( buf->header.external.mb_expected != RVF_INVALID_MB_ID) /* remove the buffer from old expected mb */
1467 { _remove_from_list( buf, &rvf_banks[ buf->header.external.mb_expected] );
1468 }
1469 /* enqueue the buffer in the list of waiting buffer */
1470 buf->header.external.mb_expected = mb_id;
1471 _add_to_list( buf, new_mb );
1472 new_mb->returned_red = TRUE;
1473 return RVF_RED;
1474 }
1475 }
1476
1477 /*******************************************************************************
1478 **
1479 ** Function rvf_free_buf
1480 **
1481 ** Description Called by an application to free a buffer
1482 **
1483 ** Parameters: buffer pointer
1484 **
1485 ** Returns T_RVF_RET: T_RVF_OK if succesful,
1486 **
1487 *******************************************************************************/
1488 T_RVF_RET rvf_free_buf( T_RVF_BUFFER * p_buffer)
1489 { T_RVF_INTERNAL_BUF * buf;
1490 T_RVF_MB * mb;
1491 T_RVF_MB_ID mb_id;
1492 UINT32 buf_size;
1493
1494
1495 buf = USER2MEM(p_buffer);
1496
1497 mb_id = buf->header.external.mb_id;
1498 mb = &rvf_banks[mb_id];
1499 buf_size = rvf_get_buf_size(p_buffer);
1500
1501 /* do not need to change the mb id of the buffer, since it will be overwritten by p_prev */
1502
1503 /* free the buffer */
1504 if ( !_release_buf(buf) )
1505 { return RVF_MEMORY_ERR;
1506 }
1507
1508 #if RVF_ENABLE_STATS
1509 mem_in_use -= buf_size + sizeof(T_RVF_INTERNAL_BUF) + RVF_CORRUPT_OVERHEAD;
1510 #endif
1511
1512 rvf_disable(20); /* enter critical section */
1513
1514 /* decrease mb memory use */
1515 mb->cur_memory_used -= buf_size;
1516
1517 rvf_enable(); /* exit critical section */
1518
1519
1520 /* call the callback function if state of the mb switches to RVF_GREEN and there is no buffer waiting */
1521 if ( (mb->returned_red == TRUE) && (mb->cur_memory_used < mb->watermark) && ( mb->first_buffer_index == RVF_INVALID_INDEX) && ( mb->func != NULL) )
1522 { mb->returned_red = FALSE;
1523 mb->func( mb_id);
1524 }
1525 else
1526 { /* count as many waiting buffers as possible on the mb */
1527 while( (mb->first_buffer_index != RVF_INVALID_INDEX) && (rvf_count_buf( mb_id, (UINT8 *) (waiting_buffers[mb->first_buffer_index]) + sizeof(T_RVF_INTERNAL_BUF)) != RVF_RED) );
1528 if ( (mb->cur_memory_used < mb->watermark) && ( mb->first_buffer_index == RVF_INVALID_INDEX) && (mb->returned_red == TRUE) && ( mb->func != NULL) )
1529 { mb->returned_red = FALSE;
1530 mb->func( mb_id);
1531 }
1532 }
1533
1534 return RVF_OK;
1535 }
1536
1537
1538 /*******************************************************************************
1539 **
1540 ** Function rvf_set_callback_func
1541 **
1542 ** Description Called the first time an application wants to set the callback
1543 ** function associated to a memory bank.
1544 **
1545 ** Parameters: memory bank id, pointer to the callback function.
1546 **
1547 ** Returns T_RVF_RET: T_RVF_OK if succesful,
1548 **
1549 *******************************************************************************/
1550 T_RVF_RET rvf_set_callback_func(T_RVF_MB_ID mb_id, MB_CALLBACK_FUNC func)
1551 { T_RVF_MB * mb;
1552
1553 /* checking for invalid memory bank IDs */
1554 if (mb_id >= RVF_MAX_REAL_MB)
1555 return RVF_INVALID_PARAMETER;
1556 mb = &rvf_banks[mb_id];
1557 if ( (mb->max != 0) && (mb->func == NULL) ) /* if the mb has been created and the callback func has never been set */
1558 { mb->func = func;
1559 return RVF_OK;
1560 }
1561 return RVF_INVALID_PARAMETER;
1562 }
1563
1564
1565 /*******************************************************************************
1566 **
1567 ** Function rvf_change_callback_func
1568 **
1569 ** Description Called by an application to change the callback
1570 ** function associated to a memory bank.
1571 ** It means the callback function has to be set before.
1572 **
1573 ** Parameters: memory bank id, pointer to the callback function.
1574 **
1575 ** Returns T_RVF_RET: T_RVF_OK if succesful,
1576 **
1577 *******************************************************************************/
1578 T_RVF_RET rvf_change_callback_func(T_RVF_MB_ID mb_id, MB_CALLBACK_FUNC func)
1579 { T_RVF_MB * mb;
1580
1581 /* checking for invalid memory bank IDs */
1582 if (mb_id >= RVF_MAX_REAL_MB)
1583 return RVF_INVALID_PARAMETER;
1584 mb = &rvf_banks[mb_id];
1585 if ( (mb->max != 0) && (mb->func != NULL) ) /* if the mb has been created and the callback func has already been set */
1586 { mb->func = func;
1587 return RVF_OK;
1588 }
1589 return RVF_INVALID_PARAMETER;
1590 }
1591
1592 #ifdef _WINDOWS_
1593 /*******************************************************************************
1594 **
1595 ** Function _rvf_window_dump_mem
1596 **
1597 ** Description Called by a C++ object to update the graphical display of
1598 ** memory
1599 **
1600 ** Parameters: Opaque pointer to C++ object
1601 **
1602 ** Returns void
1603 **
1604 ** WARNING DON'T CHANGE THE SYNTAX OF DISPLAYED DATAS SINCE
1605 ** THEY ARE PARSED TO DISPLAY GRAPHICALLY THE MEMORY
1606 ** STATUS
1607 **
1608 *******************************************************************************/
1609 void _rvf_window_dump_mem(void *m)
1610 {
1611
1612
1613 #if RVF_ENABLE_STATS /* conditional compilation if stats are enabled */
1614 char mb_info[100];
1615 UINT16 num_mb, num_buf, index;
1616 UINT32 total_mem_size = 0;
1617 UINT32 total_max_used = 0;
1618 UINT32 total_cur_used = 0;
1619 T_RVF_MB * mb;
1620
1621
1622 for ( num_mb = 0; num_mb < RVF_MAX_TOTAL_MB; num_mb++ )
1623 {
1624 /* trace the mb if it has been created*/
1625 if ( rvf_name_id[num_mb].mb_params.size > 0 )
1626 { mb = &rvf_banks[ rvf_name_id[num_mb].mb_id ];
1627 num_buf = 0;
1628 index = mb->first_buffer_index;
1629 while ( index != RVF_INVALID_INDEX)
1630 { num_buf++;
1631 index = next_buffer[index];
1632 }
1633 strcpy(mb_info,rvf_name_id[num_mb].mb_name);
1634 mb_info[10]='\0';
1635 AddNewState(m,mb_info,
1636 mb->cur_memory_used,mb->max_reached,mb->watermark,mb->max);
1637
1638
1639 total_mem_size += mb->max;
1640 total_max_used += mb->max_reached;
1641 total_cur_used += mb->cur_memory_used;
1642 }
1643 }
1644
1645 #endif /* RVF_ENABLE_STATS */
1646 }
1647
1648 #endif
1649
1650 /*******************************************************************************
1651 **
1652 ** Function rvf_dump_mem
1653 **
1654 ** Description Called by an application to dump mb state and display statistics
1655 **
1656 ** Parameters: None
1657 **
1658 ** Returns void
1659 **
1660 ** WARNING DON'T CHANGE THE SYNTAX OF DISPLAYED DATAS SINCE
1661 ** THEY ARE PARSED TO DISPLAY GRAPHICALLY THE MEMORY
1662 ** STATUS
1663 **
1664 *******************************************************************************/
1665 void rvf_dump_mem()
1666 {
1667 #if RVF_ENABLE_STATS /* conditional compilation if stats are enabled */
1668 char mb_info[100];
1669 UINT16 num_mb, num_buf, index;
1670 UINT32 total_mem_size = 0;
1671 UINT32 total_max_used = 0;
1672 UINT32 total_cur_used = 0;
1673 T_RVF_MB * mb;
1674
1675
1676 /* display memory required, obtained and ratio */
1677 rvf_send_trace("MEM STAT: Total memory required", 31, required_size, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1678 rvf_send_trace("MEM STAT: Total memory obtained", 31, obtained_size, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1679 rvf_send_trace("MEM STAT: Total memory used ", 31, used_size, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1680 sprintf( mb_info,"MEM STAT: Mem usage ratio : %010f%%", ( (double)(required_size) / (double)(obtained_size) ) *100 );
1681 rvf_send_trace(mb_info, 44, NULL_PARAM , RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1682
1683 rvf_send_trace("*** START DUMPING MEMORY BANK ***", 33, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1684 /* for each mb, display its name, its id, its cur_size, its watermark, its limit, its max reached, the number of callback functions enqueued,
1685 (the requested size, the number of allocated buffer), the average buffer size for this mb */
1686 rvf_send_trace("**MB_NAME* Id Used_mem Watermark Limit Peak Nb_buff Avg_buf_size", 67, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1687
1688 for ( num_mb = 0; num_mb < RVF_MAX_TOTAL_MB; num_mb++ )
1689 {
1690 /* trace the mb if it has been created*/
1691 if ( rvf_name_id[num_mb].mb_params.size > 0 )
1692 { mb = &rvf_banks[ rvf_name_id[num_mb].mb_id ];
1693 num_buf = 0;
1694 index = mb->first_buffer_index;
1695 while ( index != RVF_INVALID_INDEX)
1696 { num_buf++;
1697 index = next_buffer[index];
1698 }
1699 sprintf( mb_info, "%10.10s %2d %6d %6d %6d %6d %2d %6d",
1700 rvf_name_id[num_mb].mb_name, rvf_name_id[num_mb].mb_id,
1701 mb->cur_memory_used, mb->watermark, mb->max, mb->max_reached, num_buf,
1702 mb->num_buf == 0? 0:mb->required_size / mb->num_buf);
1703
1704 rvf_send_trace( mb_info, 67, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1705
1706 total_mem_size += mb->max;
1707 total_max_used += mb->max_reached;
1708 total_cur_used += mb->cur_memory_used;
1709 }
1710 }
1711 sprintf( mb_info, "TOTAL: ******** %6d********** %6d %6d",
1712 total_cur_used, total_mem_size, total_max_used );
1713
1714 rvf_send_trace( mb_info, 46, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
1715
1716 #endif /* RVF_ENABLE_STATS */
1717 }
1718
1719
1720 /*******************************************************************************
1721 **
1722 ** Function rvf_get_available_mem
1723 **
1724 ** Description Called to get the total size of the memory and the used size.
1725 **
1726 ** Parameters: (return) UINT32 * total_size: contains the number of bytes in the memory.
1727 ** (return) UINT32 * used_size: contains the number of used bytes in the memory.
1728 **
1729 ** Returns T_RVF_RET: RVF_OK if successful, else a negative value.
1730 **
1731 *******************************************************************************/
1732 T_RVF_RET rvf_get_available_mem( UINT32 * total_size, UINT32 * used_size )
1733 {
1734 UINT16 count;
1735 *total_size = 0;
1736 *used_size = 0;
1737
1738 /* check if there is enough available physical memory (static or dynamic): if Sum(mb size) <= Sum(pool size)*/
1739 for ( count = 0; count < _rvf_get_number_of_pool(); count ++ ) /* sum the memory in pools */
1740 { *total_size += _rvf_pools[count].pool_size;
1741 }
1742 /* sum the memory required by existing mb */
1743 for ( count = 0; count < RVF_MAX_REAL_MB; count ++ )
1744 { *used_size += rvf_banks[count].max;
1745 }
1746
1747 return RVF_OK;
1748 }
1749
1750
1751 /*******************************************************************************
1752 **
1753 ** Function rvf_get_mb_param
1754 **
1755 ** Description return the parameters of a specific memory bank
1756 **
1757 ** Parameters: T_RVF_MB_NAME: name of the memory bank
1758 ** (return) T_RVF_MB_PARAM*: parameter of the memory bank.
1759 **
1760 ** Returns T_RVF_RET: RVF_OK if successful, else a negative value.
1761 **
1762 *******************************************************************************/
1763 T_RVF_RET rvf_get_mb_param( T_RVF_MB_NAME mb_name, T_RVF_MB_PARAM * param)
1764 { UINT8 num_mb;
1765
1766 /* find the mb name in the array */
1767 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
1768 if ( num_mb == RVF_MAX_TOTAL_MB ) /* mb name not found */
1769 { return RVF_INVALID_PARAMETER;
1770 }
1771
1772 /* copy the parameters of the memory bank */
1773 *param = rvf_name_id[num_mb].mb_params;
1774
1775 return RVF_OK;
1776 }
1777
1778
1779 /*******************************************************************************
1780 **
1781 ** Function rvf_set_mb_param
1782 **
1783 ** Description change the parameters of a specific memory bank
1784 **
1785 ** Parameters: T_RVF_MB_NAME: name of the memory bank
1786 ** T_RVF_MB_PARAM*: parameter of the memory bank.
1787 **
1788 ** Returns T_RVF_RET: RVF_OK if successful, else a negative value.
1789 **
1790 *******************************************************************************/
1791 T_RVF_RET rvf_set_mb_param( T_RVF_MB_NAME mb_name, T_RVF_MB_PARAM * param)
1792 { UINT8 num_mb;
1793 T_RVF_MB_ID mb_id;
1794 T_RVF_MB * mb;
1795
1796 /* find the mb name in the array */
1797 for ( num_mb = 0; (num_mb < RVF_MAX_TOTAL_MB) && (!_str_cmp(mb_name, rvf_name_id[num_mb].mb_name) ); num_mb++);
1798 if ( num_mb == RVF_MAX_TOTAL_MB ) /* mb name not found */
1799 { return RVF_INVALID_PARAMETER;
1800 }
1801
1802 mb_id = rvf_name_id[num_mb].mb_id;
1803 mb = &rvf_banks[ mb_id ];
1804
1805 rvf_disable(20); /* enter critical section */
1806
1807 /* decrease the mb param by the old parameters */
1808 mb->watermark -= rvf_name_id[num_mb].mb_params.watermark;
1809 mb->max -= rvf_name_id[num_mb].mb_params.size;
1810
1811 /* save the mb parameters */
1812 rvf_name_id[num_mb].mb_params.size = param->size;
1813 rvf_name_id[num_mb].mb_params.watermark = param->watermark;
1814
1815 /* increase the mb param by the new parameters */
1816 mb->watermark += param->watermark;
1817 mb->max += param->size;
1818
1819 rvf_enable(); /* exit critical section */
1820
1821 /* dequeue callback functions if state switches to RVF_GREEN */
1822
1823 return RVF_OK;
1824 }
1825
1826
1827
1828
1829 /*******************************************************************************
1830 **
1831 ** Function rvf_empty_mailboxes
1832 **
1833 ** Description Called by rvf_exit_task to empty a task's mailboxes before
1834 ** killing it
1835 **
1836 ** Parameters: task_id: task of wich the mailboxes have to be emptied
1837 **
1838 ** Returns RV_OK
1839 **
1840 *******************************************************************************/
1841 T_RV_RET _rvf_empty_mailboxes (T_RVF_G_ADDR_ID task_id)
1842 {
1843 void * p_buf = NULL;
1844 T_RVF_INTERNAL_BUF * p_hdr;
1845 UINT8 mbox_id = 0;
1846
1847 if (task_id >= MAX_RVF_TASKS)
1848 {
1849 rvf_send_trace( "RVF: rvf_empty_mbox(): invalid taskid: ", 39, task_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
1850 return RVF_INVALID_PARAMETER;
1851 }
1852
1853 for (mbox_id = 0; mbox_id< RVF_NUM_TASK_MBOX; mbox_id++)
1854 { /* while the chained list is not empty */
1855 /*while ( OSTaskQFirst[task_id][mbox_id] )
1856 {
1857 rvf_disable(9);
1858
1859 p_hdr = OSTaskQFirst[task_id][mbox_id];
1860 OSTaskQFirst[task_id][mbox_id] = p_hdr->p_next;
1861 */
1862 while ( pRtAddrIdTable[task_id]->OSTaskQFirst[mbox_id] )
1863 {
1864 rvf_disable(9);
1865
1866 p_hdr = pRtAddrIdTable[task_id]->OSTaskQFirst[mbox_id];
1867 pRtAddrIdTable[task_id]->OSTaskQFirst[mbox_id] = p_hdr->p_next;
1868
1869 #if RVF_ENABLE_BUF_LINKAGE_CHECK
1870 /* set as unlinked */
1871 RVF_SET_BUF_UNLINKED(p_hdr);
1872 #endif
1873
1874 p_buf = (UINT8 *)p_hdr + sizeof(T_RVF_INTERNAL_BUF);
1875
1876 rvf_enable(); /* exit critical section */
1877
1878 rvf_free_buf(p_buf);
1879 }
1880 }
1881
1882
1883 return (RV_OK);
1884 }
1885
1886
1887 /*******************************************************************************
1888 **
1889 ** Function rvf_scan_next
1890 **
1891 ** Description return the next item in the queue if any.
1892 ** If the end of the queue is reached, returns NULL.
1893 ** If current item is NULL, returns the first item in the queue.
1894 **
1895 ** Returns NULL if the end of the queue is reached, else a pointer to the buffer.
1896 **
1897 *******************************************************************************/
1898 T_RVF_BUFFER * rvf_scan_next (T_RVF_BUFFER_Q * p_q, T_RVF_BUFFER * p_buf)
1899 {
1900 T_RVF_INTERNAL_BUF *p_hdr;
1901
1902 if (!p_q->count) /* if the queue is empty */
1903 return (NULL);
1904
1905 if (p_buf == NULL) /* if current item == NULL, returns the first one */
1906 {
1907 return (T_RVF_BUFFER*)p_q->p_first;
1908 }
1909
1910 rvf_disable(12); /* enter critical section */
1911
1912 p_hdr = (T_RVF_INTERNAL_BUF *)((UINT8 *)p_buf - sizeof(T_RVF_INTERNAL_BUF));
1913 p_hdr = p_hdr->p_next;
1914 if (p_hdr != NULL)
1915 { p_hdr = (T_RVF_INTERNAL_BUF*) ((UINT8 *)p_hdr + sizeof(T_RVF_INTERNAL_BUF));
1916 }
1917
1918 rvf_enable();
1919
1920 return (T_RVF_BUFFER*)p_hdr;
1921 }
1922
1923
1924 /*******************************************************************************
1925 **
1926 ** Function rvf_remove_from_queue
1927 **
1928 ** Description remove a specific item from a queue
1929 **
1930 ** Returns RVF_OK if the item is removed, RVF_INTERNAL_ERR else.
1931 **
1932 *******************************************************************************/
1933 T_RVF_RET rvf_remove_from_queue (T_RVF_BUFFER_Q * p_q, T_RVF_BUFFER * p_buf)
1934 {
1935 T_RVF_INTERNAL_BUF *p_hdr;
1936 T_RVF_INTERNAL_BUF *p_target;
1937
1938
1939 if (!p_q->count) /* if the queue is empty */
1940 return (RVF_INTERNAL_ERR);
1941
1942 rvf_disable(12); /* enter critical section */
1943
1944 /* find the specific item in the queue */
1945 p_target = USER2MEM((UINT8*)p_buf);
1946 p_hdr = USER2MEM( (UINT8 *)p_q->p_first);
1947
1948 if( p_hdr == p_target )
1949 { /* the specific item is the first one */
1950 rvf_dequeue( p_q);
1951 rvf_enable();
1952 return (RVF_OK);
1953 }
1954
1955 while( (p_hdr->p_next != p_target) && (p_hdr->p_next != NULL) )
1956 { p_hdr = p_hdr->p_next;
1957 }
1958
1959 if( p_hdr->p_next == NULL) /* item not found */
1960 { rvf_enable();
1961 return (RVF_INTERNAL_ERR);
1962 }
1963
1964
1965 p_hdr->p_next = p_target->p_next;
1966 p_q->count--;
1967
1968 /* if we removed the last buffer */
1969 if (p_q->p_last == p_buf)
1970 { p_q->p_last = p_hdr + sizeof(T_RVF_INTERNAL_BUF);
1971 }
1972
1973 p_target->p_next = NULL;
1974
1975 #if RVF_ENABLE_BUF_LINKAGE_CHECK
1976 /* set as unlinked */
1977 RVF_SET_BUF_UNLINKED(p_target);
1978 #endif
1979
1980 rvf_enable(); /* exit critical section */
1981
1982 return (RVF_OK);
1983 }
1984
1985 /*******************************************************************************
1986 **
1987 ** Function rvf_dump_pool
1988 **
1989 ** Description Called by an application to dump memory pool usage
1990 **
1991 ** Parameters: None
1992 **
1993 ** Returns void
1994 **
1995 *******************************************************************************/
1996 void rvf_dump_pool()
1997 {
1998 #if RVF_ENABLE_STATS /* conditional compilation if stats are enabled */
1999
2000 UINT16 num_pool;
2001 UINT32 total_mem = 0;
2002
2003 /* display memory stats */
2004 rvf_send_trace("*** START DUMPING MEMORY ***", 28, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
2005
2006 /* display the total amount of memory available in the system */
2007 /* and the total amount of memory currently in use */
2008 for( num_pool = 0; num_pool < _rvf_get_number_of_pool(); num_pool++)
2009 { total_mem += _rvf_pools[num_pool].pool_size;
2010 }
2011
2012 rvf_send_trace( "Total memory available ", 23, total_mem, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
2013 rvf_send_trace( "Memory currently in use", 23, mem_in_use, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
2014
2015 #endif /* RVF_ENABLE_STATS */
2016 }
2017
2018 static void rvf_free_protected_buf(void *buf)
2019 {
2020 rvf_free_buf(buf);
2021 }
2022
2023 void rvf_get_protected_buf(T_RVF_MB_ID mb_id, UINT32 buffer_size, T_RVF_BUFFER** p_buffer)
2024 {
2025 T_RVF_MB_STATUS err;
2026 err=rvf_get_buf(mb_id,buffer_size,p_buffer);
2027 if (err==RVF_GREEN)
2028 {
2029 struct _protectedPtr_ *ptr;
2030 struct _exceptionContext_ *context;
2031
2032 context=_currentExceptionContext_[rvf_get_taskid()];
2033 err=rvf_get_buf(mb_id,sizeof(struct _protectedPtr_),(void*)&ptr);
2034 ptr->next=NULL;
2035 ptr->previous=NULL;
2036 ptr->ptr=*p_buffer;
2037 ptr->func=rvf_free_protected_buf;
2038
2039 if (err==RVF_GREEN)
2040 {
2041 if (context->stack==NULL)
2042 {
2043 context->stack=ptr;
2044 }
2045 else
2046 {
2047 ptr->previous=context->stack;
2048 context->stack->next=ptr;
2049 context->stack=ptr;
2050 }
2051 }
2052 else
2053 {
2054 rvf_free_buf(*p_buffer);
2055 }
2056 }
2057 if (err!=RVF_GREEN)
2058 throw(E_not_enough_memory);
2059 }
2060
2061 //TISHMMS Project
2062 /* add by xmzhou_trace_string to trace debug trace message */
2063 void xmzhou_trace_string(char * string2trace)
2064 {
2065 rvf_send_trace(string2trace,strlen(string2trace),NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
2066 }
2067
2068 void xmzhou_trace_string_value(char * string2trace,UINT32 value)
2069 {
2070 rvf_send_trace(string2trace,strlen(string2trace),value, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
2071 }
2072
2073 static void mychar2hex(char ch, char *str)
2074 {
2075 unsigned char h_nibble = (ch >> 4) & 0x0F;
2076 unsigned char l_nibble = ch & 0x0F;
2077
2078 if (h_nibble < 10)
2079 str[0] = 48 + h_nibble;
2080 else
2081 str[0] = 55 + h_nibble;
2082
2083 if (l_nibble < 10)
2084 str[1] = 48 + l_nibble;
2085 else
2086 str[1] = 55 + l_nibble;
2087 }
2088
2089 void xmzhou_trace_n_bytes(char * buffer0, UINT32 len)
2090 {
2091 int i;
2092 int traced_len=0;
2093 char mybuffer[40];
2094 char *tracebuffer;
2095
2096 if(buffer0==NULL) return;
2097
2098 xmzhou_trace_string_value("xmzhou dumping data length=",len);
2099 xmzhou_trace_string("-------");
2100
2101
2102 while(traced_len<len){
2103
2104 if((len-traced_len)>=16){
2105 tracebuffer=mybuffer;
2106 for (i = 0; i < 16; i++) {
2107 mychar2hex (buffer0[traced_len+i], tracebuffer);
2108 tracebuffer += 2;
2109 }
2110 traced_len+=16;
2111 *tracebuffer = '\0';
2112 rvf_send_trace(mybuffer,strlen(mybuffer),NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
2113 rvf_delay(20);
2114 }else{
2115 tracebuffer=mybuffer;
2116 for(i=0;i<(len-traced_len);i++)
2117 {
2118 mychar2hex (buffer0[traced_len+i], tracebuffer);
2119 tracebuffer += 2;
2120 }
2121 *tracebuffer = '\0';
2122 rvf_send_trace(mybuffer,strlen(mybuffer),NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
2123 rvf_delay(20);
2124 break;
2125 }
2126
2127 }
2128 }