summaryrefslogtreecommitdiff
path: root/fw/fe310/bsp/gloss/sys_sbrk.c
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2020-08-05 03:39:22 +0200
committerUros Majstorovic <majstor@majstor.org>2020-08-05 03:39:22 +0200
commitcf7c06297d04bade9cd04c056f9ed510e64dd7bd (patch)
treea3b8cc23574b98e10874b51d33c9fe1bfc012663 /fw/fe310/bsp/gloss/sys_sbrk.c
parent5cd610a07468137066ea4daa5176c3e7045113b0 (diff)
code -> fw
Diffstat (limited to 'fw/fe310/bsp/gloss/sys_sbrk.c')
-rw-r--r--fw/fe310/bsp/gloss/sys_sbrk.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/fw/fe310/bsp/gloss/sys_sbrk.c b/fw/fe310/bsp/gloss/sys_sbrk.c
new file mode 100644
index 0000000..ce10c90
--- /dev/null
+++ b/fw/fe310/bsp/gloss/sys_sbrk.c
@@ -0,0 +1,38 @@
+#include <sys/types.h>
+
+/* brk is handled entirely within the C library. This limits METAL programs that
+ * use the C library to be disallowed from dynamically allocating memory
+ * without talking to the C library, but that sounds like a sane way to go
+ * about it. Note that there is no error checking anywhere in this file, users
+ * will simply get the relevant error when actually trying to use the memory
+ * that's been allocated. */
+extern char metal_segment_heap_target_start;
+extern char metal_segment_heap_target_end;
+static char *brk = &metal_segment_heap_target_start;
+
+int
+_brk(void *addr)
+{
+ brk = addr;
+ return 0;
+}
+
+char *
+_sbrk(ptrdiff_t incr)
+{
+ char *old = brk;
+
+ /* If __heap_size == 0, we can't allocate memory on the heap */
+ if(&metal_segment_heap_target_start == &metal_segment_heap_target_end) {
+ return (void *)-1;
+ }
+
+ /* Don't move the break past the end of the heap */
+ if ((brk + incr) <= &metal_segment_heap_target_end) {
+ brk += incr;
+ } else {
+ return (void *)-1;
+ }
+
+ return old;
+}