blob: 504db4b1b9ca3a6d1de564d4458fce15f5a12393 [file] [log] [blame]
xbeefe34222014-03-16 00:14:26 -07001#include <unistd.h>
Damien429d7192013-10-04 19:53:11 +01002#include <stdio.h>
3#include <stdlib.h>
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +02004#include <string.h>
Damien429d7192013-10-04 19:53:11 +01005
6#include "misc.h"
Paul Sokolovskyef181022014-01-03 03:06:25 +02007#include "mpconfig.h"
Damien429d7192013-10-04 19:53:11 +01008
Damien George2d15c122014-01-29 20:33:20 +00009#if 0 // print debugging info
Paul Sokolovsky44739e22014-02-16 18:11:42 +020010#define DEBUG_printf DEBUG_printf
Damien George2d15c122014-01-29 20:33:20 +000011#else // don't print debugging info
Damien George1dc76af2014-02-26 16:57:08 +000012#define DEBUG_printf(...) (void)0
Damien George2d15c122014-01-29 20:33:20 +000013#endif
14
Paul Sokolovskyef181022014-01-03 03:06:25 +020015#if MICROPY_MEM_STATS
Paul Sokolovsky520e2f52014-02-12 18:31:30 +020016STATIC int total_bytes_allocated = 0;
17STATIC int current_bytes_allocated = 0;
18STATIC int peak_bytes_allocated = 0;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020019
20#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
Paul Sokolovskyef181022014-01-03 03:06:25 +020021#endif
Damien429d7192013-10-04 19:53:11 +010022
Paul Sokolovskyb62c30b2014-02-10 22:37:09 +020023#if MICROPY_ENABLE_GC
24#include "gc.h"
25
26// We redirect standard alloc functions to GC heap - just for the rest of
27// this module. In the rest of micropython source, system malloc can be
28// freely accessed - for interfacing with system and 3rd-party libs for
29// example. On the other hand, some (e.g. bare-metal) ports may use GC
30// heap as system heap, so, to avoid warnings, we do undef's first.
31#undef malloc
32#undef free
33#undef realloc
34#define malloc gc_alloc
35#define free gc_free
36#define realloc gc_realloc
37#endif // MICROPY_ENABLE_GC
38
Damien429d7192013-10-04 19:53:11 +010039void *m_malloc(int num_bytes) {
40 if (num_bytes == 0) {
41 return NULL;
42 }
43 void *ptr = malloc(num_bytes);
44 if (ptr == NULL) {
45 printf("could not allocate memory, allocating %d bytes\n", num_bytes);
46 return NULL;
47 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020048#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +010049 total_bytes_allocated += num_bytes;
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020050 current_bytes_allocated += num_bytes;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020051 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +020052#endif
Damien George2d15c122014-01-29 20:33:20 +000053 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Damien429d7192013-10-04 19:53:11 +010054 return ptr;
55}
56
57void *m_malloc0(int num_bytes) {
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +020058 void *ptr = m_malloc(num_bytes);
59 if (ptr != NULL) {
60 memset(ptr, 0, num_bytes);
Damien429d7192013-10-04 19:53:11 +010061 }
Damien429d7192013-10-04 19:53:11 +010062 return ptr;
63}
64
Damien732407f2013-12-29 19:33:23 +000065void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
66 if (new_num_bytes == 0) {
Damien429d7192013-10-04 19:53:11 +010067 free(ptr);
68 return NULL;
69 }
Paul Sokolovskycdd2c622014-01-30 03:58:17 +020070 void *new_ptr = realloc(ptr, new_num_bytes);
71 if (new_ptr == NULL) {
Damien732407f2013-12-29 19:33:23 +000072 printf("could not allocate memory, reallocating %d bytes\n", new_num_bytes);
Damien429d7192013-10-04 19:53:11 +010073 return NULL;
74 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020075#if MICROPY_MEM_STATS
Paul Sokolovsky43f1c802014-01-01 23:04:25 +020076 // At first thought, "Total bytes allocated" should only grow,
77 // after all, it's *total*. But consider for example 2K block
78 // shrunk to 1K and then grown to 2K again. It's still 2K
79 // allocated total. If we process only positive increments,
80 // we'll count 3K.
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020081 int diff = new_num_bytes - old_num_bytes;
82 total_bytes_allocated += diff;
83 current_bytes_allocated += diff;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020084 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +020085#endif
Paul Sokolovskycdd2c622014-01-30 03:58:17 +020086 DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
87 return new_ptr;
Damien429d7192013-10-04 19:53:11 +010088}
89
Damien732407f2013-12-29 19:33:23 +000090void m_free(void *ptr, int num_bytes) {
91 if (ptr != NULL) {
92 free(ptr);
93 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020094#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020095 current_bytes_allocated -= num_bytes;
Paul Sokolovskyef181022014-01-03 03:06:25 +020096#endif
Damien George2d15c122014-01-29 20:33:20 +000097 DEBUG_printf("free %p, %d\n", ptr, num_bytes);
Damien732407f2013-12-29 19:33:23 +000098}
99
Damien8b3a7c22013-10-23 20:20:17 +0100100int m_get_total_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200101#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +0100102 return total_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200103#else
104 return -1;
105#endif
Damien429d7192013-10-04 19:53:11 +0100106}
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200107
108int m_get_current_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200109#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200110 return current_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200111#else
112 return -1;
113#endif
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200114}
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200115
116int m_get_peak_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200117#if MICROPY_MEM_STATS
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200118 return peak_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200119#else
120 return -1;
121#endif
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200122}