Skip to content

Instantly share code, notes, and snippets.

@mazgi
Created December 16, 2012 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mazgi/4312037 to your computer and use it in GitHub Desktop.
Save mazgi/4312037 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
static const long MiB = 1024 * 1024;
int
digit (long value)
{
int result = 1;
if (value < 0)
{
value *= -1;
result++;
}
while ((value /= 10) > 0)
result++;
return result;
}
void
avoid_oomkiller (void)
{
char path[512] = { '\0' };
snprintf (path, 512 - 1, "/proc/%d/oom_adj", getpid ());
FILE *fp;
if ((fp = fopen (path, "w")))
{
fputs ("-17\n", fp);
fclose (fp);
printf ("Write -17 to %s.\n", path);
}
else
{
printf ("Cannot open [%s]:%4d\n", path, __LINE__);
}
}
int
main (int argc, char *argv[])
{
avoid_oomkiller ();
long bytes = 0;
int result = 0;
while ((result = getopt (argc, argv, "k:m:g:")) != -1)
{
long unit = 1;
switch (result)
{
case 'g':
unit *= 1024;
case 'm':
unit *= 1024;
case 'k':
unit *= 1024;
errno = 0;
long linteger = strtol (optarg, NULL, 10);
if (errno == 0)
unit *= linteger;
break;
case ':':
case '?':
default:
break;
}
bytes += unit;
}
char *fmt = NULL;
char **allocated = NULL;
size_t length = bytes / MiB + 1;
allocated = calloc (length, sizeof (char *));
if (allocated == NULL)
{
printf ("Cannot allocate memory:%4d\n", __LINE__);
goto dealloc;
}
const char meta_fmt[] = "Allocating [%%0%dld/%%%dld] bytes... ";
const int d = digit (bytes);
const size_t fmt_length = strlen (meta_fmt) + (d * 2);
fmt = calloc (fmt_length + 1 /* strlen("\0") */ , sizeof (char));
if (fmt == NULL)
{
printf ("Cannot allocate memory:%4d\n", __LINE__);
goto dealloc;
}
snprintf (fmt, fmt_length, meta_fmt, d, d);
char *first_msg =
calloc (fmt_length + 1 /* strlen("\0") */ , sizeof (char));
if (first_msg == NULL)
{
printf ("Cannot allocate memory:%4d\n", __LINE__);
goto dealloc;
}
snprintf (first_msg, fmt_length, fmt, 0, bytes);
const int msg_length = strlen (first_msg);
printf ("%s", first_msg);
free (first_msg);
for (long i = 0; i <= bytes; i += 1024)
{
const size_t index = i / MiB;
char *ptr = (char *) realloc (allocated[index], i * sizeof (char));
if (ptr == NULL)
{
printf ("Cannot allocate memory:%4d\n", __LINE__);
goto dealloc;
}
memset (ptr, 'x', i * sizeof (char));
for (int j = 0; j < msg_length; j++)
printf ("\b");
printf (fmt, i, bytes);
allocated[index] = ptr;
}
puts ("done.");
puts ("Press enter to free.");
getchar ();
dealloc:
free (fmt);
for (size_t i = 0; i < length; i++)
free (allocated[i]);
free (allocated);
puts ("Released.");
return 0;
}
@mazgi
Copy link
Author

mazgi commented Dec 16, 2012

[root@PortEllen] # gcc -W -Wall -std=gnu99 -o allocator allocator.c
[root@PortEllen] # valgrind --tool=memcheck --leak-check=yes ./allocator -k2
==16114== Memcheck, a memory error detector
==16114== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==16114== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==16114== Command: ./allocator -k2
==16114== 
Write -17 to /proc/16114/oom_adj.
Allocating [2048/2048] bytes... done.
Press enter to free.

Released.
==16114== 
==16114== HEAP SUMMARY:
==16114==     in use at exit: 0 bytes in 0 blocks
==16114==   total heap usage: 6 allocs, 6 frees, 25,236 bytes allocated
==16114== 
==16114== All heap blocks were freed -- no leaks are possible
==16114== 
==16114== For counts of detected and suppressed errors, rerun with: -v
==16114== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

@mazgi
Copy link
Author

mazgi commented Dec 17, 2012

[root@PortEllen] # valgrind --tool=memcheck --leak-check=yes ./allocator -k2
==15999== Memcheck, a memory error detector
==15999== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==15999== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==15999== Command: ./allocator -k2
==15999== 
Write -17 to /proc/15999/oom_adj.
Allocating [2048/2048] bytes... done.
Press enter to free.

Released.
==15999== 
==15999== HEAP SUMMARY:
==15999==     in use at exit: 0 bytes in 0 blocks
==15999==   total heap usage: 7 allocs, 7 frees, 3,740 bytes allocated
==15999== 
==15999== All heap blocks were freed -- no leaks are possible
==15999== 
==15999== For counts of detected and suppressed errors, rerun with: -v
==15999== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment