comparison riviera/rvf/rvf_buffer.c @ 0:75a11d740a02

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