/* -*- mode: C; mode: folding; fill-column: 70; -*- *//* Copyright 2010, Georgia Institute of Technology, USA. *//* See COPYING for license. */#include "compat.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <errno.h>#include <limits.h>#include <unistd.h>#include <time.h>#include <fcntl.h>#include <sys/types.h>#include <sys/mman.h> #if !defined(MAP_HUGETLB)#define MAP_HUGETLB 0#endif#if !defined(MAP_POPULATE)#define MAP_POPULATE 0#endif#if !defined(MAP_NOSYNC)#define MAP_NOSYNC 0#endif #if 0/* Included in the generator. */void *xmalloc (size_t sz){ void *out; if (!(out = malloc (sz))) { perror ("malloc failed"); abort (); } return out;}#endif #if defined(__MTA__)||defined(USE_MMAP_LARGE)||defined(USE_MMAP_LARGE_EXT)#define MAX_LARGE 32static int n_large_alloc = 0;static struct { void * p; size_t sz; int fd;} large_alloc[MAX_LARGE]; static int installed_handler = 0;static void (*old_abort_handler)(int); static voidexit_handler (void){ int k; for (k = 0; k < n_large_alloc; ++k) { if (large_alloc[k].p) munmap (large_alloc[k].p, large_alloc[k].sz); if (large_alloc[k].fd >= 0) close (large_alloc[k].fd); large_alloc[k].p = NULL; large_alloc[k].fd = -1; }} static voidabort_handler (int passthrough){ exit_handler (); if (old_abort_handler) old_abort_handler (passthrough);}#endif #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)#define MAP_ANONYMOUS MAP_ANON#endif void *xmalloc_large (size_t sz){#if defined(__MTA__)||defined(USE_MMAP_LARGE) void *out; int which = n_large_alloc++; if (n_large_alloc > MAX_LARGE) { fprintf (stderr, "Too many large allocations. %d %d\n", n_large_alloc, MAX_LARGE); --n_large_alloc; abort (); } large_alloc[which].p = NULL; large_alloc[which].fd = -1; out = mmap (NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB|MAP_POPULATE, 0, 0); if (out == MAP_FAILED || !out) { perror ("mmap failed"); abort (); } large_alloc[which].p = out; large_alloc[which].sz = sz; return out;#else return xmalloc (sz);#endif} voidxfree_large (void *p){#if defined(__MTA__)||defined(USE_MMAP_LARGE)||defined(USE_MMAP_LARGE_EXT) int k, found = 0; for (k = 0; k < n_large_alloc; ++k) { if (p == large_alloc[k].p) { munmap (p, large_alloc[k].sz); large_alloc[k].p = NULL; if (large_alloc[k].fd >= 0) { close (large_alloc[k].fd); large_alloc[k].fd = -1; } found = 1; break; } } if (found) { --n_large_alloc; for (; k < n_large_alloc; ++k) large_alloc[k] = large_alloc[k+1]; } else free (p);#else free (p);#endif} void *xmalloc_large_ext (size_t sz){#if !defined(__MTA__)&&defined(USE_MMAP_LARGE_EXT) char extname[PATH_MAX+1]; char *tmppath; void *out; int fd, which; if (getenv ("TMPDIR")) tmppath = getenv ("TMPDIR"); else if (getenv ("TEMPDIR")) tmppath = getenv ("TEMPDIR"); else tmppath = "/tmp"; sprintf (extname, "%s/graph500-ext-XXXXXX", tmppath); which = n_large_alloc++; if (n_large_alloc > MAX_LARGE) { fprintf (stderr, "Out of large allocations.\n"); abort (); } large_alloc[which].p = 0; large_alloc[which].fd = -1; fd = mkstemp (extname); if (fd < 0) { perror ("xmalloc_large_ext failed to make a file"); abort (); } if (unlink (extname)) { perror ("UNLINK FAILED!"); goto errout; } #if _XOPEN_SOURCE >= 500 if (pwrite (fd, &fd, sizeof (fd), sz - sizeof(fd)) != sizeof (fd)) { perror ("resizing pwrite failed"); goto errout; }#else if (lseek (fd, sz - sizeof(fd), SEEK_SET) < 0) { perror ("lseek failed"); goto errout; } if (write (fd, &fd, sizeof(fd)) != sizeof (fd)) { perror ("resizing write failed"); goto errout; }#endif fcntl (fd, F_SETFD, O_ASYNC); out = mmap (NULL, sz, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE|MAP_NOSYNC, fd, 0); if (MAP_FAILED == out || !out) { perror ("mmap ext failed"); goto errout; } if (!installed_handler) { installed_handler = 1; if (atexit (exit_handler)) { perror ("failed to install exit handler"); goto errout; } old_abort_handler = signal (SIGABRT, abort_handler); if (SIG_ERR == old_abort_handler) { perror ("failed to install cleanup handler"); goto errout; } } large_alloc[which].p = out; large_alloc[which].sz = sz; large_alloc[which].fd = fd; return out; errout: if (fd >= 0) close (fd); abort ();#else return xmalloc_large (sz);#endif} /*voidmark_large_unused (void *p){#if !defined(__MTA__) int k; for (k = 0; k < n_large_alloc; ++k) if (p == large_alloc[k].p) posix_madvise (large_alloc[k].p, large_alloc[k].sz, POSIX_MADV_DONTNEED);#endif} voidmark_large_willuse (void *p){#if !defined(__MTA__) int k; for (k = 0; k < n_large_alloc; ++k) if (p == large_alloc[k].p) posix_madvise (large_alloc[k].p, large_alloc[k].sz, POSIX_MADV_WILLNEED);#endif}*/
/* -*- mode: C; mode: folding; fill-column: 70; -*- */
/* Copyright 2010, Georgia Institute of Technology, USA. */
/* See COPYING for license. */
#include "compat.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#if !defined(MAP_HUGETLB)
#define MAP_HUGETLB 0
#endif
#if !defined(MAP_POPULATE)
#define MAP_POPULATE 0
#endif
#if !defined(MAP_NOSYNC)
#define MAP_NOSYNC 0
#endif
#if 0
/* Included in the generator. */
void *
xmalloc (size_t sz)
{
void *out;
if (!(out = malloc (sz))) {
perror ("malloc failed");
abort ();
}
return out;
}
#endif
#if defined(__MTA__)||defined(USE_MMAP_LARGE)||defined(USE_MMAP_LARGE_EXT)
#define MAX_LARGE 32
static int n_large_alloc = 0;
static struct {
void * p;
size_t sz;
int fd;
} large_alloc[MAX_LARGE];
static int installed_handler = 0;
static void (*old_abort_handler)(int);
static void
exit_handler (void)
{
int k;
for (k = 0; k < n_large_alloc; ++k) {
if (large_alloc[k].p)
munmap (large_alloc[k].p, large_alloc[k].sz);
if (large_alloc[k].fd >= 0)
close (large_alloc[k].fd);
large_alloc[k].p = NULL;
large_alloc[k].fd = -1;
}
}
static void
abort_handler (int passthrough)
{
exit_handler ();
if (old_abort_handler) old_abort_handler (passthrough);
}
#endif
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
void *
xmalloc_large (size_t sz)
{
#if defined(__MTA__)||defined(USE_MMAP_LARGE)
void *out;
int which = n_large_alloc++;
if (n_large_alloc > MAX_LARGE) {
fprintf (stderr, "Too many large allocations. %d %d\n", n_large_alloc, MAX_LARGE);
--n_large_alloc;
abort ();
}
large_alloc[which].p = NULL;
large_alloc[which].fd = -1;
out = mmap (NULL, sz, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB|MAP_POPULATE, 0, 0);
if (out == MAP_FAILED || !out) {
perror ("mmap failed");
abort ();
}
large_alloc[which].p = out;
large_alloc[which].sz = sz;
return out;
#else
return xmalloc (sz);
#endif
}
void
xfree_large (void *p)
{
#if defined(__MTA__)||defined(USE_MMAP_LARGE)||defined(USE_MMAP_LARGE_EXT)
int k, found = 0;
for (k = 0; k < n_large_alloc; ++k) {
if (p == large_alloc[k].p) {
munmap (p, large_alloc[k].sz);
large_alloc[k].p = NULL;
if (large_alloc[k].fd >= 0) {
close (large_alloc[k].fd);
large_alloc[k].fd = -1;
}
found = 1;
break;
}
}
if (found) {
--n_large_alloc;
for (; k < n_large_alloc; ++k)
large_alloc[k] = large_alloc[k+1];
} else
free (p);
#else
free (p);
#endif
}
void *
xmalloc_large_ext (size_t sz)
{
#if !defined(__MTA__)&&defined(USE_MMAP_LARGE_EXT)
char extname[PATH_MAX+1];
char *tmppath;
void *out;
int fd, which;
if (getenv ("TMPDIR"))
tmppath = getenv ("TMPDIR");
else if (getenv ("TEMPDIR"))
tmppath = getenv ("TEMPDIR");
else
tmppath = "/tmp";
sprintf (extname, "%s/graph500-ext-XXXXXX", tmppath);
which = n_large_alloc++;
if (n_large_alloc > MAX_LARGE) {
fprintf (stderr, "Out of large allocations.\n");
abort ();
}
large_alloc[which].p = 0;
large_alloc[which].fd = -1;
fd = mkstemp (extname);
if (fd < 0) {
perror ("xmalloc_large_ext failed to make a file");
abort ();
}
if (unlink (extname)) {
perror ("UNLINK FAILED!");
goto errout;
}
#if _XOPEN_SOURCE >= 500
if (pwrite (fd, &fd, sizeof (fd), sz - sizeof(fd)) != sizeof (fd)) {
perror ("resizing pwrite failed");
goto errout;
}
#else
if (lseek (fd, sz - sizeof(fd), SEEK_SET) < 0) {
perror ("lseek failed");
goto errout;
}
if (write (fd, &fd, sizeof(fd)) != sizeof (fd)) {
perror ("resizing write failed");
goto errout;
}
#endif
fcntl (fd, F_SETFD, O_ASYNC);
out = mmap (NULL, sz, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_POPULATE|MAP_NOSYNC, fd, 0);
if (MAP_FAILED == out || !out) {
perror ("mmap ext failed");
goto errout;
}
if (!installed_handler) {
installed_handler = 1;
if (atexit (exit_handler)) {
perror ("failed to install exit handler");
goto errout;
}
old_abort_handler = signal (SIGABRT, abort_handler);
if (SIG_ERR == old_abort_handler) {
perror ("failed to install cleanup handler");
goto errout;
}
}
large_alloc[which].p = out;
large_alloc[which].sz = sz;
large_alloc[which].fd = fd;
return out;
errout:
if (fd >= 0) close (fd);
abort ();
#else
return xmalloc_large (sz);
#endif
}
/*
void
mark_large_unused (void *p)
{
#if !defined(__MTA__)
int k;
for (k = 0; k < n_large_alloc; ++k)
if (p == large_alloc[k].p)
posix_madvise (large_alloc[k].p, large_alloc[k].sz, POSIX_MADV_DONTNEED);
#endif
}
void
mark_large_willuse (void *p)
{
#if !defined(__MTA__)
int k;
for (k = 0; k < n_large_alloc; ++k)
if (p == large_alloc[k].p)
posix_madvise (large_alloc[k].p, large_alloc[k].sz, POSIX_MADV_WILLNEED);
#endif
}
*/