changeset 117:32560561ccea

First attempt at program level dynamic memory Created a new "class" memStack. It is essentially the same as the other stack in the program... TODO: find a C way to combine these if possible Moved the dynamic test program to be a part of the new system, it seems to work... The general idea here is that if there is no dynamic memory in the system, it asks the os to allocate a part of its heap for the program's usage. The os gives the program a chunk, 4kb alligned, which it can use as part of its heap. Additionally, the address of the chunk is tracked by the os in a stack. When the program exits, the os will free all the memory in the stack and go back to the main program.
author Jonathan Pevarnek <pevarnj@gmail.com>
date Thu, 16 Jun 2011 11:24:39 -0400
parents 967a56b96d13
children 6186160278c9
files .hgignore Makefile include/error.h include/memStack.h include/os/svcNums.h include/prog/svcCalls.h src/dynamic.c src/os/memStack.c src/os/scall.c src/os/std.c src/prog/dynamic.c
diffstat 11 files changed, 210 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Jun 12 10:09:39 2011 -0400
+++ b/.hgignore	Thu Jun 16 11:24:39 2011 -0400
@@ -16,3 +16,4 @@
 ^hercules/curDisk\.img$
 
 ^changes
+^Makefile\.bak$
--- a/Makefile	Sun Jun 12 10:09:39 2011 -0400
+++ b/Makefile	Thu Jun 16 11:24:39 2011 -0400
@@ -12,15 +12,15 @@
 LDFLAGS=-m elf64_s390
 
 OSBINS=shell
-PROGBINS=hello ls echo
+PROGBINS=hello ls echo dynamic
 
-shell_OBJS=src/os/shell.o src/os/std.o src/os/fs.o src/os/string.o src/os/stdio.o src/os/scall.o src/os/heap.o arch/arch.a
+shell_OBJS=src/os/shell.o src/os/std.o src/os/fs.o src/os/string.o src/os/stdio.o src/os/scall.o src/os/heap.o src/os/memStack.o arch/arch.a
 hello_OBJS=src/prog/hello.o src/prog/std.o src/prog/string.o
 ls_OBJS=src/prog/ls.o
 echo_OBJS=src/prog/echo.o src/prog/std.o src/prog/string.o
+dynamic_OBJS=src/prog/dynamic.o src/prog/std.o src/prog/string.o src/prog/stack.o
 
 sarpn_OBJS=src/sarpn.o src/std.o src/string.o src/prog/stack.o src/operations.o src/math.o arch/arch.a
-dynamic_OBJS=src/dynamic.o src/std.o src/string.o src/stack.o arch/arch.a
 testFS_OBJS=src/testFS.o src/std.o src/string.o src/os/fs.o arch/arch.a
 
 ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o \
@@ -57,11 +57,11 @@
 	$(LD) $(LDFLAGS) -T scripts/linkerProg.script -o $@ $^
 echo: $(echo_OBJS)
 	$(LD) $(LDFLAGS) -T scripts/linkerProg.script -o $@ $^
+dynamic: $(dynamic_OBJS)
+	$(LD) $(LDFLAGS) -T scripts/linkerProg.script -o $@ $^
 
 sarpn: $(sarpn_OBJS)
 	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
-dynamic: $(dynamic_OBJS)
-	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
 testFS: $(testFS_OBJS)
 	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
 
@@ -119,8 +119,6 @@
 
 # DO NOT DELETE
 
-src/dynamic.o: include/std.h include/die.h include/memHead.h include/string.h
-src/dynamic.o: include/stack.h
 src/sarpn.o: include/std.h include/die.h include/memHead.h include/string.h
 src/sarpn.o: include/operations.h include/stack.h
 src/testFS.o: include/std.h include/die.h include/memHead.h include/os/fs.h
--- a/include/error.h	Sun Jun 12 10:09:39 2011 -0400
+++ b/include/error.h	Thu Jun 16 11:24:39 2011 -0400
@@ -14,6 +14,7 @@
 //Modules
 #define MODFS 1 //stuff in the file system
 #define MODTOD 2 //Time of date
+#define MODMS 3 //memStack
 
 #define NOERROR 0 //General error code for not an error
 
@@ -33,6 +34,10 @@
 #define UPTIME 1 //the actual time of date was not set in the system
 #define INVALID 2
 
+//Codes: memstack
+//1: allocfail
+#define EMPTY 2 //stack is empty
+
 
 typedef u32 ErrCode;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/memStack.h	Thu Jun 16 11:24:39 2011 -0400
@@ -0,0 +1,24 @@
+#ifndef __MEMSTACK_H
+#define __MEMSTACK_H
+
+#include <error.h>
+
+typedef void* Pointer;
+
+struct MSELT {
+	Pointer elt;
+	struct MSELT *next;
+};
+typedef struct MSELT MSElt;
+
+typedef struct {
+	MSElt *top;
+} MemStack;
+
+ErrCode msPop(MemStack *stack, Pointer *value);
+ErrCode msPush(MemStack *stack, Pointer value);
+MemStack* msInit();
+void msDestroyFN(MemStack *stack, void (*fn)(void*));
+void msDestroy(MemStack *stack);
+
+#endif
--- a/include/os/svcNums.h	Sun Jun 12 10:09:39 2011 -0400
+++ b/include/os/svcNums.h	Thu Jun 16 11:24:39 2011 -0400
@@ -5,5 +5,6 @@
 #define SVC_PRINT 1
 #define SVC_READ 2
 #define SVC_FINFO 3
