blob: 27eaac108826401983855268950a7ed138a551d6 [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
33#define malloc gc_alloc
34#define free gc_free
35#define realloc gc_realloc
36#endif // MICROPY_ENABLE_GC
37
Damien429d7192013-10-04 19:53:11 +010038void *m_malloc(int num_bytes) {
39 if (num_bytes == 0) {
40 return NULL;
41 }
42 void *ptr = malloc(num_bytes);
43 if (ptr == NULL) {
44 printf("could not allocate memory, allocating %d bytes\n", num_bytes);
45 return NULL;
46 }
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
56void *m_malloc0(int num_bytes) {
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +020057 void *ptr = m_malloc(num_bytes);
58 if (ptr != NULL) {
59 memset(ptr, 0, num_bytes);
Damien429d7192013-10-04 19:53:11 +010060 }
Damien429d7192013-10-04 19:53:11 +010061 return ptr;
62}
63
Damien732407f2013-12-29 19:33:23 +000064void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
65 if (new_num_bytes == 0) {
Damien429d7192013-10-04 19:53:11 +010066 free(ptr);
67 return NULL;
68 }
Paul Sokolovskycdd2c622014-01-30 03:58:17 +020069 void *new_ptr = realloc(ptr, new_num_bytes);
70 if (new_ptr == NULL) {
Damien732407f2013-12-29 19:33:23 +000071 printf("could not allocate memory, reallocating %d bytes\n", new_num_bytes);
Damien429d7192013-10-04 19:53:11 +010072 return NULL;
73 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020074#if MICROPY_MEM_STATS
Paul Sokolovsky43f1c802014-01-01 23:04:25 +020075 // At first thought, "Total bytes allocated" should only grow,
76 // after all, it's *total*. But consider for example 2K block
77 // shrunk to 1K and then grown to 2K again. It's still 2K
78 // allocated total. If we process only positive increments,
79 // we'll count 3K.
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020080 int diff = new_num_bytes - old_num_bytes;
81 total_bytes_allocated += diff;
82 current_bytes_allocated += diff;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020083 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +020084#endif
Paul Sokolovskycdd2c622014-01-30 03:58:17 +020085 DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
86 return new_ptr;
Damien429d7192013-10-04 19:53:11 +010087}
88
Damien732407f2013-12-29 19:33:23 +000089void m_free(void *ptr, int num_bytes) {
90 if (ptr != NULL) {
91 free(ptr);
92 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020093#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020094 current_bytes_allocated -= num_bytes;
Paul Sokolovskyef181022014-01-03 03:06:25 +020095#endif
Damien George2d15c122014-01-29 20:33:20 +000096 DEBUG_printf("free %p, %d\n", ptr, num_bytes);
Damien732407f2013-12-29 19:33:23 +000097}
98
Damien8b3a7c22013-10-23 20:20:17 +010099int m_get_total_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200100#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +0100101 return total_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200102#else
103 return -1;
104#endif
Damien429d7192013-10-04 19:53:11 +0100105}
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200106
107int m_get_current_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200108#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200109 return current_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200110#else
111 return -1;
112#endif
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200113}
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200114
115int m_get_peak_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200116#if MICROPY_MEM_STATS
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200117 return peak_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200118#else
119 return -1;
120#endif
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200121}