From 0d67f8bb210a940c3b5ee59e7b29766d7b3d7c60 Mon Sep 17 00:00:00 2001
From: Terraneo Federico <fede.tft@hotmail.it>
Date: Thu, 23 Jan 2014 00:57:16 +0000
Subject: [PATCH] Refactored Thread::createUserspace(), thread creation no
 longer calls errorHandler(OUT_OF_MEMORY)

---
 miosix/_doc/textdoc/Changelog.txt         |  5 +++
 miosix/kernel/kernel.cpp                  | 41 +++++------------------
 miosix/kernel/kernel.h                    |  3 +-
 miosix_np_2/nbproject/private/private.xml |  2 ++
 4 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/miosix/_doc/textdoc/Changelog.txt b/miosix/_doc/textdoc/Changelog.txt
index 7b3928ac..15957f68 100644
--- a/miosix/_doc/textdoc/Changelog.txt
+++ b/miosix/_doc/textdoc/Changelog.txt
@@ -1,5 +1,10 @@
 Changelog for Miosix np embedded OS
 
+- Thread creation no longer calls errorHandler(OUT_OF_MEMORY) if there
+  is no memory to create a thread. This has been done to prevent system
+  reboots when the (kernel) heap is full, especially if a process creates
+  another process.
+- Refactored Thread::createUserspace() to call Thread::doCreate()
 - Added a per-process FileDescriptorTable
 - Added ProcessBase class. The kernel used to have a null pointer as process,
   now it has a ProcessBase instance, and is the only entity that has an
diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp
index 3d45f973..64e14a68 100644
--- a/miosix/kernel/kernel.cpp
+++ b/miosix/kernel/kernel.cpp
@@ -580,11 +580,8 @@ Thread *Thread::doCreate(void*(*startfunc)(void*) , unsigned int stacksize,
     //Allocate memory for the thread, return if fail
     unsigned int *base=static_cast<unsigned int*>(malloc(sizeof(Thread)+
             fullStackSize));
-    if(base==NULL)
-    {
-        errorHandler(OUT_OF_MEMORY);
-        return NULL;
-    }
+    if(base==NULL) return NULL;
+    
     //At the top of thread memory allocate the Thread class with placement new
     void *threadClass=base+(fullStackSize/sizeof(unsigned int));
     Thread *thread=new (threadClass) Thread(base,stacksize,defaultReent);
@@ -701,41 +698,21 @@ miosix_private::SyscallParameters Thread::switchToUserspace()
 
 Thread *Thread::createUserspace(void *(*startfunc)(void *), void *argv,
                     unsigned short options, Process *proc)
-{   
-    //Allocate memory for the thread, return if fail
-    unsigned int *base=static_cast<unsigned int*>(malloc(sizeof(Thread)+
-            SYSTEM_MODE_PROCESS_STACK_SIZE+WATERMARK_LEN+CTXSAVE_ON_STACK));
-    if(base==NULL)
-    {
-        errorHandler(OUT_OF_MEMORY);
-        return NULL;//Error
-    }
-    //At the top of thread memory allocate the Thread class with placement new
-    void *threadClass=base+((SYSTEM_MODE_PROCESS_STACK_SIZE+WATERMARK_LEN+
-            CTXSAVE_ON_STACK)/sizeof(unsigned int));
-    Thread *thread=new (threadClass) Thread(base,SYSTEM_MODE_PROCESS_STACK_SIZE,false);
+{
+    Thread *thread=doCreate(startfunc,SYSTEM_MODE_PROCESS_STACK_SIZE,argv,
+            options,false);
+    if(thread==NULL) return NULL;
+
+    unsigned int *base=thread->watermark;
     try {
         thread->userCtxsave=new unsigned int[CTXSAVE_SIZE];
-    } catch(std::bad_alloc&)
-    {
+    } catch(std::bad_alloc&) {
         thread->~Thread();
         free(base); //Delete ALL thread memory
-        errorHandler(OUT_OF_MEMORY);
         return NULL;//Error
     }
-
-    //Fill watermark and stack
-    memset(base, WATERMARK_FILL, WATERMARK_LEN);
-    base+=WATERMARK_LEN/sizeof(unsigned int);
-    memset(base, STACK_FILL, SYSTEM_MODE_PROCESS_STACK_SIZE);
-
-    //On some architectures some registers are saved on the stack, therefore
-    //initCtxsave *must* be called after filling the stack.
-    miosix_private::initCtxsave(thread->ctxsave,startfunc,
-            reinterpret_cast<unsigned int*>(thread),argv);
     
     thread->proc=proc;
-    if((options & JOINABLE)==0) thread->flags.IRQsetDetached();
     thread->flags.IRQsetWait(true); //Thread is not yet ready
     
     //Add thread to thread list
diff --git a/miosix/kernel/kernel.h b/miosix/kernel/kernel.h
index ddec3c5f..cd5d4f77 100644
--- a/miosix/kernel/kernel.h
+++ b/miosix/kernel/kernel.h
@@ -438,8 +438,7 @@ public:
      * to delete it, or NULL in case of errors.
      *
      * Calls errorHandler(INVALID_PARAMETERS) if stacksize or priority are
-     * invalid, and errorHandler(OUT_OF_MEMORY) if the heap is full.
-     * Can be called when the kernel is paused.
+     * invalid. Can be called when the kernel is paused.
      */
     static Thread *create(void *(*startfunc)(void *), unsigned int stacksize,
                             Priority priority=Priority(), void *argv=NULL,
diff --git a/miosix_np_2/nbproject/private/private.xml b/miosix_np_2/nbproject/private/private.xml
index fc1d89ef..b8cb6f37 100644
--- a/miosix_np_2/nbproject/private/private.xml
+++ b/miosix_np_2/nbproject/private/private.xml
@@ -12,10 +12,12 @@
     <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
         <group>
             <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/kernel/process.h</file>
+            <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/filesystem/file_access.h</file>
             <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/kernel/kernel.h</file>
             <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/kernel/process.cpp</file>
             <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/kernel/kernel.cpp</file>
             <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/main.cpp</file>
+            <file>file:/media/truecrypt1/Projects/ARM/miosix/miosix-kernel/miosix/filesystem/file_access.cpp</file>
         </group>
     </open-files>
 </project-private>
-- 
GitLab