MHEG5  18.9.0
MHEG5 Documentation
glue_memory.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2000 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
26 /*---includes for this file--------------------------------------------------*/
27 #include <stdlib.h>
28 #ifdef TRACING
29 #include <stdio.h>
30 #endif
31 #include <string.h>
32 #include "stb_os.h"
33 #include "glue_debug.h"
34 #include "glue_memory.h"
35 
36 /*---constant definitions for this file--------------------------------------*/
37 
38 #define MallocFunc STB_MemAlloc
39 #define FreeFunc STB_MemFree
40 
41 
42 #define MAX_BLK_STRS 0x80 /* 128 memory blocks */
43 #define VTINY_BITS 2
44 #define MIGIT_BITS 3
45 #define SMALL_BITS 4
46 #define MEDUM_BITS 5
47 #define LARGE_BITS 6
48 #define STR_DATA_SIZE(bz) (MAX_BLK_STRS << bz)
49 #define STR_BLCK_SIZE(bz) STR_DATA_SIZE(bz) + sizeof(S_STRINGS_BLOCK)
50 #define CONTROL_SIZE (MAX_BLK_STRS >> 3)
51 
52 #define BlkStrFree( head, bz, data ) \
53  { S_STRINGS_BLOCK *pBlk = head; \
54  do { \
55  unsigned char *blk_data = (unsigned char *)pBlk + sizeof(S_STRINGS_BLOCK); \
56  if (data >= blk_data \
57  && data < blk_data + STR_DATA_SIZE(bz)) \
58  { int tmp; \
59  tmp = (data - blk_data) >> bz; \
60  pBlk->control[tmp >> 3] &= (U8BIT) ~(1 << (tmp & 7)); \
61  break; \
62  } \
63  pBlk = pBlk->next; \
64  } while (pBlk != NULL); \
65  if (pBlk == NULL) { TRACE(TERROR, ("Not freed %x", data)) } \
66  }
67 
68 typedef struct s_strings_block
69 {
72 #ifdef MHG_TRACK_MEM
73  U16BIT line[MAX_BLK_STRS];
74 #endif
76 
77 
78 #ifdef MHG_TRACK_MEM
79  #define MH5EMT_MAGIC 0xE579A36D
80 
81 typedef struct _mh5emtEntry_struct mh5emtEntry_t, *pMh5emtEntry_t;
82 
83 struct _mh5emtEntry_struct
84 {
85  pMh5emtEntry_t addr;
86  pMh5emtEntry_t prev;
87  pMh5emtEntry_t next;
88  const char *callingFunc;
89  unsigned int size;
90  int line;
91  int src;
92  int magic;
93 };
94 #endif
95 
96 /*---local (static) variable declarations for this file----------------------*/
102 
103 #ifdef TRACING
104  #define TOTAL_GRPS 24
105 static int mem_prints = 0;
106 static int mem_alloc_failed[TOTAL_GRPS];
107 static int mem_alloc_counts[TOTAL_GRPS];
108 static int mem_grp_max_sz[TOTAL_GRPS];
109 #endif
110 
111 #ifdef MHG_TRACK_MEM
112 static void *mh5emt_mutex = NULL;
113 static mh5emtEntry_t mh5emt_listHead;
114 static pMh5emtEntry_t pMh5emt_listTail = NULL;
115 
116 const char *mem_strings[MAX_MEM_SRCS] = {
117  "TOTALMEM", "SYSTEM ", "DSM-CC ", "SI_QUERY", "SSFCACHE", "FREETYPE", "MHENGINE", "GRAPHICS", "SURFACES"
118 };
119 
120 static unsigned long cur_mem_total[MAX_MEM_SRCS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
121 static unsigned long max_mem_total[MAX_MEM_SRCS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
122 
123  #ifdef _WINDOWS
124  #define MAX_SAVED_MALLOCS 0x1000
125 mh5emtEntry_t saved_mallocs[MAX_SAVED_MALLOCS];
126 int saved_malloc_cnt = 0;
127  #endif
128 
129 #endif
130 
131 
132 /*---local function definitions----------------------------------------------*/
133 
134 /*---global function definitions---------------------------------------------*/
135 
136 #ifdef MHG_TRACK_MEM
137 void mh5emt_init(void)
138 {
139 #ifdef TRACING
140  int g, sz, ts = 0;
141  for (g = 0, sz = 2; g != TOTAL_GRPS; g++)
142  {
143  mem_grp_max_sz[g] = sz;
144  if ((sz >= 32) && (sz <= 1024))
145  {
146  if (ts)
147  {
148  sz += ts;
149  ts = 0;
150  }
151  else
152  {
153  ts = sz >> 1;
154  sz += ts;
155  }
156  }
157  else
158  {
159  sz <<= 1; /* multiply by 2 */
160  }
161  }
162 #endif
163  if (pMh5emt_listTail == NULL)
164  {
165  mh5emt_mutex = STB_OSCreateMutex();
166 
167  /* -- Initialise engine memory tracking */
168  mh5emt_listHead.magic = 0;
169  mh5emt_listHead.callingFunc = NULL;
170  mh5emt_listHead.size = 0;
171  mh5emt_listHead.addr = NULL;
172  mh5emt_listHead.prev = NULL;
173  mh5emt_listHead.next = NULL;
174 
175  pMh5emt_listTail = &mh5emt_listHead;
176  }
177 }
178 
179 void mh5emt_close(void)
180 {
181 }
182 
183 #endif /* MHG_TRACK_MEM */
184 
190 void MHEG5freeMemFunc(void *what)
191 {
192 #ifdef MHG_TRACK_MEM
193  pMh5emtEntry_t pEmtHdr = (pMh5emtEntry_t)what;
194  /* -- Debug code for tracking engine memory usage */
195  if (what == 0)
196  {
197  TRACE(TERROR, ("**** WARNING: Attempt to free NULL MHEG5 memory block ****"))
198  }
199  else
200  {
201  unsigned char *pByte = (unsigned char *)what;
202 
203  /* -- Get actual start of memory block (debug header) */
204  pEmtHdr--;
205 
206  STB_OSMutexLock( mh5emt_mutex );
207 
208  if ((pEmtHdr->magic == MH5EMT_MAGIC) &&
209  (pEmtHdr->addr == pEmtHdr) &&
210  (pEmtHdr->prev != NULL))
211  {
212  /* -- Remove block from allocated list */
213  pEmtHdr->prev->next = pEmtHdr->next;
214  if (pEmtHdr->next)
215  {
216  pEmtHdr->next->prev = pEmtHdr->prev;
217  }
218  else
219  {
220  /* -- Block is at tail of list so re-assign tail */
221  pMh5emt_listTail = pEmtHdr->prev;
222  }
223 
224  if (cur_mem_total[0] < pEmtHdr->size)
225  {
226  TRACE(TERROR, ("now=%ld, size=%ld", cur_mem_total[0], pEmtHdr->size))
227  }
228  else
229  {
230  cur_mem_total[0] -= pEmtHdr->size;
231 
232  if (pEmtHdr->src > 0 && pEmtHdr->src < MAX_MEM_SRCS)
233  {
234  if (cur_mem_total[pEmtHdr->src] < pEmtHdr->size)
235  {
236  TRACE(TERROR, ("src=%d, now=%ld, size=%ld", pEmtHdr->src, cur_mem_total[pEmtHdr->src], pEmtHdr->size))
237  }
238  else
239  {
240  cur_mem_total[pEmtHdr->src] -= pEmtHdr->size;
241  }
242  }
243  else
244  {
245  TRACE(TERROR, ("free with invalid src id %d", pEmtHdr->src))
246  }
247  }
248  pByte += pEmtHdr->size;
249  if (pByte[0] != 'e' || pByte[1] != 'n' || pByte[2] != 'd' || pByte[3] != 'm')
250  {
251  TRACE(TERROR, ("**** ERROR: free MHEG5 memory block with data corruption ****"))
252  }
253  /* -- NULL debug header contents */
254  pEmtHdr->magic = 0;
255  pEmtHdr->callingFunc = NULL;
256  pEmtHdr->size = 0;
257  pEmtHdr->src = 0;
258  pEmtHdr->line = 0;
259  pEmtHdr->addr = NULL;
260  pEmtHdr->prev = NULL;
261  pEmtHdr->next = NULL;
262  }
263  else
264  {
265  TRACE(TERROR, ("**** ERROR: Attempt to free invalid MHEG5 memory block ****"))
266  assert(0);
267  }
268 
269  STB_OSMutexUnlock( mh5emt_mutex );
270 
271  /* -- Free the actual block */
272  what = pEmtHdr;
273  }
274 #endif
275  FreeFunc(what);
276 }
277 
288 #ifdef MHG_TRACK_MEM
289 void* MHEG5getMemFunc(void *callingFunction, int size, int line, int src)
290 #else
291 void * MHEG5getMemFunc(int size)
292 #endif
293 {
294  void *rc = 0;
295  #ifdef TRACING
296  int grp;
297  #endif
298  #ifdef MHG_TRACK_MEM
299  pMh5emtEntry_t pEmtHdr;
300  unsigned char *pByte;
301 
302  if (pMh5emt_listTail == NULL)
303  {
304  mh5emt_init();
305  }
306  #define theMemSize size + sizeof(mh5emtEntry_t) + 4
307  #else
308  #define theMemSize size
309  #endif
310 
311  if (size <= 0)
312  {
313  #ifdef MHG_TRACK_MEM
314  TRACE(TERROR, ("%s:%d requested size: %d\n", (const char *)callingFunction, line, size));
315  #else
316  TRACE(TERROR, ("requested size: %d", size));
317  #endif
318  return 0; /*** RETURN ***/
319  }
320 
321  #ifdef TRACING
322  grp = 0;
323  while ((mem_grp_max_sz[grp] < size) && (grp != TOTAL_GRPS - 1))
324  {
325  grp++;
326  }
327  #endif
328 
329  /* -- Allocate a bigger block to store debug header */
330  rc = MallocFunc(theMemSize);
331  if (!rc)
332  {
333  TRACER(mem_alloc_failed[grp]++; )
334  TRACE(TERROR, ("ERROR: Failed to alloc memory, sz=%d\n", size))
335  #ifdef MHEG5LOG
336  MHEG5LogPrintf(MHEG5ERROR, "*** Out of memory Error *** Calling Function: %p , requested size: %d\n", callingFunction, size);
337  #endif /* #ifdef MHEG5LOG */
338  #ifdef MHG_TRACK_MEM
339  TRACE(TMEMORY, ("*** Out of memory (total %ld) *** %s:%d size: %d\n", cur_mem_total[0], (const char *)callingFunction, line, size))
340  mh5emt_print(0xf);
341  #endif
342  }
343  else
344  {
345  TRACER(mem_alloc_counts[grp]++; )
346  #ifdef MHG_TRACK_MEM
347  assert( src > 0 && src < MAX_MEM_SRCS );
348  assert( size > 0 );
349  pEmtHdr = (pMh5emtEntry_t)rc;
350  /* -- Memory pointer passed to engine is after debug header */
351  rc = pEmtHdr + 1;
352  pByte = (unsigned char *)rc;
353  pByte += size;
354  pByte[0] = 'e'; pByte[1] = 'n'; pByte[2] = 'd'; pByte[3] = 'm';
355  /* -- Store debug header contents */
356  pEmtHdr->magic = MH5EMT_MAGIC;
357  pEmtHdr->callingFunc = (const char *)callingFunction;
358  pEmtHdr->line = line;
359  pEmtHdr->src = src;
360  pEmtHdr->size = (unsigned int)size;
361  pEmtHdr->addr = pEmtHdr;
362 
363  cur_mem_total[src] += (unsigned int)size;
364  if (cur_mem_total[src] > max_mem_total[src])
365  max_mem_total[src] = cur_mem_total[src];
366  cur_mem_total[0] += (unsigned int)size;
367  if (cur_mem_total[0] > max_mem_total[0])
368  max_mem_total[0] = cur_mem_total[0];
369 
370  /* -- Put block on tail of list */
371  STB_OSMutexLock( mh5emt_mutex );
372  pEmtHdr->prev = pMh5emt_listTail;
373  pEmtHdr->next = NULL;
374  pMh5emt_listTail->next = pEmtHdr;
375 
376  /* -- Move tail of list to new block */
377  pMh5emt_listTail = pEmtHdr;
378  STB_OSMutexUnlock( mh5emt_mutex );
379 
380  #ifdef _WINDOWS
381  saved_mallocs[saved_malloc_cnt].next = pEmtHdr;
382  saved_malloc_cnt++;
383  if (saved_malloc_cnt == MAX_SAVED_MALLOCS)
384  {
385  saved_malloc_cnt = 1;
386  }
387  memcpy(saved_mallocs + saved_malloc_cnt, pEmtHdr, sizeof(mh5emtEntry_t));
388  #endif
389  #endif
390  }
391  return rc;
392 }
393 
394 
395 
396 
397 
398 /*
399  static void BlkInit( S_STRINGS_BLOCK* pBlk, int dbits )
400  {
401  int cx;
402  pBlk->next = NULL;
403  for( cx = 0; cx != (CONTROL_SIZE-1); cx++ )
404  {
405  pBlk->control[cx] = 0x0;
406  }
407  pBlk->control[CONTROL_SIZE-1] = TOP_CONTROL(dbits);
408  }
409  */
410 
411 static BOOLEAN STR_Initialise(void)
412 {
413  unsigned char *heads;
414 
420  if (heads == NULL)
421  {
422  TRACE(TERROR, ("failed to allocate string memory"))
423  return FALSE;
424  }
425 
426  vtiny_strmem_head = (S_STRINGS_BLOCK *)heads;
427  memset( heads, 0, sizeof(S_STRINGS_BLOCK));
428  heads += STR_BLCK_SIZE(VTINY_BITS);
429 
430  migit_strmem_head = (S_STRINGS_BLOCK *)heads;
431  memset( heads, 0, sizeof(S_STRINGS_BLOCK));
432  heads += STR_BLCK_SIZE(MIGIT_BITS);
433 
434  small_strmem_head = (S_STRINGS_BLOCK *)heads;
435  memset( heads, 0, sizeof(S_STRINGS_BLOCK));
436  heads += STR_BLCK_SIZE(SMALL_BITS);
437 
438  medum_strmem_head = (S_STRINGS_BLOCK *)heads;
439  memset( heads, 0, sizeof(S_STRINGS_BLOCK));
440  heads += STR_BLCK_SIZE(MEDUM_BITS);
441 
442  large_strmem_head = (S_STRINGS_BLOCK *)heads;
443  memset( heads, 0, sizeof(S_STRINGS_BLOCK));
444 
445  return TRUE;
446 }
447 
448 static void FreeStrBlocks( S_STRINGS_BLOCK *pBlk, int dbits )
449 {
450  S_STRINGS_BLOCK *next = pBlk->next;
451 
452  #ifdef MHG_TRACK_MEM
453  unsigned char *data;
454  int cx, bx, bbits;
455  /* Check the string allocations are all gone in head block */
456  for (cx = 0; cx != CONTROL_SIZE; cx++)
457  {
458  if (pBlk->control[cx] != 0x00)
459  {
460  for (bbits = 1, bx = 0; bbits != 0x100; bbits <<= 1, bx++)
461  {
462  if ((pBlk->control[cx] & bbits))
463  {
464  data = (unsigned char *)pBlk + sizeof(S_STRINGS_BLOCK) + (((cx << 3) + bx) << dbits);
465  TRACE(TMEMORY, ("(%d,%d) line=%d Not freed \"%s\"", cx, bx, pBlk->line[(cx << 3) + bx], data))
466  }
467  }
468  }
469  }
470  #endif
471 
472  while (next != NULL)
473  {
474  pBlk = next;
475  #ifdef MHG_TRACK_MEM
476  /* Check the string allocations are all gone */
477  for (cx = 0; cx != CONTROL_SIZE; cx++)
478  {
479  if (pBlk->control[cx] != 0x00)
480  {
481  for (bbits = 1, bx = 0; bbits != 0x100; bbits <<= 1, bx++)
482  {
483  if ((pBlk->control[cx] & bbits))
484  {
485  data = (unsigned char *)pBlk + sizeof(S_STRINGS_BLOCK) + (((cx << 3) + bx) << dbits);
486  TRACE(TMEMORY, ("(%d,%d) line=%d Not freed \"%s\"", cx, bx, pBlk->line[(cx << 3) + bx], data))
487  }
488  }
489  }
490  }
491  #endif
492  next = pBlk->next;
493  MHEG5freeMem( pBlk );
494  }
495 }
496 
497 void STR_Shutdown(void)
498 {
499  TRACE(TMEMORY, ("freeing extra string memory"))
500  FreeStrBlocks( large_strmem_head, LARGE_BITS );
501  FreeStrBlocks( medum_strmem_head, MEDUM_BITS );
502  FreeStrBlocks( small_strmem_head, SMALL_BITS );
503  FreeStrBlocks( migit_strmem_head, MIGIT_BITS );
504  FreeStrBlocks( vtiny_strmem_head, VTINY_BITS );
505 
506  TRACE(TMEMORY, ("freeing header string memory"))
507  MHEG5freeMem( vtiny_strmem_head );
508 }
509 
510 static void ReleaseAnyFreeStrBlocks( S_STRINGS_BLOCK *pBlk, int dbits )
511 {
512  int cx;
513  S_STRINGS_BLOCK *prev;
514  /* always leave the first 'header' block for each */
515  while (pBlk->next != NULL)
516  {
517  prev = pBlk;
518  pBlk = pBlk->next;
519  /* Check the string allocations are all gone in head block */
520  cx = 0;
521  while (cx != CONTROL_SIZE && pBlk->control[cx] == 0x00)
522  cx++;
523  if (cx == CONTROL_SIZE)
524  {
525  prev->next = pBlk->next;
526  MHEG5freeMem( pBlk );
527  pBlk = prev;
528  }
529  }
530 }
531 
532 /* free 'string' block memory no longer required */
533 void STR_TidyUp(void)
534 {
535  assert( vtiny_strmem_head );
536  ReleaseAnyFreeStrBlocks( large_strmem_head, LARGE_BITS );
537  ReleaseAnyFreeStrBlocks( medum_strmem_head, MEDUM_BITS );
538  ReleaseAnyFreeStrBlocks( small_strmem_head, SMALL_BITS );
539  ReleaseAnyFreeStrBlocks( migit_strmem_head, MIGIT_BITS );
540  ReleaseAnyFreeStrBlocks( vtiny_strmem_head, VTINY_BITS );
541 }
542 
543 #ifndef MHG_TRACK_MEM
544 #define BlkStrAlloc(bk, bz, ln) BlkStrAlloc(bk, bz)
545 #endif
546 
547 static unsigned char* BlkStrAlloc( S_STRINGS_BLOCK *pBlk, int dbits, int line )
548 {
549  unsigned char *data = NULL;
550  int cx, bx, bbits;
551  do
552  {
553  for (cx = 0; cx != CONTROL_SIZE; cx++)
554  {
555  if (pBlk->control[cx] != 0xff)
556  {
557  for (bbits = 1, bx = 0; bbits != 0x100; bbits <<= 1, bx++)
558  {
559  if (!(pBlk->control[cx] & bbits))
560  {
561  pBlk->control[cx] |= bbits;
562  data = (unsigned char *)pBlk + sizeof(S_STRINGS_BLOCK) + (((cx << 3) + bx) << dbits);
563  #ifdef MHG_TRACK_MEM
564  pBlk->line[(cx << 3) + bx] = (U16BIT)line;
565  #endif
566  break;
567  }
568  }
569  break;
570  }
571  }
572  if (cx == CONTROL_SIZE)
573  {
574  if (pBlk->next == NULL)
575  {
576  pBlk->next = (S_STRINGS_BLOCK *)MHEG5getMem( STR_BLCK_SIZE(dbits));
577  if (pBlk->next)
578  {
579  memset( pBlk->next, 0, sizeof(S_STRINGS_BLOCK));
580  }
581  else
582  {
583  data = NULL;
584  }
585  }
586  pBlk = pBlk->next;
587  }
588  }
589  while ((cx == CONTROL_SIZE) && (pBlk != NULL));
590  return data;
591 }
592 
593 #ifdef MHG_TRACK_MEM
594 unsigned char* STR_DataAllocFunc( unsigned int len, int line )
595 #else
596 unsigned char * STR_DataAlloc( unsigned int len )
597 #endif
598 {
599  unsigned char *data;
600  if (len < (1 << SMALL_BITS))
601  {
602  if (len < (1 << MIGIT_BITS))
603  {
604  if (len < (1 << VTINY_BITS))
605  {
606  data = BlkStrAlloc( vtiny_strmem_head, VTINY_BITS, line );
607  }
608  else
609  {
610  data = BlkStrAlloc( migit_strmem_head, MIGIT_BITS, line );
611  }
612  }
613  else
614  {
615  data = BlkStrAlloc( small_strmem_head, SMALL_BITS, line );
616  }
617  }
618  else
619  {
620  if (len < (1 << MEDUM_BITS))
621  {
622  data = BlkStrAlloc( medum_strmem_head, MEDUM_BITS, line );
623  }
624  else
625  {
626  if (len < (1 << LARGE_BITS))
627  {
628  data = BlkStrAlloc( large_strmem_head, LARGE_BITS, line );
629  }
630  else
631  {
632  data = (unsigned char *)MHEG5getMem( len + 1 );
633  }
634  }
635  }
636  if (data != NULL)
637  {
638  data[len] = 0; /*null terminate string*/
639  }
640  return data;
641 }
642 
643 #ifndef BlkStrFree
644 static void BlkStrFree( S_STRINGS_BLOCK *pBlk, int bz, unsigned char *data )
645 {
646  do
647  {
648  unsigned char *blk_data = (unsigned char *)pBlk + sizeof(S_STRINGS_BLOCK);
649  if (data >= blk_data &&
650  data < blk_data + STR_DATA_SIZE(bz))
651  {
652  int tmp;
653  tmp = (data - blk_data) >> bz;
654  pBlk->control[tmp >> 3] &= (U8BIT) ~(1 << (tmp & 7));
655  break;
656  }
657  pBlk = pBlk->next;
658  }
659  while (pBlk != NULL);
660  if (pBlk == NULL)
661  {
662  TRACE(TERROR, ("Not freed %x", data))
663  }
664 }
665 
666 #endif /*BlkStrFree*/
667 
668 void STR_DataFree( unsigned char *data, unsigned int len )
669 {
670  if (len < (1 << SMALL_BITS))
671  {
672  if (len < (1 << MIGIT_BITS))
673  {
674  if (len < (1 << VTINY_BITS))
675  {
676  BlkStrFree( vtiny_strmem_head, VTINY_BITS, data );
677  }
678  else
679  {
680  BlkStrFree( migit_strmem_head, MIGIT_BITS, data );
681  }
682  }
683  else
684  {
685  BlkStrFree( small_strmem_head, SMALL_BITS, data );
686  }
687  }
688  else
689  {
690  if (len < (1 << MEDUM_BITS))
691  {
692  BlkStrFree( medum_strmem_head, MEDUM_BITS, data );
693  }
694  else
695  {
696  if (len < (1 << LARGE_BITS))
697  {
698  BlkStrFree( large_strmem_head, LARGE_BITS, data );
699  }
700  else
701  {
702  MHEG5freeMem( data );
703  }
704  }
705  }
706 }
707 
708 void MHG_DebugMemStats(int line)
709 {
710 #ifdef TRACING
711  int nx, last = 0;
712  char tmp[64];
713  char str[512];
714  str[0] = 0;
715  for (nx = 0; nx != TOTAL_GRPS; nx++)
716  {
717  sprintf(tmp, "(%03x-%03x)=%03d ", last, mem_grp_max_sz[nx] - 1, mem_alloc_counts[nx]);
718  last = mem_grp_max_sz[nx];
719  strcat(str, tmp);
720  if ((nx % 6) == 5)
721  {
722  TRACE(TMEMORY, ("%s", str))
723  str[0] = 0;
724  }
725  mem_alloc_counts[nx] = 0;
726  }
727  #ifdef MHG_TRACK_MEM
728  for (nx = 0; nx != MAX_MEM_SRCS; nx++)
729  {
730  TRACE(TMEMORY, ("Src=%s \tNow= %03ld\tMax= %03ld", mem_strings[nx], cur_mem_total[nx], max_mem_total[nx]))
731  }
732  #endif
733  if (mem_prints)
734  {
735  for (nx = 0; nx != TOTAL_GRPS; nx++)
736  {
737  if (mem_alloc_failed[nx])
738  {
739  TRACE(TMEMORY, ("Had failures: %d, %d", nx, mem_alloc_failed[nx]));
740  mem_alloc_failed[nx] = 0;
741  }
742  }
743  }
744  else
745  {
746  for (nx = 0; nx != TOTAL_GRPS; nx++)
747  {
748  mem_alloc_failed[nx] = 0;
749  }
750  mem_prints++;
751  }
752 #endif /*TRACING*/
753 }
754 
755 #ifdef MHG_TRACK_MEM
756 /* -- Print list of all engine memory blocks currently allocated */
757 void mh5emt_print(unsigned int which)
758 {
759  const char dig[16] = "0123456789ABCDEF";
760  unsigned int ndx;
761  U8BIT *pch;
762  pMh5emtEntry_t pEmtHdr;
763  BOOLEAN src_on[MAX_MEM_SRCS];
764 
765  for (ndx = 0; ndx != MAX_MEM_SRCS; ndx++)
766  {
767  src_on[ndx] = (which & (1 << ndx)) ? TRUE : FALSE;
768  }
769 
771 
772  TPRINT(TMEMORY, ("\n#### ALLOCATED ENGINE MEMORY OBJECTS ####\n"))
773 
774  STB_OSMutexLock( mh5emt_mutex );
775  pEmtHdr = mh5emt_listHead.next;
776 
777  while (pEmtHdr != NULL)
778  {
779  if (src_on[pEmtHdr->src])
780  {
781  TPRINT(TMEMORY, ("\"\n%s:%d Size: %u, Addr: %p \"",
782  pEmtHdr->callingFunc, pEmtHdr->line, pEmtHdr->size, pEmtHdr->addr))
783  pch = (U8BIT *)(pEmtHdr->addr + 1);
784  for (ndx = 0; (ndx < pEmtHdr->size); pch++, ndx++)
785  {
786  if ((*pch >= 0x20) && (*pch < 0x7e) && (*pch != '='))
787  {
788  TPRINT(TMEMORY, ("%c", *pch))
789  }
790  else
791  {
792  TPRINT(TMEMORY, ("=%c%c", dig[*pch >> 4], dig[*pch & 0xf]))
793  if (ndx > 8)
794  ndx = pEmtHdr->size;
795  }
796  }
797  }
798  pEmtHdr = pEmtHdr->next;
799  }
800  STB_OSMutexUnlock( mh5emt_mutex );
801 }
802 
803 #endif
804 
805 
806 
808 {
809  BOOLEAN result;
810 
811  #ifdef MHG_TRACK_MEM
812  /* -- Debug code - initialise engine memory tracking */
813  if (pMh5emt_listTail == NULL)
814  {
815  mh5emt_init();
816  }
817  #endif
818 
819  if (vtiny_strmem_head != NULL)
820  {
821  result = TRUE;
822  }
823  else
824  {
825  result = STR_Initialise();
826  }
827  return result;
828 }
829 
831 {
832  if (vtiny_strmem_head != NULL)
833  {
834  STR_Shutdown();
835  vtiny_strmem_head = NULL;
836  }
837 #ifdef MHG_TRACK_MEM
838  /* -- Debug code - print engine memory tracking state */
839  TRACE(TMEMORY, (""))
840  mh5emt_print(0xf);
841 #endif
842 }
843 
844 #ifdef MHG_TRACK_MEM
845 S_STRING MH5GlueStringCopyFunc(S_STRING source, int line )
846 #else
848 #endif
849 {
850  S_STRING rc;
851 
852  if (source.zlen != 0)
853  {
854  #ifdef MHG_TRACK_MEM
855  rc.zptr = STR_DataAllocFunc( source.zlen, line + 7000 );
856  #else
857  rc.zptr = STR_DataAlloc( source.zlen );
858  #endif
859  if (rc.zptr)
860  {
861  assert(rc.zptr != source.zptr);
862  memcpy(rc.zptr, source.zptr, source.zlen);
863  rc.zlen = source.zlen;
864  }
865  else
866  {
867  rc.zlen = 0;
868  }
869  }
870  else
871  {
872  rc.zptr = NULL;
873  rc.zlen = 0;
874  }
875  return rc;
876 }
877 
878 #ifdef MHG_TRACK_MEM
879 S_STRING MH5GlueStringConcatFunc(S_STRING src1, S_STRING src2, int line )
880 #else
882 #endif
883 {
884  S_STRING rc;
885 
886  rc.zlen = src1.zlen + src2.zlen;
887  if (rc.zlen == 0)
888  {
889  rc.zptr = NULL;
890  }
891  else
892  {
893  #ifdef MHG_TRACK_MEM
894  rc.zptr = STR_DataAllocFunc( src1.zlen + src2.zlen, line + 8000 );
895  #else
896  rc.zptr = STR_DataAlloc( src1.zlen + src2.zlen );
897  #endif
898  if (rc.zptr)
899  {
900  if (src1.zptr != NULL && src1.zlen != 0)
901  {
902  memcpy(rc.zptr, src1.zptr, src1.zlen);
903  }
904  else
905  {
906  src1.zlen = 0;
907  }
908  if (src2.zptr != NULL && src2.zlen != 0)
909  {
910  memcpy(rc.zptr + src1.zlen, src2.zptr, src2.zlen);
911  }
912  }
913  else
914  {
915  rc.zlen = 0;
916  }
917  }
918  return rc;
919 }
920 
921 #ifdef MHG_TRACK_MEM
922 S_STRING MH5GlueStringAllocFunc(U32BIT size, int line )
923 #else
925 #endif
926 {
927  S_STRING rc;
928 
929  if (size != 0)
930  {
931  #ifdef MHG_TRACK_MEM
932  rc.zptr = STR_DataAllocFunc( size, line + 6000 );
933  #else
934  rc.zptr = STR_DataAlloc( size );
935  #endif
936  if (rc.zptr)
937  {
938  rc.zlen = size;
939  }
940  else
941  {
942  rc.zlen = 0;
943  }
944  }
945  else
946  {
947  rc.zptr = NULL;
948  rc.zlen = 0;
949  }
950  return rc;
951 }
952 
953 #ifdef MHG_TRACK_MEM
954 S_STRING MH5GlueStringCreateFunc(U32BIT size, U8BIT *data, int line )
955 #else
957 #endif
958 {
959  S_STRING rc;
960 
961  if (size != 0)
962  {
963  #ifdef MHG_TRACK_MEM
964  rc.zptr = STR_DataAllocFunc( size, line + 6000 );
965  #else
966  rc.zptr = STR_DataAlloc( size );
967  #endif
968  if (rc.zptr)
969  {
970  rc.zlen = size;
971  memcpy(rc.zptr, data, size);
972  }
973  else
974  {
975  rc.zlen = 0;
976  }
977  }
978  else
979  {
980  rc.zptr = NULL;
981  rc.zlen = 0;
982  }
983  return rc;
984 }
985 
987 {
988  assert(pStr != NULL);
989  if (pStr->zptr != NULL)
990  {
991  STR_DataFree( pStr->zptr, pStr->zlen );
992  pStr->zptr = NULL;
993  pStr->zlen = 0;
994  }
995 }
996 
997 /*EOF*/
#define TPRINT(t, x)
Definition: glue_debug.h:119
S_STRINGS_BLOCK * large_strmem_head
Definition: glue_memory.c:101
S_STRING MH5GlueStringCopy(S_STRING source)
Definition: glue_memory.c:847
S_STRING MH5GlueStringCreate(U32BIT size, U8BIT *data)
Definition: glue_memory.c:956
const char * data
Definition: mh5gate.c:56
#define MEDUM_BITS
Definition: glue_memory.c:46
S_STRINGS_BLOCK * vtiny_strmem_head
Definition: glue_memory.c:97
S_STRINGS_BLOCK * migit_strmem_head
Definition: glue_memory.c:98
Debug tracing.
#define MHEG5getMem
Definition: glue_memory.h:93
struct s_strings_block S_STRINGS_BLOCK
#define theMemSize
void STR_Shutdown(void)
Definition: glue_memory.c:497
void * MHEG5getMemFunc(int size)
Allocate a block of memory from the free pool. This function should be called using the macro MHEG5ge...
Definition: glue_memory.c:291
U8BIT * zptr
Definition: dtvstring.h:31
#define MIGIT_BITS
Definition: glue_memory.c:44
S_STRING MH5GlueStringAlloc(U32BIT size)
Definition: glue_memory.c:924
S_STRINGS_BLOCK * medum_strmem_head
Definition: glue_memory.c:100
U8BIT control[CONTROL_SIZE]
Definition: glue_memory.c:71
#define LARGE_BITS
Definition: glue_memory.c:47
void MH5GlueStringFree(S_STRING *pStr)
Definition: glue_memory.c:986
uint8_t U8BIT
Definition: techtype.h:82
#define SMALL_BITS
Definition: glue_memory.c:45
#define VTINY_BITS
Definition: glue_memory.c:43
#define CONTROL_SIZE
Definition: glue_memory.c:50
Memory functions.
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. &#39;leave&#39;, &#39;signal&#39; or &#39;release&#39;)
#define MHEG5freeMem
Definition: glue_memory.h:94
unsigned char * STR_DataAlloc(unsigned int len)
Definition: glue_memory.c:596
void MH5GlueMemoryTerminate(void)
Definition: glue_memory.c:830
#define BlkStrFree(head, bz, data)
Definition: glue_memory.c:52
#define MallocFunc
Definition: glue_memory.c:38
void * STB_OSCreateMutex(void)
Create a mutex.
int len
Definition: mh5gate.c:57
#define FreeFunc
Definition: glue_memory.c:39
uint16_t U16BIT
Definition: techtype.h:84
#define TRACER(x)
Definition: glue_debug.h:123
BOOLEAN MH5GlueMemoryInitialise(void)
Definition: glue_memory.c:807
void MHEG5freeMemFunc(void *what)
Free some memory allocated by a call to MHEG5getMemFunc.
Definition: glue_memory.c:190
void STR_TidyUp(void)
Definition: glue_memory.c:533
#define FALSE
Definition: techtype.h:68
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. &#39;enter&#39;, &#39;wait&#39; or &#39;get&#39;).
#define STR_BLCK_SIZE(bz)
Definition: glue_memory.c:49
U8BIT BOOLEAN
Definition: techtype.h:99
U32BIT zlen
Definition: dtvstring.h:30
#define TRUE
Definition: techtype.h:69
S_STRING MH5GlueStringConcat(S_STRING src1, S_STRING src2)
Definition: glue_memory.c:881
void MHG_DebugMemStats(int line)
Definition: glue_memory.c:708
struct s_strings_block * next
Definition: glue_memory.c:70
#define BlkStrAlloc(bk, bz, ln)
Definition: glue_memory.c:544
#define STR_DATA_SIZE(bz)
Definition: glue_memory.c:48
void STR_DataFree(unsigned char *data, unsigned int len)
Definition: glue_memory.c:668
S_STRINGS_BLOCK * small_strmem_head
Definition: glue_memory.c:99
uint32_t U32BIT
Definition: techtype.h:86
#define MAX_BLK_STRS
Definition: glue_memory.c:42
#define TRACE(t, x)
Definition: glue_debug.h:118
Header file - Function prototypes for operating system.