blob: 45e939b6c2508553d2e62c082631ff84a9857ea7 [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <stdio.h>
2#include <stdlib.h>
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +02003#include <string.h>
Damien429d7192013-10-04 19:53:11 +01004
5#include "misc.h"
Paul Sokolovskyef181022014-01-03 03:06:25 +02006#include "mpconfig.h"
Damien429d7192013-10-04 19:53:11 +01007
Damien George2d15c122014-01-29 20:33:20 +00008#if 0 // print debugging info
Paul Sokolovsky44739e22014-02-16 18:11:42 +02009#define DEBUG_printf DEBUG_printf
Damien George2d15c122014-01-29 20:33:20 +000010#else // don't print debugging info
Damien George1dc76af2014-02-26 16:57:08 +000011#define DEBUG_printf(...) (void)0
Damien George2d15c122014-01-29 20:33:20 +000012#endif
13
Paul Sokolovskyef181022014-01-03 03:06:25 +020014#if MICROPY_MEM_STATS
Paul Sokolovsky520e2f52014-02-12 18:31:30 +020015STATIC int total_bytes_allocated = 0;
16STATIC int current_bytes_allocated = 0;
17STATIC int peak_bytes_allocated = 0;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020018
19#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
Paul Sokolovskyef181022014-01-03 03:06:25 +020020#endif
Damien429d7192013-10-04 19:53:11 +010021
Paul Sokolovskyb62c30b2014-02-10 22:37:09 +020022#if MICROPY_ENABLE_GC
23#include "gc.h"
24
25// We redirect standard alloc functions to GC heap - just for the rest of
26// this module. In the rest of micropython source, system malloc can be
27// freely accessed - for interfacing with system and 3rd-party libs for
28// example. On the other hand, some (e.g. bare-metal) ports may use GC
29// heap as system heap, so, to avoid warnings, we do undef's first.
30#undef malloc
31#undef free
32#undef realloc
Damien George12bab722014-04-05 20:35:48 +010033#define malloc(b) gc_alloc((b), false)
34#define malloc_with_finaliser(b) gc_alloc((b), true)
Paul Sokolovskyb62c30b2014-02-10 22:37:09 +020035#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) {
Damien George6902eed2014-04-04 10:52:59 +000045 return m_malloc_fail(num_bytes);
Damien429d7192013-10-04 19:53:11 +010046 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020047#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +010048 total_bytes_allocated += num_bytes;
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020049 current_bytes_allocated += num_bytes;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020050 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +020051#endif
Damien George2d15c122014-01-29 20:33:20 +000052 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Damien429d7192013-10-04 19:53:11 +010053 return ptr;
54}
55
Damien George12bab722014-04-05 20:35:48 +010056#if MICROPY_ENABLE_FINALISER
57void *m_malloc_with_finaliser(int num_bytes) {
mux4f7e9f52014-04-03 23:55:12 +020058 if (num_bytes == 0) {
59 return NULL;
60 }
Damien George12bab722014-04-05 20:35:48 +010061 void *ptr = malloc_with_finaliser(num_bytes);
mux4f7e9f52014-04-03 23:55:12 +020062 if (ptr == NULL) {
Damien George12bab722014-04-05 20:35:48 +010063 return m_malloc_fail(num_bytes);
mux4f7e9f52014-04-03 23:55:12 +020064 }
65#if MICROPY_MEM_STATS
66 total_bytes_allocated += num_bytes;
67 current_bytes_allocated += num_bytes;
68 UPDATE_PEAK();
69#endif
70 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
71 return ptr;
72}
Damien George12bab722014-04-05 20:35:48 +010073#endif
mux4f7e9f52014-04-03 23:55:12 +020074
Damien429d7192013-10-04 19:53:11 +010075void *m_malloc0(int num_bytes) {
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +020076 void *ptr = m_malloc(num_bytes);
77 if (ptr != NULL) {
78 memset(ptr, 0, num_bytes);
Damien429d7192013-10-04 19:53:11 +010079 }
Damien429d7192013-10-04 19:53:11 +010080 return ptr;
81}
82
Damien732407f2013-12-29 19:33:23 +000083void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
84 if (new_num_bytes == 0) {
Damien429d7192013-10-04 19:53:11 +010085 free(ptr);
86 return NULL;
87 }
Paul Sokolovskycdd2c622014-01-30 03:58:17 +020088 void *new_ptr = realloc(ptr, new_num_bytes);
89 if (new_ptr == NULL) {
Damien George6902eed2014-04-04 10:52:59 +000090 return m_malloc_fail(new_num_bytes);
Damien429d7192013-10-04 19:53:11 +010091 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020092#if MICROPY_MEM_STATS
Paul Sokolovsky43f1c802014-01-01 23:04:25 +020093 // At first thought, "Total bytes allocated" should only grow,
94 // after all, it's *total*. But consider for example 2K block
95 // shrunk to 1K and then grown to 2K again. It's still 2K
96 // allocated total. If we process only positive increments,
97 // we'll count 3K.
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020098 int diff = new_num_bytes - old_num_bytes;
99 total_bytes_allocated += diff;
100 current_bytes_allocated += diff;
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200101 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +0200102#endif
Paul Sokolovskycdd2c622014-01-30 03:58:17 +0200103 DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
104 return new_ptr;
Damien429d7192013-10-04 19:53:11 +0100105}
106
Damien732407f2013-12-29 19:33:23 +0000107void m_free(void *ptr, int num_bytes) {
108 if (ptr != NULL) {
109 free(ptr);
110 }
Paul Sokolovskyef181022014-01-03 03:06:25 +0200111#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200112 current_bytes_allocated -= num_bytes;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200113#endif
Damien George2d15c122014-01-29 20:33:20 +0000114 DEBUG_printf("free %p, %d\n", ptr, num_bytes);
Damien732407f2013-12-29 19:33:23 +0000115}
116
Damien8b3a7c22013-10-23 20:20:17 +0100117int m_get_total_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200118#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +0100119 return total_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200120#else
121 return -1;
122#endif
Damien429d7192013-10-04 19:53:11 +0100123}
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200124
125int m_get_current_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200126#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200127 return current_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200128#else
129 return -1;
130#endif
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200131}
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200132
133int m_get_peak_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200134#if MICROPY_MEM_STATS
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200135 return peak_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200136#else
137 return -1;
138#endif
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200139}