Created
December 16, 2012 19:47
-
-
Save mazgi/4312037 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Author
mazgi
commented
Dec 16, 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