23# ifndef __sync_synchronize
24# define __sync_synchronize void
29#include <sys/resource.h>
47#define RAMBLOCKS_MAX 1000
55static int checked_getrlimit(
int resource,
struct rlimit *rlim)
58 if (getrlimit(resource, rlim) != 0) {
60 fprintf (stderr,
"%s:%d getrlimit() failed with errno=%d %s\n",
61 __FILE__,__LINE__, errno,strerror(errno));
75static size_t oomtest_fill_preinit(
const size_t minHeap,
const size_t minStack)
84size_t (*
oomtest_fill)(
const size_t minHeap,
const size_t minStack)=oomtest_fill_preinit;
94static void oomtest_free_preinit()
110static size_t oomtest_enable_preinit(
const size_t softlimit)
115 fprintf(stderr,
"%s:%d oomtest_enable called without oomtest_config before\n",__FILE__,__LINE__);
130static size_t oomtest_disable_preinit()
133 fprintf(stderr,
"%s:%d oomtest_disable called without oomtest_config before\n",__FILE__,__LINE__);
151static size_t oomtest_getbiggestblock(
void** p_ramblock)
164 static size_t max,cur;
165 static struct rlimit limit;
171 checked_getrlimit(RLIMIT_AS, &limit);
172 max = limit.rlim_cur;
175 while ((max>0)&&(
NULL==*p_ramblock)) {
180 cur = min+(max-min)/2;
202static size_t oomtest_fill_postinit(
const size_t minHeap,
const size_t minStack)
204 unsigned int l_numblock;
206 void*
volatile l_reservedheap;
207 void* l_reservedstack;
210 if (
NULL!=_oomblocks[0]) {
213 fprintf (stderr,
"%s:%d oomblocks are already allocated\n", __FILE__,__LINE__);
221 l_reservedstack=alloca(minStack);
222 (void)l_reservedstack;
229 fprintf(stderr,
"%s:%d Failed to reserve minheap bytes\n",__FILE__,__LINE__);
237 l_sum += oomtest_getbiggestblock(&(_oomblocks[l_numblock++]));
239 l_sum += oomtest_getbiggestblock(&(_oomblocks[l_numblock++]));
243 _oomblocks[l_numblock]=
NULL;
248 if (
NULL!=l_reservedheap)
249 free(l_reservedheap);
261static void oomtest_free_postinit()
266 if (
NULL==_oomblocks[0]) {
267 fprintf(stderr,
"%s:%d no blocks to free in oomtest_free.\n",__FILE__,__LINE__);
274 free(_oomblocks[l_i]);
275 _oomblocks[l_i] =
NULL;
281 __asm__ volatile(
"": : :
"memory");
293static size_t oomtest_enable_postinit(
const size_t softlimit)
296 size_t l_softlimit = softlimit;
302 checked_getrlimit(RLIMIT_AS, &limit);
305 if (0==l_softlimit) {
307 l_softlimit = limit.rlim_max;
311 limit.rlim_cur = l_softlimit;
314 if (setrlimit(RLIMIT_AS, &limit) != 0) {
315 fprintf (stderr,
"%s:%d setrlimit(cur=%lu, max=%lu) with errno=%d %s\n",
317 (
unsigned long)limit.rlim_cur, (
unsigned long)limit.rlim_max,
318 errno,strerror(errno));
327 return limit.rlim_cur;
337static size_t oomtest_disable_postinit()
341 if (
NULL!=_oomblocks[0]) {
342 fprintf(stderr,
"%s:%d RAM still allocated while calling oomtest_disable\n",__FILE__,__LINE__);
348 fprintf(stderr,
"%s:%d Impossible to disable oomtest if not previously enabled\n",__FILE__,__LINE__);
353 oomtest_enable_postinit(0);
356 checked_getrlimit(RLIMIT_AS, &limit);
363 return limit.rlim_cur;
371 size_t l_hardlimit = hardlimit;
374 if (
NULL!=_oomblocks[0]) {
375 fprintf(stderr,
"%s:%d Calling oomtest_config with allocated RAM blocks is not allowed.\n",
381 l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
384 checked_getrlimit(RLIMIT_AS, &limit);
385 if (0==l_hardlimit) {
388 l_hardlimit=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
389 }
else if (l_hardlimit>l_avail) {
391 fprintf(stderr,
"%s:%d Requesing a limit %lu bigger than *installed* RAM %lu is not allowed.\n",
393 (
unsigned long)l_hardlimit,(
unsigned long)l_avail);
398 limit.rlim_cur = l_hardlimit;
399 limit.rlim_max = l_hardlimit;
402 if (setrlimit(RLIMIT_AS, &limit) != 0) {
403 fprintf (stderr,
"%s:%d setrlimit(cur=%lu, max=%lu) with errno=%d %s\n",
404 __FILE__,__LINE__, (
unsigned long)limit.rlim_cur,
405 (
unsigned long)limit.rlim_max, errno,strerror(errno));
407 checked_getrlimit(RLIMIT_AS, &limit);
408 fprintf (stderr,
"%s:%d getrlimit() is cur=%lu, max=%lu\n",
409 __FILE__,__LINE__, (
unsigned long)limit.rlim_cur,
410 (
unsigned long)limit.rlim_max);
419 return limit.rlim_max;
#define ASSERT(condition)
Assertion check macro.
#define malloc(size)
Same syntaxt and same behavior than regular malloc function, with memory leaks tracking.
#define free(ptr)
Same syntaxt and same behavior than regular free function, with memory leaks tracking.
void(* oomtest_free)()
Ends a single simple OOM test.
size_t(* oomtest_disable)()
Stops the current oomtest.
#define RAMBLOCKS_MAX
Maximum number of fragmented blocks to allocate.
#define __sync_synchronize
size_t(* oomtest_fill)(const size_t minHeap, const size_t minStack)
Starts an almost OOM single and simple test.
size_t(* oomtest_enable)(const size_t softlimit)
Starts a new oomtest environment or reconfigure the soft limit.
unsigned char oomtest_enabled()
size_t oomtest_config(const size_t hardlimit)
Sets the oomtest helpers hard rlimit and enables the oomtest helper features.