change method to alloc stack in stacksize max ( Windows ) 43/13343/3
Antoine ELIAS [Mon, 9 Dec 2013 11:53:46 +0000 (12:53 +0100)]
Change-Id: I5f6d1f461c76300dfc8698d3f014ac43834cb8f2

scilab/modules/core/sci_gateway/c/sci_stacksize.c
scilab/modules/core/src/c/getmaxMALLOC.c
scilab/modules/core/src/c/scimem.c

index 8aff685..2890dac 100644 (file)
@@ -28,6 +28,7 @@
 #include "localization.h"
 #include "stackinfo.h"
 #include "Scierror.h"
+#include "sciprint.h"
 #include "dynamic_parallel.h"
 /*--------------------------------------------------------------------------*/
 extern int C2F(adjuststacksize) ();
@@ -252,51 +253,29 @@ static int setStacksizeMax(char *fname)
     unsigned long maxmemfree = (GetLargestFreeMemoryRegion()) / sizeof(double);
 
     long long freePhysicalMem = 0;
-#ifdef _MSC_VER
-    MEMORYSTATUSEX statex;
-    statex.dwLength = sizeof (statex);
-    GlobalMemoryStatusEx (&statex);
-    //do not exceed available free memory
-
-    //use min value between max memory available and max "allocable" memory by Scilab
 
-    freePhysicalMem =  (long long)(statex.ullAvailPageFile / sizeof(double));
-    //if free memory is used, keep 10% to OS
-#else
+#ifndef _MSC_VER
     freePhysicalMem = (long long)((get_avphys_pages() * get_phys_pages()) / sizeof(double));
 #endif
 
-    if (freePhysicalMem > 0 && freePhysicalMem < maxmemfree)
-    {
-        maxmemfree = (unsigned long)(freePhysicalMem * 0.9);
-    }
-
     /* We have already max */
     if (maxmemfree <= backupSize)
     {
         LhsVar(1) = 0;
-        C2F(putlhsvar) ();
+        PutLhsVar();
         return 0;
     }
 
     /* we do a stacksize('min') */
     if (setStacksizeMin(fname) == 0)
     {
-        unsigned long memmaxavailablebyscilab = get_max_memory_for_scilab_stack();
-        unsigned long newMemSizeMax = maxmemfree;
-        int errCode;
-
-        if (memmaxavailablebyscilab < newMemSizeMax)
-        {
-            newMemSizeMax = memmaxavailablebyscilab;
-        }
-
-        if (newMemSizeMax < MIN_STACKSIZE)
+        int errCode = 0;
+        if (maxmemfree < MIN_STACKSIZE)
         {
-            newMemSizeMax = MIN_STACKSIZE;
+            maxmemfree = MIN_STACKSIZE;
         }
 
-        errCode = setStacksize(newMemSizeMax);
+        errCode = setStacksize(maxmemfree);
         if (errCode != 0)
         {
             setStacksize(backupSize);
@@ -341,15 +320,19 @@ static int setStacksize(unsigned long newsize)
                     C2F(adjuststacksize) (&newsize, &ptr);
                     return 0;
                 }
+                //sciprint("  malloc error\n");
                 return -3;      /* We haven't been able to create (or resize) the stack (probably a malloc error */
             }
             /* Not possible to assign that amount of memory */
+            //sciprint("  Not Enough Minerals !\n");
             return -1;
         }
         /* Trying to create a too small stack */
+        //sciprint("  < MIN_STACKSIZE\n");
         return -2;
     }
     /* Set the stacksize to the same size... No need to do anything */
+    //sciprint("  same size\n");
     return 0;
 }
 
index b1aa8ae..ac12db0 100644 (file)
@@ -13,6 +13,8 @@
 /*-----------------------------------------------------------------------------------*/
 #ifdef _MSC_VER
 #include <Windows.h>
+#include <Psapi.h>
+#include "getScilabPreference.h"
 #else
 #include <sys/resource.h>
 #include "machine.h"
 #endif
 
 #include "getmaxMALLOC.h"
