Roland Mainz
2013-09-18 05:14:37 UTC
Hi!
----
[Mainly for Glenn]
Below is the promised demo code which shows a way to do temporary
allocations from the stack but switch to |malloc()| if they grow too
large (a similar wrapper could be done with |stkalloc()| instead of
|malloc()|).
Erm... Glenn: If the concept looks good enough then I can make a patch
to integrate it into libast... and then we can go hunting for
consumers...
* Notes:
- Typical stack allocations should be 1/8-1/4 of the system's page
size... but usually 256 bytes is a good trade-off. However if a system
supports and uses largepages (rememer Solaris/SPARC uses 64k pages for
the stack) for stack a larger size may be better
- On pre-C99 platforms the macro waste stack space if |malloc()| is
used. With ISO C99 or higher the macros use VLAs (=variable length
arrays) to reduce the size of the stack arrays we grab memory from to
1 byte (we can't use 0 for portability reasons and to ensure the
debuggers/instrumentation tools don't get mad)
- The whole macro set was "inspired" by the |utf322wc()| iconv code
which currently has two codepaths... one with |malloc()| and one
without... maybe we can "fold" the code back to one which uses these
macros (which would mean much less code usage)
- There should be a build-time option to always force the usage of
|malloc()| ... this would mainly be to help instrumentation utilities
(e.g. valgrind, Rational Purity etc.)
Code follows...
-- snip --
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if __STDC_VERSION__ >= 199901L
/*
* Use variable-lenth arrays (=VLAs) to reduce the size of the stack
* memory area to 1 (0 is not supported by all compilers) if we
* don't use it
*/
#define TMPSTACKMALLOC(varname, size, maxstack) \
char _##varname##_s[((size) > (maxstack))?1:(maxstack)]; \
void *varname; \
(varname = (void *)(((size) > (maxstack))? \
(malloc(size)): \
(_##varname##_s)))
#else
#define TMPSTACKMALLOC(varname, size, maxstack) \
char _##varname##_s[(maxstack)]; \
void *varname; \
(varname = (void *)(((size) > (maxstack))? \
(malloc(size)): \
(_##varname##_s)))
#endif
#define TMPSTACKFREE(varname) \
if((varname) != (_##varname##_s) && (varname) != NULL) \
free((varname))
int main(int ac, char *av[])
{
puts("#start.");
TMPSTACKMALLOC(myv, 5000, 8192);
memset(myv, 5, 5000);
TMPSTACKFREE(myv);
puts("#done.");
return(EXIT_SUCCESS);
}
-- snip --
----
Bye,
Roland
----
[Mainly for Glenn]
Below is the promised demo code which shows a way to do temporary
allocations from the stack but switch to |malloc()| if they grow too
large (a similar wrapper could be done with |stkalloc()| instead of
|malloc()|).
Erm... Glenn: If the concept looks good enough then I can make a patch
to integrate it into libast... and then we can go hunting for
consumers...
* Notes:
- Typical stack allocations should be 1/8-1/4 of the system's page
size... but usually 256 bytes is a good trade-off. However if a system
supports and uses largepages (rememer Solaris/SPARC uses 64k pages for
the stack) for stack a larger size may be better
- On pre-C99 platforms the macro waste stack space if |malloc()| is
used. With ISO C99 or higher the macros use VLAs (=variable length
arrays) to reduce the size of the stack arrays we grab memory from to
1 byte (we can't use 0 for portability reasons and to ensure the
debuggers/instrumentation tools don't get mad)
- The whole macro set was "inspired" by the |utf322wc()| iconv code
which currently has two codepaths... one with |malloc()| and one
without... maybe we can "fold" the code back to one which uses these
macros (which would mean much less code usage)
- There should be a build-time option to always force the usage of
|malloc()| ... this would mainly be to help instrumentation utilities
(e.g. valgrind, Rational Purity etc.)
Code follows...
-- snip --
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if __STDC_VERSION__ >= 199901L
/*
* Use variable-lenth arrays (=VLAs) to reduce the size of the stack
* memory area to 1 (0 is not supported by all compilers) if we
* don't use it
*/
#define TMPSTACKMALLOC(varname, size, maxstack) \
char _##varname##_s[((size) > (maxstack))?1:(maxstack)]; \
void *varname; \
(varname = (void *)(((size) > (maxstack))? \
(malloc(size)): \
(_##varname##_s)))
#else
#define TMPSTACKMALLOC(varname, size, maxstack) \
char _##varname##_s[(maxstack)]; \
void *varname; \
(varname = (void *)(((size) > (maxstack))? \
(malloc(size)): \
(_##varname##_s)))
#endif
#define TMPSTACKFREE(varname) \
if((varname) != (_##varname##_s) && (varname) != NULL) \
free((varname))
int main(int ac, char *av[])
{
puts("#start.");
TMPSTACKMALLOC(myv, 5000, 8192);
memset(myv, 5, 5000);
TMPSTACKFREE(myv);
puts("#done.");
return(EXIT_SUCCESS);
}
-- snip --
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)