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. canon_malloc_init
  14. combine_meminfo
  15. GetCombinedMemInfo
  16. malloc
  17. 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 // semaphore for canon heap on vxworks
 229 #if !defined(CAM_DRYOS)
 230 int canon_heap_sem;
 231 
 232 void canon_malloc_init(void) {
 233     canon_heap_sem=CreateBinarySemaphore("canonheap", 1);
 234 }
 235 #endif
 236 
 237 //----------------------------------------------------------------------------
 238 static void combine_meminfo(cam_meminfo *combined,cam_meminfo *m)
 239 {
 240     combined->total_size += m->total_size;
 241     if(m->free_block_max_size > combined->free_block_max_size)
 242     {
 243         combined->free_block_max_size = m->free_block_max_size; 
 244     }
 245     combined->free_size += m->free_size;
 246     combined->free_block_count += m->free_block_count;
 247     combined->allocated_size += m->allocated_size;
 248     combined->allocated_peak += m->allocated_peak;
 249     combined->allocated_count += m->allocated_count;
 250 }
 251 
 252 // Build a combined meminfo from available heaps
 253 // free block max size is the single largest free block
 254 // other fields are total, or zero where it doesn't make sense to combine
 255 void GetCombinedMemInfo(cam_meminfo *camera_meminfo)
 256 {
 257     // get system meminfo, should always be available
 258     GetMemInfo(camera_meminfo);
 259 // some fields are set to -1 for vxworks cams
 260 #if !defined(CAM_DRYOS)
 261     camera_meminfo->allocated_peak = 0;
 262     camera_meminfo->total_size = 0;
 263 #ifdef CAM_NO_MEMPARTINFO
 264     // a more useful base value than 0
 265     camera_meminfo->free_size = camera_meminfo->free_block_max_size;
 266     camera_meminfo->free_block_count = 0;
 267     camera_meminfo->allocated_size = 0;
 268     camera_meminfo->allocated_count = 0;
 269 #endif
 270 #endif
 271 
 272     // these don't make sense to combine
 273     camera_meminfo->start_address = camera_meminfo->end_address = 0;
 274 
 275     cam_meminfo m;
 276     if(GetARamInfo(&m)) {
 277         combine_meminfo(camera_meminfo,&m);
 278     }
 279     if(GetExMemInfo(&m)) {
 280         combine_meminfo(camera_meminfo,&m);
 281     }
 282 }
 283 
 284 void *malloc(long size)
 285 {
 286     extern void *canon_malloc(long size);
 287 
 288     void *p = chdk_malloc(&aram_heap,size);
 289 
 290     if (p == 0)
 291         p = chdk_malloc(&exmem_heap,size);
 292 
 293     if (p == 0)
 294         p = canon_malloc(size);
 295 
 296     return p;
 297 }
 298 
 299 void free(void *p)
 300 {
 301     extern void canon_free(void *p);
 302 
 303     if (!chdk_free(&aram_heap,p))
 304             if (!chdk_free(&exmem_heap,p))
 305             canon_free(p);
 306 }
 307 

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