#include <stdlib.h>
#include <string.h>
-#define omp_max_predefined_alloc omp_thread_mem_alloc
+#define omp_max_predefined_alloc ompx_pinned_mem_alloc
/* These macros may be overridden in config/<target>/allocator.c. */
#ifndef MEMSPACE_ALLOC
omp_low_lat_mem_space, /* omp_cgroup_mem_alloc. */
omp_low_lat_mem_space, /* omp_pteam_mem_alloc. */
omp_low_lat_mem_space, /* omp_thread_mem_alloc. */
+ omp_default_mem_space, /* ompx_pinned_mem_alloc. */
};
struct omp_allocator_data
}
else
{
- omp_memspace_handle_t memspace = (allocator_data
- ? allocator_data->memspace
- : predefined_alloc_mapping[allocator]);
- ptr = MEMSPACE_ALLOC (memspace, new_size,
- allocator_data && allocator_data->pinned);
+ omp_memspace_handle_t memspace __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->memspace
+ : predefined_alloc_mapping[allocator]);
+ int pinned __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->pinned
+ : allocator == ompx_pinned_mem_alloc);
+ ptr = MEMSPACE_ALLOC (memspace, new_size, pinned);
if (ptr == NULL)
goto fail;
}
fail:
int fallback = (allocator_data
? allocator_data->fallback
- : allocator == omp_default_mem_alloc
+ : (allocator == omp_default_mem_alloc
+ || allocator == ompx_pinned_mem_alloc)
? omp_atv_null_fb
: omp_atv_default_mem_fb);
switch (fallback)
omp_free (void *ptr, omp_allocator_handle_t allocator)
{
struct omp_mem_header *data;
- omp_memspace_handle_t memspace = omp_default_mem_space;
+ omp_memspace_handle_t memspace __attribute__((unused))
+ = omp_default_mem_space;
int pinned __attribute__((unused)) = false;
if (ptr == NULL)
pinned = allocator_data->pinned;
}
else
- memspace = predefined_alloc_mapping[data->allocator];
+ {
+ memspace = predefined_alloc_mapping[data->allocator];
+ pinned = (data->allocator == ompx_pinned_mem_alloc);
+ }
MEMSPACE_FREE (memspace, data->ptr, data->size, pinned);
}
allocator_data->used_pool_size = used_pool_size;
gomp_mutex_unlock (&allocator_data->lock);
#endif
- ptr = MEMSPACE_CALLOC (allocator_data->memspace, new_size,
- allocator_data->pinned);
+ int pinned __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->pinned
+ : allocator == ompx_pinned_mem_alloc);
+ ptr = MEMSPACE_CALLOC (allocator_data->memspace, new_size, pinned);
if (ptr == NULL)
{
#ifdef HAVE_SYNC_BUILTINS
}
else
{
- omp_memspace_handle_t memspace = (allocator_data
- ? allocator_data->memspace
- : predefined_alloc_mapping[allocator]);
- ptr = MEMSPACE_ALLOC (memspace, new_size,
- allocator_data && allocator_data->pinned);
+ omp_memspace_handle_t memspace __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->memspace
+ : predefined_alloc_mapping[allocator]);
+ int pinned __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->pinned
+ : allocator == ompx_pinned_mem_alloc);
+ ptr = MEMSPACE_CALLOC (memspace, new_size, pinned);
if (ptr == NULL)
goto fail;
}
fail:
int fallback = (allocator_data
? allocator_data->fallback
- : allocator == omp_default_mem_alloc
+ : (allocator == omp_default_mem_alloc
+ || allocator == ompx_pinned_mem_alloc)
? omp_atv_null_fb
: omp_atv_default_mem_fb);
switch (fallback)
gomp_mutex_unlock (&allocator_data->lock);
#endif
if (prev_size)
- new_ptr = MEMSPACE_REALLOC (allocator_data->memspace, data->ptr,
- data->size, new_size,
- (free_allocator_data
- && free_allocator_data->pinned),
- allocator_data->pinned);
+ {
+ int was_pinned __attribute__((unused))
+ = (free_allocator_data
+ ? free_allocator_data->pinned
+ : free_allocator == ompx_pinned_mem_alloc);
+ new_ptr = MEMSPACE_REALLOC (allocator_data->memspace, data->ptr,
+ data->size, new_size, was_pinned,
+ allocator_data->pinned);
+ }
else
new_ptr = MEMSPACE_ALLOC (allocator_data->memspace, new_size,
allocator_data->pinned);
&& (free_allocator_data == NULL
|| free_allocator_data->pool_size == ~(uintptr_t) 0))
{
- omp_memspace_handle_t memspace = (allocator_data
- ? allocator_data->memspace
- : predefined_alloc_mapping[allocator]);
+ omp_memspace_handle_t memspace __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->memspace
+ : predefined_alloc_mapping[allocator]);
+ int was_pinned __attribute__((unused))
+ = (free_allocator_data
+ ? free_allocator_data->pinned
+ : free_allocator == ompx_pinned_mem_alloc);
+ int pinned __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->pinned
+ : allocator == ompx_pinned_mem_alloc);
new_ptr = MEMSPACE_REALLOC (memspace, data->ptr, data->size, new_size,
- (free_allocator_data
- && free_allocator_data->pinned),
- allocator_data && allocator_data->pinned);
+ was_pinned, pinned);
if (new_ptr == NULL)
goto fail;
ret = (char *) new_ptr + sizeof (struct omp_mem_header);
}
else
{
- omp_memspace_handle_t memspace
+ omp_memspace_handle_t memspace __attribute__((unused))
= (allocator_data
? allocator_data->memspace
: predefined_alloc_mapping[allocator]);
- new_ptr = MEMSPACE_ALLOC (memspace, new_size,
- allocator_data && allocator_data->pinned);
+ int pinned __attribute__((unused))
+ = (allocator_data
+ ? allocator_data->pinned
+ : allocator == ompx_pinned_mem_alloc);
+ new_ptr = MEMSPACE_ALLOC (memspace, new_size, pinned);
if (new_ptr == NULL)
goto fail;
}
fail:
int fallback = (allocator_data
? allocator_data->fallback
- : allocator == omp_default_mem_alloc
+ : (allocator == omp_default_mem_alloc
+ || allocator == ompx_pinned_mem_alloc)
? omp_atv_null_fb
: omp_atv_default_mem_fb);
switch (fallback)
--- /dev/null
+/* { dg-do run } */
+
+/* Test that ompx_pinned_mem_alloc fails correctly. */
+
+#ifdef __linux__
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+#include <sys/resource.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 ();
+}
+
+void
+set_pin_limit (int size)
+{
+ struct rlimit limit;
+ if (getrlimit (RLIMIT_MEMLOCK, &limit))
+ abort ();
+ limit.rlim_cur = (limit.rlim_max < size ? limit.rlim_max : size);
+ if (setrlimit (RLIMIT_MEMLOCK, &limit))
+ abort ();
+}
+#else
+int
+get_pinned_mem ()
+{
+ return 0;
+}
+
+void
+set_pin_limit ()
+{
+}
+#endif
+
+#include <omp.h>
+
+/* This should be large enough to cover multiple pages. */
+#define SIZE 10000*1024
+
+int
+main ()
+{
+ /* Ensure that the limit is smaller than the allocation. */
+ set_pin_limit (SIZE/2);
+
+ // Sanity check
+ if (get_pinned_mem () != 0)
+ abort ();
+
+ // Should fail
+ void *p = omp_alloc (SIZE, ompx_pinned_mem_alloc);
+ if (p)
+ abort ();
+
+ // Should fail
+ p = omp_calloc (1, SIZE, ompx_pinned_mem_alloc);
+ if (p)
+ abort ();
+
+ // Should fail to realloc
+ void *notpinned = omp_alloc (SIZE, omp_default_mem_alloc);
+ p = omp_realloc (notpinned, SIZE, ompx_pinned_mem_alloc, omp_default_mem_alloc);
+ if (!notpinned || p)
+ abort ();
+
+ // No memory should have been pinned
+ int amount = get_pinned_mem ();
+ if (amount != 0)
+ abort ();
+
+ return 0;
+}