2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Allan CORNET
4 * Copyright (C) 2009-2010 - DIGITEO - Allan CORNET
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
23 #include "getmaxMALLOC.h"
25 #include "localization.h"
26 #include "stackinfo.h"
29 #include "dynamic_parallel.h"
30 /*--------------------------------------------------------------------------*/
31 extern int C2F(adjuststacksize) ();
33 /*--------------------------------------------------------------------------*/
34 #define MIN_STACKSIZE 180000
35 #define PARAM_MAX_STR "max"
36 #define PARAM_MIN_STR "min"
37 /*--------------------------------------------------------------------------*/
38 static int sci_stacksizeNoRhs(char *fname);
39 static int sci_stacksizeOneRhs(char *fname);
40 static int sci_stacksizeMax(char *fname);
41 static int sci_stacksizeMin(char *fname);
42 static int setStacksizeMin(char *fname);
43 static int setStacksizeMax(char *fname);
44 static int setStacksize(unsigned long newsize);
45 static unsigned long getCurrentStacksize(void);
46 static unsigned long getUsedStacksize(void);
47 static char *getStackCreationErrorMessage(int errCode);
49 /*--------------------------------------------------------------------------*/
51 * stacksize - set scilab stack size
58 * n : integer, the required stack size given in number of double precision words
59 * 'max' : try to allocate the maximum of memory
60 * 'max' : allocate the minimum of memory
61 * sz : 2-vector [total used]
63 /*--------------------------------------------------------------------------*/
64 int C2F(sci_stacksize) (char *fname, unsigned long fname_len)
73 return sci_stacksizeNoRhs(fname);
75 return dynParallelConcurrency() ? dynParallelForbidden(fname) : sci_stacksizeOneRhs(fname);
78 /*--------------------------------------------------------------------------*/
79 static int sci_stacksizeNoRhs(char *fname)
82 int *paramoutINT = NULL;
86 paramoutINT = (int *)MALLOC(sizeof(int) * 2);
88 C2F(getstackinfo) (&total, &used);
89 paramoutINT[0] = total;
90 paramoutINT[1] = used;
94 CreateVarFromPtr(Rhs + 1, MATRIX_OF_INTEGER_DATATYPE, &n1, &m1, (int *)¶moutINT);
108 /*--------------------------------------------------------------------------*/
109 static int sci_stacksizeOneRhs(char *fname)
111 int l1 = 0, n1 = 0, m1 = 0;
114 if (GetType(1) == sci_matrix)
116 GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);
117 if ((m1 == 1) && (n1 == 1))
119 unsigned long NEWMEMSTACKSIZE = (unsigned long) * stk(l1);
121 /* add 1 for alignment problems */
122 if (is_a_valid_size_for_scilab_stack(NEWMEMSTACKSIZE + 1))
124 if ((NEWMEMSTACKSIZE >= MIN_STACKSIZE) && (NEWMEMSTACKSIZE <= get_max_memory_for_scilab_stack()))
126 /* we backup previous size */
127 unsigned long backupSize = getCurrentStacksize();
129 errCode = setStacksizeMin(fname);
132 errCode = setStacksize(NEWMEMSTACKSIZE);
141 /* restore previous size */
142 setStacksize(backupSize);
143 Scierror(10001, _("%s: Cannot allocate memory.\n%s\n"), fname, getStackCreationErrorMessage(errCode));
148 /* restore previous size */
149 setStacksize(backupSize);
150 Scierror(10001, _("%s: Cannot allocate memory.\n%s\n"), fname, getStackCreationErrorMessage(errCode));
156 Scierror(1504, _("%s: Out of bounds value. Not in [%lu,%lu].\n"), fname, MIN_STACKSIZE, get_max_memory_for_scilab_stack() - 1);
161 Scierror(1504, _("%s: Out of bounds value. Not in [%lu,%lu].\n"), fname, MIN_STACKSIZE, get_max_memory_for_scilab_stack() - 1);
166 Scierror(204, _("%s: Wrong size for input argument #%d: Scalar expected.\n"), fname, 1);
169 else if (GetType(1) == sci_strings)
173 GetRhsVar(1, STRING_DATATYPE, &m1, &n1, &l1);
175 if (strcmp(PARAM_MAX_STR, param) == 0)
177 return sci_stacksizeMax(fname);
179 else if (strcmp(PARAM_MIN_STR, param) == 0)
181 return sci_stacksizeMin(fname);
185 Scierror(204, _("%s: Wrong type for input argument #%d: Scalar, '%s' or '%s'.\n"), fname, 1, "min", "max");
190 Scierror(204, _("%s: Wrong type for input argument #%d: Scalar, '%s' or '%s'.\n"), fname, 1, "min", "max");
195 /*--------------------------------------------------------------------------*/
196 static int sci_stacksizeMax(char *fname)
198 if (setStacksizeMax(fname) == 0)
205 Scierror(10001, _("%s: Cannot allocate memory.\n"), fname);
210 /*--------------------------------------------------------------------------*/
211 static int sci_stacksizeMin(char *fname)
213 if (setStacksizeMin(fname) == 0)
220 Scierror(10001, _("%s: Cannot allocate memory.\n"), fname);
225 /*--------------------------------------------------------------------------*/
226 static int setStacksizeMin(char *fname)
228 unsigned long memstackused = getUsedStacksize();
230 if (memstackused < MIN_STACKSIZE)
232 return setStacksize(MIN_STACKSIZE);
236 /* Add 3000 security for the stack */
237 return setStacksize(memstackused + 3000);
241 /*--------------------------------------------------------------------------*/
242 static int setStacksizeMax(char *fname)
244 /* we backup previous size */
245 unsigned long backupSize = getCurrentStacksize();
247 /* Bug 5495 on Windows 2000 -- WONT FIX GetLargestFreeMemoryRegion */
248 /* it works on XP, Vista, S7ven */
249 /* GetLargestFreeMemoryRegion() returns a superior size to real value */
250 unsigned long maxmemfree = (GetLargestFreeMemoryRegion()) / sizeof(double);
252 /* We have already max */
253 if (maxmemfree <= backupSize)
260 /* we do a stacksize('min') */
261 if (setStacksizeMin(fname) == 0)
264 if (maxmemfree < MIN_STACKSIZE)
266 maxmemfree = MIN_STACKSIZE;
269 errCode = setStacksize(maxmemfree);
272 setStacksize(backupSize);
273 Scierror(10001, _("%s: Cannot allocate memory.\n%s\n"), fname, getStackCreationErrorMessage(errCode));
279 /* stacksize('min') fails */
280 /* restore previous size */
281 setStacksize(backupSize);
282 Scierror(10001, _("%s: Cannot allocate memory.\n"), fname);
287 /*--------------------------------------------------------------------------*/
290 * @return 0 if success
291 * -1 if cannot allocate this quantity of memory
292 * -2 if the requested size is smaller than the minimal one
293 * -3 unable to create (or resize) the stack (probably a malloc error
295 static int setStacksize(unsigned long newsize)
297 if (newsize != getCurrentStacksize())
299 if ((newsize >= MIN_STACKSIZE))
301 if ((newsize <= get_max_memory_for_scilab_stack()))
303 unsigned long ptr = 0;
305 C2F(scimem) (&newsize, &ptr);
311 C2F(adjuststacksize) (&newsize, &ptr);
314 //sciprint(" malloc error\n");
315 return -3; /* We haven't been able to create (or resize) the stack (probably a malloc error */
317 /* Not possible to assign that amount of memory */
318 //sciprint(" Not Enough Minerals !\n");
321 /* Trying to create a too small stack */
322 //sciprint(" < MIN_STACKSIZE\n");
325 /* Set the stacksize to the same size... No need to do anything */
326 //sciprint(" same size\n");
330 /*--------------------------------------------------------------------------*/
331 static unsigned long getCurrentStacksize(void)
333 unsigned long memstacktotal = 0;
334 unsigned long memstackused = 0;
336 C2F(getstackinfo) (&memstacktotal, &memstackused);
338 return memstacktotal;
341 /*--------------------------------------------------------------------------*/
342 static unsigned long getUsedStacksize(void)
344 unsigned long memstacktotal = 0;
345 unsigned long memstackused = 0;
347 C2F(getstackinfo) (&memstacktotal, &memstackused);
352 /*--------------------------------------------------------------------------*/
354 static char *getStackCreationErrorMessage(int errCode)
359 return _("%s: Cannot allocate this quantity of memory.\n");
362 return _("%s: The requested size is smaller than the minimal one.\n");
365 return _("%s: Unable to create (or resize) the stack (probably a malloc error).\n");
368 return _("%s: Unknown error.\n");
371 /*--------------------------------------------------------------------------*/