b38a4bd102
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that fixes an omp_alloc bug which is hard to test for - if the first allocator fails but has a larger alignment trait and has a fallback allocator, either the default behavior or a user fallback, then the extra alignment will be used even in the fallback allocation, rather than just starting with whatever alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc). Jonathan's comment on IRC this morning made me realize that I should add alloc_align attributes to 2 of the prototypes and I still need to add testsuite coverage for omp_realloc, will do that in a follow-up. 2021-09-30 Jakub Jelinek <jakub@redhat.com> * omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc, omp_realloc): New prototypes. (omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free) attribute. * allocator.c: Include string.h. (omp_aligned_alloc): No longer static, add ialias. Add new_alignment variable and use it instead of alignment so that when retrying the old alignment is used again. Don't retry if new alignment is the same as old alignment, unless allocator had pool size. (omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call. (omp_aligned_calloc, omp_calloc, omp_realloc): New functions. * libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc, omp_aligned_calloc and omp_realloc. * testsuite/libgomp.c-c++-common/alloc-4.c (main): Add omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests. * testsuite/libgomp.c-c++-common/alloc-5.c: New test. * testsuite/libgomp.c-c++-common/alloc-6.c: New test. * testsuite/libgomp.c-c++-common/alloc-7.c: New test. * testsuite/libgomp.c-c++-common/alloc-8.c: New test.
185 lines
5.2 KiB
C
185 lines
5.2 KiB
C
#include <omp.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
const omp_alloctrait_t traits2[]
|
|
= { { omp_atk_alignment, 16 },
|
|
{ omp_atk_sync_hint, omp_atv_default },
|
|
{ omp_atk_access, omp_atv_default },
|
|
{ omp_atk_pool_size, 1024 },
|
|
{ omp_atk_fallback, omp_atv_default_mem_fb },
|
|
{ omp_atk_partition, omp_atv_environment } };
|
|
omp_alloctrait_t traits3[]
|
|
= { { omp_atk_sync_hint, omp_atv_uncontended },
|
|
{ omp_atk_alignment, 32 },
|
|
{ omp_atk_access, omp_atv_all },
|
|
{ omp_atk_pool_size, 512 },
|
|
{ omp_atk_fallback, omp_atv_allocator_fb },
|
|
{ omp_atk_fb_data, 0 },
|
|
{ omp_atk_partition, omp_atv_default } };
|
|
const omp_alloctrait_t traits4[]
|
|
= { { omp_atk_alignment, 128 },
|
|
{ omp_atk_pool_size, 1024 },
|
|
{ omp_atk_fallback, omp_atv_null_fb } };
|
|
|
|
int
|
|
main ()
|
|
{
|
|
int *volatile p = (int *) omp_aligned_calloc (sizeof (int), 3, sizeof (int), omp_default_mem_alloc);
|
|
int *volatile q;
|
|
int *volatile r;
|
|
int i;
|
|
omp_alloctrait_t traits[3]
|
|
= { { omp_atk_alignment, 64 },
|
|
{ omp_atk_fallback, omp_atv_null_fb },
|
|
{ omp_atk_pool_size, 4096 } };
|
|
omp_allocator_handle_t a, a2;
|
|
|
|
if ((((uintptr_t) p) % __alignof (int)) != 0 || p[0] || p[1] || p[2])
|
|
abort ();
|
|
p[0] = 1;
|
|
p[1] = 2;
|
|
p[2] = 3;
|
|
omp_free (p, omp_default_mem_alloc);
|
|
p = (int *) omp_aligned_calloc (2 * sizeof (int), 1, 2 * sizeof (int), omp_default_mem_alloc);
|
|
if ((((uintptr_t) p) % (2 * sizeof (int))) != 0 || p[0] || p[1])
|
|
abort ();
|
|
p[0] = 1;
|
|
p[1] = 2;
|
|
omp_free (p, omp_null_allocator);
|
|
omp_set_default_allocator (omp_default_mem_alloc);
|
|
p = (int *) omp_aligned_calloc (1, 1, sizeof (int), omp_null_allocator);
|
|
if ((((uintptr_t) p) % __alignof (int)) != 0 || p[0])
|
|
abort ();
|
|
p[0] = 3;
|
|
omp_free (p, omp_get_default_allocator ());
|
|
|
|
a = omp_init_allocator (omp_default_mem_space, 3, traits);
|
|
if (a == omp_null_allocator)
|
|
abort ();
|
|
p = (int *) omp_aligned_calloc (32, 3, 1024, a);
|
|
if ((((uintptr_t) p) % 64) != 0)
|
|
abort ();
|
|
for (i = 0; i < 3072 / sizeof (int); i++)
|
|
if (p[i])
|
|
abort ();
|
|
p[0] = 1;
|
|
p[3071 / sizeof (int)] = 2;
|
|
if (omp_aligned_calloc (8, 192, 16, a) != NULL)
|
|
abort ();
|
|
omp_free (p, a);
|
|
p = (int *) omp_aligned_calloc (128, 6, 512, a);
|
|
if ((((uintptr_t) p) % 128) != 0)
|
|
abort ();
|
|
for (i = 0; i < 3072 / sizeof (int); i++)
|
|
if (p[i])
|
|
abort ();
|
|
p[0] = 3;
|
|
p[3071 / sizeof (int)] = 4;
|
|
omp_free (p, omp_null_allocator);
|
|
omp_set_default_allocator (a);
|
|
if (omp_get_default_allocator () != a)
|
|
abort ();
|
|
p = (int *) omp_aligned_calloc (64, 12, 256, omp_null_allocator);
|
|
for (i = 0; i < 3072 / sizeof (int); i++)
|
|
if (p[i])
|
|
abort ();
|
|
if (omp_aligned_calloc (8, 128, 24, omp_null_allocator) != NULL)
|
|
abort ();
|
|
omp_free (p, a);
|
|
omp_destroy_allocator (a);
|
|
|
|
a = omp_init_allocator (omp_default_mem_space,
|
|
sizeof (traits2) / sizeof (traits2[0]),
|
|
traits2);
|
|
if (a == omp_null_allocator)
|
|
abort ();
|
|
if (traits3[5].key != omp_atk_fb_data)
|
|
abort ();
|
|
traits3[5].value = (uintptr_t) a;
|
|
a2 = omp_init_allocator (omp_default_mem_space,
|
|
sizeof (traits3) / sizeof (traits3[0]),
|
|
traits3);
|
|
if (a2 == omp_null_allocator)
|
|
abort ();
|
|
p = (int *) omp_aligned_calloc (4, 5, 84, a2);
|
|
for (i = 0; i < 420 / sizeof (int); i++)
|
|
if (p[i])
|
|
abort ();
|
|
if ((((uintptr_t) p) % 32) != 0)
|
|
abort ();
|
|
p[0] = 5;
|
|
p[419 / sizeof (int)] = 6;
|
|
q = (int *) omp_aligned_calloc (8, 24, 32, a2);
|
|
if ((((uintptr_t) q) % 16) != 0)
|
|
abort ();
|
|
for (i = 0; i < 768 / sizeof (int); i++)
|
|
if (q[i])
|
|
abort ();
|
|
q[0] = 7;
|
|
q[767 / sizeof (int)] = 8;
|
|
r = (int *) omp_aligned_calloc (8, 64, 8, a2);
|
|
if ((((uintptr_t) r) % 8) != 0)
|
|
abort ();
|
|
for (i = 0; i < 512 / sizeof (int); i++)
|
|
if (r[i])
|
|
abort ();
|
|
r[0] = 9;
|
|
r[511 / sizeof (int)] = 10;
|
|
omp_free (p, omp_null_allocator);
|
|
omp_free (q, a2);
|
|
omp_free (r, omp_null_allocator);
|
|
omp_destroy_allocator (a2);
|
|
omp_destroy_allocator (a);
|
|
|
|
a = omp_init_allocator (omp_default_mem_space,
|
|
sizeof (traits4) / sizeof (traits4[0]),
|
|
traits4);
|
|
if (a == omp_null_allocator)
|
|
abort ();
|
|
if (traits3[5].key != omp_atk_fb_data)
|
|
abort ();
|
|
traits3[5].value = (uintptr_t) a;
|
|
a2 = omp_init_allocator (omp_default_mem_space,
|
|
sizeof (traits3) / sizeof (traits3[0]),
|
|
traits3);
|
|
if (a2 == omp_null_allocator)
|
|
abort ();
|
|
omp_set_default_allocator (a2);
|
|
#ifdef __cplusplus
|
|
p = static_cast <int *> (omp_aligned_calloc (4, 21, 20));
|
|
#else
|
|
p = (int *) omp_aligned_calloc (4, 21, 20, omp_null_allocator);
|
|
#endif
|
|
if ((((uintptr_t) p) % 32) != 0)
|
|
abort ();
|
|
for (i = 0; i < 420 / sizeof (int); i++)
|
|
if (p[i])
|
|
abort ();
|
|
p[0] = 5;
|
|
p[419 / sizeof (int)] = 6;
|
|
q = (int *) omp_aligned_calloc (64, 12, 64, omp_null_allocator);
|
|
if ((((uintptr_t) q) % 128) != 0)
|
|
abort ();
|
|
for (i = 0; i < 768 / sizeof (int); i++)
|
|
if (q[i])
|
|
abort ();
|
|
q[0] = 7;
|
|
q[767 / sizeof (int)] = 8;
|
|
if (omp_aligned_calloc (8, 24, 32, omp_null_allocator) != NULL)
|
|
abort ();
|
|
#ifdef __cplusplus
|
|
omp_free (p);
|
|
omp_free (q);
|
|
omp_free (NULL);
|
|
#else
|
|
omp_free (p, omp_null_allocator);
|
|
omp_free (q, omp_null_allocator);
|
|
omp_free (NULL, omp_null_allocator);
|
|
#endif
|
|
omp_free (NULL, omp_null_allocator);
|
|
omp_destroy_allocator (a2);
|
|
omp_destroy_allocator (a);
|
|
return 0;
|
|
}
|