root/core/memmgmt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. chdk_heap_init
  2. chdk_heap_create
  3. chdk_malloc
  4. chdk_free
  5. chdk_meminfo
  6. chdk_testing
  7. exmem_testing
  8. exmem_malloc_init
  9. GetExMemInfo
  10. aram_testing
  11. aram_malloc_init
  12. GetARamInfo
  13. combine_meminfo
  14. GetCombinedMemInfo
  15. malloc
  16. free

   1 #include "platform.h"
   2 #include "stdlib.h"
   3 #include "core.h"
   4 #include "conf.h"
   5 #include "gui_draw.h"
   6 
   7 //----------------------------------------------------------------------------
   8 // Memory wrappers
   9 
  10 extern void *suba_init(void *heap, unsigned size, unsigned mincell, char *name);
  11 extern void *suba_alloc(void *heap, unsigned size, unsigned zero);
  12 extern int suba_free(void *heap, void *p);
  13 
  14 //----------------------------------------------------------------------------
  15 // Manage block of memory controlled by suba
  16 typedef struct
  17 {
  18     void    *heap;
  19     void    *start;
  20     void    *end;
  21     int     size;
  22 } chdk_heap;
  23 
  24 static void chdk_heap_init(chdk_heap *h)
  25 {
  26     h->heap = 0;
  27     h->start = 0;
  28     h->end = 0;
  29     h->size = 0;
  30 }
  31 
  32 static void chdk_heap_create(chdk_heap *h, void *mem, int size, int chdk_in_heap, int heap_testing, char *name)
  33 {
  34     if (h)
  35     {
  36         if (chdk_in_heap)
  37         {
  38                     // If loading CHDK into heap then move heap start past the end of CHDK
  39                     // and reduce available space by CHDK size (MEMISOSIZE)
  40                     // round MEMISOSIZE up to next 4 byte boundary if needed (just in case)
  41                     h->start = mem + ((camera_info.memisosize+3)&0xFFFFFFFC);
  42                     h->size = size - ((camera_info.memisosize+3)&0xFFFFFFFC);
  43         }
  44         else
  45         {
  46                     // Set start & size based on requested values
  47                     h->start = mem;
  48                     h->size = size;
  49         }
  50 
  51                 h->end = h->start + h->size;
  52 
  53         if (heap_testing)
  54         {
  55                     // For testing exmem allocated memory for corruption from normal camera operations
  56                     // set the above #define. This will allocate the memory; but won't use it (exmem_heap is set to 0)
  57                     // Instead all the memory is filled with the guard value below.
  58                     // In gui_draw_debug_vals_osd (gui.c) the memory is tested for the guard value and if any
  59                     // corruption has occurred then info about the memory locations that were altered is displayed
  60             // Note: do not use heap_testing and chdk_in_heap at the same time
  61                     unsigned long *p;
  62                     for (p=(unsigned long*)h->start; p<(unsigned long*)h->end; p++) *p = 0xDEADBEEF;
  63         }
  64         else
  65         {
  66                 // Normal operation, use the suba allocation system to manage the memory block
  67                 h->heap = suba_init(h->start,h->size,8,name);
  68         }
  69     }
  70 }
  71 
  72 static void* chdk_malloc(chdk_heap *h, unsigned size)
  73 {
  74     if (h && h->heap)
  75             return suba_alloc(h->heap,size,0);
  76     return 0;
  77 }
  78 
  79 static int chdk_free(chdk_heap *h, void *p)
  80 {
  81     if (h && h->heap && (p >= h->start) && (p < h->end))
  82     {
  83         suba_free(h->heap,p);
  84         return 1;
  85     }
  86     return 0;
  87 }
  88 
  89 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
  90 static int chdk_meminfo(chdk_heap *h, cam_meminfo *camera_meminfo)
  91 {
  92     if (h && h->heap)
  93     {
  94             extern void suba_getmeminfo(void*, int*, int*, int*, int*, int*, int*);
  95 
  96         camera_meminfo->start_address        = (int)h->start;
  97         camera_meminfo->end_address          = (int)h->end;
  98         camera_meminfo->total_size           = h->size;
  99         suba_getmeminfo(h->heap,
 100                         &camera_meminfo->allocated_size, &camera_meminfo->allocated_peak, &camera_meminfo->allocated_count,
 101                         &camera_meminfo->free_size, &camera_meminfo->free_block_max_size, &camera_meminfo->free_block_count);
 102 
 103         return 1;   // return success
 104     }
 105     else
 106     {
 107         memset(camera_meminfo, 0, sizeof(cam_meminfo));
 108         return 0;
 109     }
 110 }
 111 
 112 #if defined(OPT_EXMEM_TESTING) || defined(OPT_ARAM_TESTING)
 113 static void chdk_testing(chdk_heap *h)
 114 {
 115     // If defined the heap memory is allocated; but not used for CHDK.
 116     // It is filled with a guard value which is checked here
 117     // Any corruption is reported, otherwise 'OK' is displayed on screen (along with the heap memory start address).
 118 
 119     // check heap allocated memory for corruption
 120     unsigned long* p = (unsigned long*)h->start;
 121     unsigned long *f = 0, *l = 0;
 122     long cnt = 0;
 123     while (p < (unsigned long*)h->end)
 124     {
 125         if (p[0] != 0xDEADBEEF)
 126         {
 127             l = p;
 128             if (f == 0) f = p;
 129             cnt++;
 130         }
 131         p++;
 132     }
 133     char osd_buf[40];
 134     if (cnt != 0)
 135     {
 136         sprintf(osd_buf, "s:%8x e:%8x", h->start, h->end);
 137         draw_string(2*FONT_WIDTH, 12*FONT_HEIGHT, osd_buf, user_color(conf.osd_color));
 138         sprintf(osd_buf, "f:%8x l:%8x c:%d", f, l, cnt);
 139     }
 140     else
 141     {
 142         sprintf(osd_buf, "OK 0x%x", h->start);
 143     }
 144     draw_string(2*FONT_WIDTH, 13*FONT_HEIGHT, osd_buf, user_color(conf.osd_color));
 145     // end of check     
 146 }
 147 #endif
 148 
 149 //----------------------------------------------------------------------------
 150 #ifdef OPT_EXMEM_MALLOC
 151 // I set this up to 16 mb and it still booted...
 152 #ifndef EXMEM_HEAP_SKIP
 153 #define EXMEM_HEAP_SKIP 0
 154 #endif
 155 #ifndef EXMEM_BUFFER_SIZE
 156 #define EXMEM_BUFFER_SIZE (1024*1024*2) // default size if not specified by camera
 157 #endif
 158 #define EXMEM_HEAP_SIZE (EXMEM_BUFFER_SIZE+EXMEM_HEAP_SKIP)     // desired space + amount to skip for the movie buffers (if needed)
 159 #endif
 160 
 161 static chdk_heap exmem_heap;
 162 
 163 #if defined(OPT_EXMEM_TESTING)
 164 void exmem_testing()
 165 {
 166     chdk_testing(&exmem_heap);
 167 }
 168 #endif
 169 
 170 void exmem_malloc_init()
 171 {
 172     chdk_heap_init(&exmem_heap);
 173 #ifdef OPT_EXMEM_MALLOC
 174 #ifndef OPT_CHDK_IN_EXMEM
 175 #define OPT_CHDK_IN_EXMEM 0
 176 #endif
 177 #ifndef OPT_EXMEM_TESTING
 178 #define OPT_EXMEM_TESTING 0
 179 #endif
 180         // pool zero is EXMEM_RAMDISK on d10
 181     extern void *exmem_alloc(int pool_id,int size,int unk,int unk2); 
 182         void *mem = exmem_alloc(0,EXMEM_HEAP_SIZE,0,0);
 183         if (mem)
 184     {
 185         chdk_heap_create(&exmem_heap, mem, EXMEM_BUFFER_SIZE, OPT_CHDK_IN_EXMEM, OPT_EXMEM_TESTING, "exmem_suba");
 186         }
 187 #endif
 188 }
 189 
 190 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
 191 int GetExMemInfo(cam_meminfo *camera_meminfo)
 192 {
 193     return chdk_meminfo(&exmem_heap, camera_meminfo);
 194 }
 195 
 196 //----------------------------------------------------------------------------
 197 
 198 static chdk_heap aram_heap;
 199 
 200 #if defined(OPT_ARAM_TESTING)
 201 void aram_testing()
 202 {
 203     chdk_testing(&aram_heap);
 204 }
 205 #endif
 206 
 207 void aram_malloc_init()
 208 {
 209     chdk_heap_init(&aram_heap);
 210 #ifdef OPT_ARAM_MALLOC
 211 #ifndef OPT_CHDK_IN_ARAM
 212 #define OPT_CHDK_IN_ARAM 0
 213 #endif
 214 #ifndef OPT_ARAM_TESTING
 215 #define OPT_ARAM_TESTING 0
 216 #endif
 217     chdk_heap_create(&aram_heap, (void*)ARAM_HEAP_START, ARAM_HEAP_SIZE, OPT_CHDK_IN_ARAM, OPT_ARAM_TESTING, "aram_suba");
 218 #endif
 219 }
 220 
 221 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
 222 int GetARamInfo(cam_meminfo *camera_meminfo)
 223 {
 224     return chdk_meminfo(&aram_heap, camera_meminfo);
 225 }
 226 
 227 //----------------------------------------------------------------------------
 228 static void combine_meminfo(cam_meminfo *combined,cam_meminfo *m)
 229 {
 230     combined->total_size += m->total_size;
 231     if(m->free_block_max_size > combined->free_block_max_size)
 232     {
 233         combined->free_block_max_size = m->free_block_max_size; 
 234     }
 235     combined->free_size += m->free_size;
 236     combined->free_block_count += m->free_block_count;
 237     combined->allocated_size += m->allocated_size;
 238     combined->allocated_peak += m->allocated_peak;
 239     combined->allocated_count += m->allocated_count;
 240 }
 241 
 242 // Build a combined meminfo from available heaps
 243 // free block max size is the single largest free block
 244 // other fields are total, or zero where it doesn't make sense to combine
 245 void GetCombinedMemInfo(cam_meminfo *camera_meminfo)
 246 {
 247     // get system meminfo, should always be available
 248     GetMemInfo(camera_meminfo);
 249 // some fields are set to -1 for vxworks cams
 250 #if !defined(CAM_DRYOS)
 251     camera_meminfo->allocated_peak = 0;
 252     camera_meminfo->total_size = 0;
 253 #ifdef CAM_NO_MEMPARTINFO
 254     // a more useful base value than 0
 255     camera_meminfo->free_size = camera_meminfo->free_block_max_size;
 256     camera_meminfo->free_block_count = 0;
 257     camera_meminfo->allocated_size = 0;
 258     camera_meminfo->allocated_count = 0;
 259 #endif
 260 #endif
 261 
 262     // these don't make sense to combine
 263     camera_meminfo->start_address = camera_meminfo->end_address = 0;
 264 
 265     cam_meminfo m;
 266     if(GetARamInfo(&m)) {
 267         combine_meminfo(camera_meminfo,&m);
 268     }
 269     if(GetExMemInfo(&m)) {
 270         combine_meminfo(camera_meminfo,&m);
 271     }
 272 }
 273 
 274 void *malloc(long size)
 275 {
 276     extern void *canon_malloc(long size);
 277 
 278     void *p = chdk_malloc(&aram_heap,size);
 279 
 280     if (p == 0)
 281         p = chdk_malloc(&exmem_heap,size);
 282 
 283     if (p == 0)
 284         p = canon_malloc(size);
 285 
 286     return p;
 287 }
 288 
 289 void free(void *p)
 290 {
 291     extern void canon_free(void *p);
 292 
 293     if (!chdk_free(&aram_heap,p))
 294             if (!chdk_free(&exmem_heap,p))
 295             canon_free(p);
 296 }
 297 

/* [<][>][^][v][top][bottom][index][help] */