+#define SVC_GETHEAP 4
 
 #endif //__SVCNUMS_H
--- a/include/prog/svcCalls.h	Sun Jun 12 10:09:39 2011 -0400
+++ b/include/prog/svcCalls.h	Thu Jun 16 11:24:39 2011 -0400
@@ -25,5 +25,10 @@
 	return invoke_svc2(SVC_FINFO, n, de);
 }
 
+static inline void* getHeap(size_t size, size_t *ammt)
+{
+	return (void*)invoke_svc2(SVC_GETHEAP, size, ammt);
+}
+
 
 #endif //__SVCCALLS_H
--- a/src/dynamic.c	Sun Jun 12 10:09:39 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * This is where everything starts
- */
-
-#include <std.h>
-#include <string.h>
-#include <stack.h>
-
-//This are simple debug functions for the memory
-
-void printHeader(Header* head)
-{
-	char buffer[20];
-	sPrint("Memory address is: ");
-	sPrint(itoa((intptr_t)head, buffer, 16));
-	sPrint("\n");
-	sPrint("The size of the block is: ");
-	sPrint(itoa(head->size, buffer, 10));
-	sPrint("\n");
-	sPrint("Next memory address is: ");
-	sPrint(itoa((intptr_t)head->next, buffer, 16));
-	sPrint("\n\n");
-}
-
-void printMem()
-{
-	Header *start = malloc(0);
-	Header *cur = start - 1; //this will be a block in the memory
-	free(start--);
-	do {
-		printHeader(cur);
-		cur = cur->next;
-	} while(cur != start);
-	sPrint("PRINTOUT DONE\n\n");
-}
-
-void dumpBuffer(char *a, int b)
-{
-	int i;
-	for(i = 0; i < b; i++) {
-		int foo = (int) a[i];
-		char c[10];
-		itoa(foo, c, 16);
-		sPrint(c);
-		sPrint(" ");
-		if(!((i + 1)%20)) sPrint("\n");
-	}
-}
-
-void start(u64 __memsize)
-{
-	init_all(__memsize);
-	size_t n;
-	char *buffer;
-	char input[30];
-
-	while(0) {
-		sPrint("How long do you want the string? ");
-		n = atoi(sGet(input, 30));
-		buffer = (char*) malloc(n);
-		if (!buffer) { //allocation failed, too large
-			sPrint("ERROR\n");
-			break;
-		}
-//		size_t i;
-//		for (i = 0; i < n - 1; i++)
-//			buffer[i]='a'; //I need to make rand...
-//		buffer[n - 1]='\0';
-//		sPrint(buffer), sPrint("\n");
-//		dumpBuffer(buffer, n);
-		sPrint(strcat(itoa((unsigned long)buffer, input, 16), "\n"));
-		free(buffer);
-	}
-
-	printMem();
-
-	Stack *stack = stack_init();
-
-	for(n = 0; n < 1000; n++) {
-		push(stack, n);
-	}
-	stack_destroy(stack);
-
-
-	printMem();
-	void *a = malloc(1223);
-	void *b = malloc(352);
-	void *c = malloc(3539);
-	void *d = malloc(325);
-	printMem();
-	free(b);
-	printMem();
-	b = malloc(400);
-	printMem();
-	sPrint("DONE\n");
-	free(a);
-	free(c);
-	free(d);
-
-	for(;;)
-		sGet(input, 0);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/memStack.c	Thu Jun 16 11:24:39 2011 -0400
@@ -0,0 +1,55 @@
+#include <memStack.h>
+#include <error.h>
+#include <std.h>
+
+//TODO come up with a nice generic stack (possible?)
+
+ErrCode msPop(MemStack *stack, Pointer *value)
+{
+	if(stack->top == NULL) {
+		return mkError(MODMS, EMPTY, ERROR);
+	} else {
+		MSElt *tip = stack->top;
+		*value = tip->elt;
+		stack->top = tip->next;
+		free(tip);
+		return NOERROR;
+	}
+}
+
+ErrCode msPush(MemStack *stack, Pointer value)
+{
+	MSElt *tip = malloc(sizeof(MSElt));
+	if(!tip) return mkError(MODMS, ALLOCFAIL, ERROR);
+	tip->elt = value;
+	tip->next = stack->top;
+	stack->top = tip;
+	return NOERROR;
+}
+
+MemStack* msInit()
+{
+	MemStack *new = malloc(sizeof(MemStack)); //TODO error checking?
+	new->top = NULL;
+	return new;
+}
+
+static void doNothing(void *foo)
+{
+	return;
+}
+
+void msDestroyFN(MemStack *stack, void (*fn)(void*))
+{
+	Pointer point;
+	while(stack->top) {
+		msPop(stack, &point);
+		fn(point);
+	}
+	free(stack);
+}
+
+void msDestroy(MemStack *stack)
+{
+	msDestroyFN(stack, doNothing);
+}
--- a/src/os/scall.c	Sun Jun 12 10:09:39 2011 -0400
+++ b/src/os/scall.c	Thu Jun 16 11:24:39 2011 -0400
@@ -2,18 +2,24 @@
 #include <os/svcNums.h>
 #include <os/fs.h>
 #include <os/svc.h>
+#include <os/heap.h>
+#include <memStack.h>
 /*
 #include <stdio.h>
 #include <string.h>
 */
 
+MemStack *ms = NULL;
+
 u64 svc_handler(u64 callCode, u64 a, u64 b, u64 c, u64 d)
 {
 	Psw psw;
 	u64 registers[16];
+	void* point;
 	savecontext(&psw, registers);
 	switch(callCode) {
 		case SVC_EXIT:
+			if(ms) msDestroyFN(ms, freeHeap); //dynamic memory was used, kill it
 			setcontext(&shellPsw, shellRegisters);
 			break;
 		case SVC_PRINT: //print
@@ -25,6 +31,12 @@
 		case SVC_FINFO:
 			registers[2] = getFInfo(a, (void*) b);
 			break;
+		case SVC_GETHEAP:
+			point = allocHeap(a, (void*)b);
+			if(!ms) ms = msInit();
+			msPush(ms, point);
+			registers[2] = (u64)point;
+			break;
 		default:
 			registers[2] = -1; //TODO HACK
 			break;
--- a/src/os/std.c	Sun Jun 12 10:09:39 2011 -0400
+++ b/src/os/std.c	Thu Jun 16 11:24:39 2011 -0400
@@ -190,9 +190,7 @@
 #ifdef OSLEVEL
 	block = allocHeap(size, &allocSize);
 #else
-	size = 0;
-	block = NULL;
-	sPrint("Program level malloc has not been implemented yet, sorry\n");
+	block = getHeap(size, &allocSize);
 #endif
 	if(!block) return NULL;
 	Header *blockH = block;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/prog/dynamic.c	Thu Jun 16 11:24:39 2011 -0400
@@ -0,0 +1,101 @@
+#include <prog/svcCalls.h>
+#include <std.h>
+#include <string.h>
+#include <stack.h>
+
+//This are simple debug functions for the memory
+
+void printHeader(Header* head)
+{
+	char buffer[20];
+	sPrint("Memory address is: ");
+	sPrint(itoa((intptr_t)head, buffer, 16));
+	sPrint("\n");
+	sPrint("The size of the block is: ");
+	sPrint(itoa(head->size, buffer, 10));
+	sPrint("\n");
+	sPrint("Next memory address is: ");
+	sPrint(itoa((intptr_t)head->next, buffer, 16));
+	sPrint("\n\n");
+}
+
+void printMem()
+{
+	Header *start = malloc(0);
+	Header *cur = start - 1; //this will be a block in the memory
+	free(start--);
+	do {
+		printHeader(cur);
+		cur = cur->next;
+	} while(cur != start);
+	sPrint("PRINTOUT DONE\n\n");
+}
+
+void dumpBuffer(char *a, int b)
+{
+	int i;
+	for(i = 0; i < b; i++) {
+		int foo = (int) a[i];
+		char c[10];
+		itoa(foo, c, 16);
+		sPrint(c);
+		sPrint(" ");
+		if(!((i + 1)%20)) sPrint("\n");
+	}
+}
+
+void start(u64 __memsize)
+{
+	init_all(__memsize);
+	size_t n;
+	char *buffer;
+	char input[30];
+
+	while(0) {
+		sPrint("How long do you want the string? ");
+		n = atoi(sGet(input, 30));
+		buffer = (char*) malloc(n);
+		if (!buffer) { //allocation failed, too large
+			sPrint("ERROR\n");
+			break;
+		}
+//		size_t i;
+//		for (i = 0; i < n - 1; i++)
+//			buffer[i]='a'; //I need to make rand...
+//		buffer[n - 1]='\0';
+//		sPrint(buffer), sPrint("\n");
+//		dumpBuffer(buffer, n);
+		sPrint(strcat(itoa((unsigned long)buffer, input, 16), "\n"));
+		free(buffer);
+	}
+
+	printMem();
+
+	/*
+	Stack *stack = stack_init();
+
+	for(n = 0; n < 1000; n++) {
+		push(stack, n);
+	}
+	stack_destroy(stack);
+	*/
+
+
+	printMem();
+	void *a = malloc(1223);
+	void *b = malloc(352);
+	void *c = malloc(3539);
+	void *d = malloc(325);
+	printMem();
+	free(b);
+	printMem();
+	b = malloc(400);
+	printMem();
+	sPrint("DONE\n");
+	free(a);
+	free(c);
+	free(d);
+
+	for(;;)
+		sGet(input, 0);
+}