BT_FN_VOID_CONST_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ERROR, "GOMP_error",
BT_FN_VOID_CONST_PTR_SIZE, ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
-DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ENABLE_PINNED_MODE,
- "GOMP_enable_pinned_mode",
- BT_FN_VOID, ATTR_NOTHROW_LIST)
input_location = saved_location;
}
-/* Emit a constructor function to enable -foffload-memory=pinned
- at runtime. Libgomp handles the OS mode setting, but we need to trigger
- it by calling GOMP_enable_pinned mode before the program proper runs. */
-
-static void
-omp_enable_pinned_mode ()
-{
- static bool visited = false;
- if (visited)
- return;
- visited = true;
-
- /* Create a new function like this:
-
- static void __attribute__((constructor))
- __set_pinned_mode ()
- {
- GOMP_enable_pinned_mode ();
- }
- */
-
- tree name = get_identifier ("__set_pinned_mode");
- tree voidfntype = build_function_type_list (void_type_node, NULL_TREE);
- tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name, voidfntype);
-
- TREE_STATIC (decl) = 1;
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 0;
- TREE_PUBLIC (decl) = 0;
- DECL_UNINLINABLE (decl) = 1;
- DECL_EXTERNAL (decl) = 0;
- DECL_CONTEXT (decl) = NULL_TREE;
- DECL_INITIAL (decl) = make_node (BLOCK);
- BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
- DECL_STATIC_CONSTRUCTOR (decl) = 1;
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("constructor"),
- NULL_TREE, NULL_TREE);
-
- tree t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
- void_type_node);
- DECL_ARTIFICIAL (t) = 1;
- DECL_IGNORED_P (t) = 1;
- DECL_CONTEXT (t) = decl;
- DECL_RESULT (decl) = t;
-
- push_struct_function (decl);
- init_tree_ssa (cfun);
-
- tree calldecl = builtin_decl_explicit (BUILT_IN_GOMP_ENABLE_PINNED_MODE);
- gcall *call = gimple_build_call (calldecl, 0);
-
- gimple_seq seq = NULL;
- gimple_seq_add_stmt (&seq, call);
- gimple_set_body (decl, gimple_build_bind (NULL_TREE, seq, NULL));
-
- cfun->function_end_locus = UNKNOWN_LOCATION;
- cfun->curr_properties |= PROP_gimple_any;
- pop_cfun ();
- cgraph_node::add_new_function (decl, true);
-}
-
/* Main entry point. */
static unsigned int
for (auto task_stmt : task_cpyfns)
finalize_task_copyfn (task_stmt);
task_cpyfns.release ();
-
- if (flag_offload_memory == OFFLOAD_MEMORY_PINNED)
- omp_enable_pinned_mode ();
-
return 0;
}
# include <inttypes.h> /* For PRIu64. */
#endif
-static bool always_pinned_mode = false;
-
-/* This function is called by the compiler when -foffload-memory=pinned
- is used. */
-
-void
-GOMP_enable_pinned_mode ()
-{
- if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)
- gomp_error ("failed to pin all memory (ulimit too low?)");
- else
- always_pinned_mode = true;
-}
-
static void *
linux_memspace_alloc (omp_memspace_handle_t memspace, size_t size, int pin)
{
(void)memspace;
- /* Explicit pinning may not be required. */
- pin = pin && !always_pinned_mode;
-
if (pin)
{
/* Note that mmap always returns zeroed memory and is therefore also a
static void *
linux_memspace_calloc (omp_memspace_handle_t memspace, size_t size, int pin)
{
- /* Explicit pinning may not be required. */
- pin = pin && !always_pinned_mode;
-
if (pin)
return linux_memspace_alloc (memspace, size, pin);
else
{
(void)memspace;
- /* Explicit pinning may not be required. */
- pin = pin && !always_pinned_mode;
-
if (pin)
munmap (addr, size);
else
linux_memspace_realloc (omp_memspace_handle_t memspace, void *addr,
size_t oldsize, size_t size, int oldpin, int pin)
{
- /* Explicit pinning may not be required. */
- pin = pin && !always_pinned_mode;
-
if (oldpin && pin)
{
void *newaddr = mremap (addr, oldsize, size, MREMAP_MAYMOVE);
global:
GOMP_alloc;
GOMP_free;
- GOMP_enable_pinned_mode;
} GOMP_5.0;
GOMP_5.1 {
+++ /dev/null
-/* { dg-do run } */
-/* { dg-additional-options "-foffload-memory=pinned" } */
-/* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */
-
-#if __cplusplus
-#define EXTERNC extern "C"
-#else
-#define EXTERNC
-#endif
-
-/* Intercept the libgomp initialization call to check it happens. */
-
-int good = 0;
-
-EXTERNC void
-GOMP_enable_pinned_mode ()
-{
- good = 1;
-}
-
-int
-main ()
-{
- if (!good)
- __builtin_exit (1);
-
- return 0;
-}
+++ /dev/null
-/* { dg-do run } */
-/* { dg-additional-options "-foffload-memory=pinned" } */
-
-/* { dg-skip-if "Pinning not implemented on this host" { ! *-*-linux-gnu* } } */
-
-/* Test that -foffload-memory=pinned works. */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef __linux__
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <sys/mman.h>
-
-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
-int
-get_pinned_mem ()
-{
- return 0;
-}
-
-#define mlockall(...) 0
-#endif
-
-#include <omp.h>
-
-int
-main ()
-{
- // Sanity check
- if (get_pinned_mem () == 0)
- {
- /* -foffload-memory=pinned has failed, but maybe that's because
- isufficient pinned memory was available. */
- if (mlockall (MCL_CURRENT | MCL_FUTURE) == 0)
- abort ();
- }
-
- return 0;
-}