/* { dg-do run } */ /* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */ /* Test that ompx_gnu_pinned_mem_alloc works. */ #include #include #ifdef __linux__ #include #include #include #include #define PAGE_SIZE sysconf(_SC_PAGESIZE) #define CHECK_SIZE(SIZE) { \ struct rlimit limit; \ if (getrlimit (RLIMIT_MEMLOCK, &limit) \ || limit.rlim_cur <= SIZE) \ { \ fprintf (stderr, "insufficient lockable memory; please increase ulimit\n"); \ abort (); \ } \ } int get_pinned_mem () { int pid = getpid (); char buf[100]; sprintf (buf, "/proc/%d/status", pid); FILE *proc = fopen (buf, "r"); if (!proc) abort (); while (fgets (buf, 100, proc)) { int val; if (sscanf (buf, "VmLck: %d", &val)) { fclose (proc); return val; } } abort (); } #else #error "OS unsupported" #endif static void verify0 (char *p, size_t s) { for (size_t i = 0; i < s; ++i) if (p[i] != 0) abort (); } #include int main () { /* Allocate at least a page each time, allowing space for overhead, but stay within the ulimit. */ const int SIZE = PAGE_SIZE - 128; CHECK_SIZE (SIZE * 5); // Sanity check if (get_pinned_mem () != 0) abort (); void *p = omp_alloc (SIZE, ompx_gnu_pinned_mem_alloc); if (!p) abort (); int amount = get_pinned_mem (); if (amount == 0) abort (); p = omp_realloc (p, SIZE * 2, ompx_gnu_pinned_mem_alloc, ompx_gnu_pinned_mem_alloc); int amount2 = get_pinned_mem (); if (amount2 <= amount) abort (); /* SIZE*2 ensures that it doesn't slot into the space possibly vacated by realloc. */ p = omp_calloc (1, SIZE * 2, ompx_gnu_pinned_mem_alloc); if (get_pinned_mem () <= amount2) abort (); verify0 (p, SIZE * 2); return 0; }