+#include "sciprint.h"
 /*-----------------------------------------------------------------------------------*/
 #ifdef _MSC_VER
 unsigned long GetLargestFreeMemoryRegion(void)
 {
+
 #if _WIN64
+
+    const ScilabPreferences* prefs =  getScilabPreferences();
     /* we need to limit values to 32 bits for Scilab :( */
 
     /* Bug 10439 JVM reserves some space in 32 bit space */
     /* "Empiric" value for a Java Heap space to 256mb */
     /* It is not really a good workaround :/ */
-#define SECURITY_FREE_MEMORY 355483647
-
-    return MAXLONG32 - SECURITY_FREE_MEMORY;
+    unsigned long SECURITY_FREE_MEMORY = (atoi(prefs->heapSize) + 85) * (1024 * 1024);
 #else
 #define SECURITY_FREE_MEMORY 1040000
-    SYSTEM_INFO systemInfo;
-    VOID *p = 0;
-    MEMORY_BASIC_INFORMATION mbi;
-    unsigned long largestSize = 0;
+#endif
 
-    GetSystemInfo(&systemInfo);
+    unsigned long realSize = 0;
 
-    while (p < systemInfo.lpMaximumApplicationAddress)
-    {
-        SIZE_T dwRet = VirtualQuery(p, &mbi, sizeof(mbi));
-        if (dwRet > 0)
-        {
-            if (mbi.State == MEM_FREE)
-            {
-                if (largestSize < mbi.RegionSize)
-                {
-                    largestSize = (unsigned long) mbi.RegionSize;
-                }
-            }
-            p = (void*) (((char*)p) + mbi.RegionSize);
-        }
-        else
-        {
-            p = (void*) (((char*)p) + systemInfo.dwPageSize);
-        }
-    }
-    /* We remove a security size to be sure that MALLOC doesn't fails */
-    if (largestSize > SECURITY_FREE_MEMORY)
+    //due to scilab stack limitation this value must not be > MAX_INT
+    realSize = 0x7fffffff;
+
+    if (realSize > SECURITY_FREE_MEMORY)
     {
-        largestSize = largestSize - SECURITY_FREE_MEMORY;
+        realSize -= SECURITY_FREE_MEMORY;
     }
-
-    return largestSize;
-#endif
+    return realSize;
 }
 /*-----------------------------------------------------------------------------------*/
 #else
index a9eb62a..ff8d72d 100644 (file)
@@ -33,6 +33,7 @@ int C2F(scimem) (int *newsize, int *ptr)
     return scimem64(ptr, *newsize, FALSE);
 #else
     register char *p1 = NULL;
+    double coef = 1.0;
 
     if (*newsize > 0)
     {
@@ -40,16 +41,28 @@ int C2F(scimem) (int *newsize, int *ptr)
         /* the last +2 is to overcome a problem with adjuststack. */
         /* Which appears on OpenSolaris and on mandriva + EEEPC. */
         /* To be corrected. Thanks Jonathan */
-        p1 = (char *)SCISTACKMALLOC(((unsigned long)sizeof(double)) * (*newsize + 1 + 2));
-
-        if (p1 != NULL)
+        while (coef > 0)
         {
-            the_ps = the_p;
-            the_p = p1;
-            /* add 1 for alignment problems */
-            *ptr = ((int)(the_p - (char *)C2F(stack).Stk)) / sizeof(double) + 1;
+            int size = (int)(*newsize * coef);
+            p1 = (char *)SCISTACKMALLOC((size + 1 + 2) * sizeof(double));
+            if (p1 != NULL)
+            {
+                the_ps = the_p;
+                the_p = p1;
+                /* add 1 for alignment problems */
+                *ptr = ((int)(the_p - (char *)C2F(stack).Stk)) / sizeof(double) + 1;
+                *newsize = size;
+                //sciprint("SUCCEED to alloc %0.0f MB ( %0.0f%% )\n", (double)(size + 1 + 2) * sizeof(double) / (1024*1024), coef * 100);
+                break;
+            }
+            else
+            {
+                //sciprint("FAILED to alloc %0.0f MB\n", (double)(size + 1 + 2) * sizeof(double) / (1024*1024));
+                coef -= 0.01; //remove 1%
+            }
         }
-        else
+
+        if (p1 == NULL)
         {
             /* We could not create a new stack, so, we are using the previous one */
             if (the_p == NULL)
@@ -58,13 +71,14 @@ int C2F(scimem) (int *newsize, int *ptr)
                 sciprint(_("No space to allocate Scilab stack.\n"));
                 exit(1);
             }
+
             *ptr = 0;
         }
+
     }
     return (0);
 #endif
 }
-
 /*--------------------------------------------------------------------------*/
 int C2F(scigmem) (int *n, int *ptr)
 {