Index: openmp/trunk/runtime/src/dllexports =================================================================== --- openmp/trunk/runtime/src/dllexports +++ openmp/trunk/runtime/src/dllexports @@ -396,6 +396,7 @@ __kmpc_taskloop 266 %endif %endif +kmpc_aligned_malloc 265 # User API entry points that have both lower- and upper- case versions for Fortran. # Number for lowercase version is indicated. Number for uppercase is obtained by adding 1000. @@ -448,6 +449,7 @@ kmp_set_stacksize_s 744 kmp_get_stacksize_s 745 kmp_set_defaults 746 +kmp_aligned_malloc 747 kmp_set_warnings_on 779 kmp_set_warnings_off 780 Index: openmp/trunk/runtime/src/include/30/omp.h.var =================================================================== --- openmp/trunk/runtime/src/include/30/omp.h.var +++ openmp/trunk/runtime/src/include/30/omp.h.var @@ -141,6 +141,7 @@ extern int __KAI_KMPC_CONVENTION kmp_get_affinity_mask_proc (int, kmp_affinity_mask_t *); extern void * __KAI_KMPC_CONVENTION kmp_malloc (size_t); + extern void * __KAI_KMPC_CONVENTION kmp_aligned_malloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_calloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_realloc (void *, size_t); extern void __KAI_KMPC_CONVENTION kmp_free (void *); Index: openmp/trunk/runtime/src/include/30/omp_lib.h.var =================================================================== --- openmp/trunk/runtime/src/include/30/omp_lib.h.var +++ openmp/trunk/runtime/src/include/30/omp_lib.h.var @@ -321,6 +321,13 @@ integer (kind=kmp_size_t_kind) size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) + import + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind) size + integer (kind=kmp_size_t_kind) alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) import integer (kind=kmp_pointer_kind) kmp_calloc @@ -416,6 +423,7 @@ !dec$ attributes alias:'KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'KMP_FREE'::kmp_free @@ -484,6 +492,7 @@ !dec$ attributes alias:'_KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'_KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'_KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'_KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'_KMP_FREE'::kmp_free @@ -555,6 +564,7 @@ !dec$ attributes alias:'kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'kmp_calloc_'::kmp_calloc !dec$ attributes alias:'kmp_realloc_'::kmp_realloc !dec$ attributes alias:'kmp_free_'::kmp_free @@ -626,6 +636,7 @@ !dec$ attributes alias:'_kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'_kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'_kmp_calloc_'::kmp_calloc !dec$ attributes alias:'_kmp_realloc_'::kmp_realloc !dec$ attributes alias:'_kmp_free_'::kmp_free Index: openmp/trunk/runtime/src/include/30/omp_lib.f.var =================================================================== --- openmp/trunk/runtime/src/include/30/omp_lib.f.var +++ openmp/trunk/runtime/src/include/30/omp_lib.f.var @@ -323,6 +323,13 @@ integer (kind=kmp_size_t_kind) size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind) size + integer (kind=kmp_size_t_kind) alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc @@ -416,6 +423,7 @@ !dec$ attributes alias:'KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'KMP_FREE'::kmp_free @@ -482,6 +490,7 @@ !dec$ attributes alias:'_KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'_KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'_KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'_KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'_KMP_FREE'::kmp_free @@ -551,6 +560,7 @@ !dec$ attributes alias:'kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'kmp_calloc_'::kmp_calloc !dec$ attributes alias:'kmp_realloc_'::kmp_realloc !dec$ attributes alias:'kmp_free_'::kmp_free @@ -620,6 +630,7 @@ !dec$ attributes alias:'_kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'_kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'_kmp_calloc_'::kmp_calloc !dec$ attributes alias:'_kmp_realloc_'::kmp_realloc !dec$ attributes alias:'_kmp_free_'::kmp_free Index: openmp/trunk/runtime/src/include/30/omp_lib.f90.var =================================================================== --- openmp/trunk/runtime/src/include/30/omp_lib.f90.var +++ openmp/trunk/runtime/src/include/30/omp_lib.f90.var @@ -328,6 +328,13 @@ integer (kind=kmp_size_t_kind), value :: size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) bind(c) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind), value :: size + integer (kind=kmp_size_t_kind), value :: alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) bind(c) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc Index: openmp/trunk/runtime/src/include/40/omp.h.var =================================================================== --- openmp/trunk/runtime/src/include/40/omp.h.var +++ openmp/trunk/runtime/src/include/40/omp.h.var @@ -137,6 +137,7 @@ extern omp_proc_bind_t __KAI_KMPC_CONVENTION omp_get_proc_bind (void); extern void * __KAI_KMPC_CONVENTION kmp_malloc (size_t); + extern void * __KAI_KMPC_CONVENTION kmp_aligned_malloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_calloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_realloc (void *, size_t); extern void __KAI_KMPC_CONVENTION kmp_free (void *); Index: openmp/trunk/runtime/src/include/40/omp_lib.h.var =================================================================== --- openmp/trunk/runtime/src/include/40/omp_lib.h.var +++ openmp/trunk/runtime/src/include/40/omp_lib.h.var @@ -393,6 +393,13 @@ integer (kind=kmp_size_t_kind), value :: size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) bind(c) + import + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind), value :: size + integer (kind=kmp_size_t_kind), value :: alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) bind(c) import integer (kind=kmp_pointer_kind) kmp_calloc @@ -481,6 +488,7 @@ !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_unset_affinity_mask_proc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_mask_proc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_malloc +!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_aligned_malloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_calloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_realloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_free @@ -548,6 +556,7 @@ !$omp declare target(kmp_unset_affinity_mask_proc ) !$omp declare target(kmp_get_affinity_mask_proc ) !$omp declare target(kmp_malloc ) +!$omp declare target(kmp_aligned_malloc ) !$omp declare target(kmp_calloc ) !$omp declare target(kmp_realloc ) !$omp declare target(kmp_free ) Index: openmp/trunk/runtime/src/include/40/omp_lib.f.var =================================================================== --- openmp/trunk/runtime/src/include/40/omp_lib.f.var +++ openmp/trunk/runtime/src/include/40/omp_lib.f.var @@ -406,6 +406,13 @@ integer (kind=kmp_size_t_kind) size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind) size + integer (kind=kmp_size_t_kind) alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc @@ -513,6 +520,7 @@ !dec$ attributes alias:'KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'KMP_FREE'::kmp_free @@ -589,6 +597,7 @@ !dec$ attributes alias:'_KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'_KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'_KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'_KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'_KMP_FREE'::kmp_free @@ -668,6 +677,7 @@ !dec$ attributes alias:'kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'kmp_calloc_'::kmp_calloc !dec$ attributes alias:'kmp_realloc_'::kmp_realloc !dec$ attributes alias:'kmp_free_'::kmp_free @@ -743,6 +753,7 @@ !dec$ attributes alias:'_kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'_kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'_kmp_calloc_'::kmp_calloc !dec$ attributes alias:'_kmp_realloc_'::kmp_realloc !dec$ attributes alias:'_kmp_free_'::kmp_free Index: openmp/trunk/runtime/src/include/40/omp_lib.f90.var =================================================================== --- openmp/trunk/runtime/src/include/40/omp_lib.f90.var +++ openmp/trunk/runtime/src/include/40/omp_lib.f90.var @@ -412,6 +412,13 @@ integer (kind=kmp_size_t_kind), value :: size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) bind(c) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind), value :: size + integer (kind=kmp_size_t_kind), value :: alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) bind(c) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc Index: openmp/trunk/runtime/src/include/41/omp.h.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp.h.var +++ openmp/trunk/runtime/src/include/41/omp.h.var @@ -173,6 +173,7 @@ extern void __KAI_KMPC_CONVENTION omp_get_partition_place_nums (int *); extern void * __KAI_KMPC_CONVENTION kmp_malloc (size_t); + extern void * __KAI_KMPC_CONVENTION kmp_aligned_malloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_calloc (size_t, size_t); extern void * __KAI_KMPC_CONVENTION kmp_realloc (void *, size_t); extern void __KAI_KMPC_CONVENTION kmp_free (void *); Index: openmp/trunk/runtime/src/include/41/omp_lib.h.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp_lib.h.var +++ openmp/trunk/runtime/src/include/41/omp_lib.h.var @@ -445,6 +445,13 @@ integer (kind=kmp_size_t_kind), value :: size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) bind(c) + import + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind), value :: size + integer (kind=kmp_size_t_kind), value :: alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) bind(c) import integer (kind=kmp_pointer_kind) kmp_calloc @@ -546,6 +553,7 @@ !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_unset_affinity_mask_proc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_mask_proc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_malloc +!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_aligned_malloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_calloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_realloc !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_free @@ -616,6 +624,7 @@ !$omp declare target(kmp_unset_affinity_mask_proc ) !$omp declare target(kmp_get_affinity_mask_proc ) !$omp declare target(kmp_malloc ) +!$omp declare target(kmp_aligned_malloc ) !$omp declare target(kmp_calloc ) !$omp declare target(kmp_realloc ) !$omp declare target(kmp_free ) Index: openmp/trunk/runtime/src/include/41/omp_lib.f.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp_lib.f.var +++ openmp/trunk/runtime/src/include/41/omp_lib.f.var @@ -453,6 +453,13 @@ integer (kind=kmp_size_t_kind) size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind) size + integer (kind=kmp_size_t_kind) alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc @@ -575,6 +582,7 @@ !dec$ attributes alias:'KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'KMP_FREE'::kmp_free @@ -654,6 +662,7 @@ !dec$ attributes alias:'_KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_KMP_MALLOC'::kmp_malloc +!dec$ attributes alias:'_KMP_ALIGNED_MALLOC'::kmp_aligned_malloc !dec$ attributes alias:'_KMP_CALLOC'::kmp_calloc !dec$ attributes alias:'_KMP_REALLOC'::kmp_realloc !dec$ attributes alias:'_KMP_FREE'::kmp_free @@ -736,6 +745,7 @@ !dec$ attributes alias:'kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'kmp_calloc_'::kmp_calloc !dec$ attributes alias:'kmp_realloc_'::kmp_realloc !dec$ attributes alias:'kmp_free_'::kmp_free @@ -814,6 +824,7 @@ !dec$ attributes alias:'_kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc !dec$ attributes alias:'_kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc !dec$ attributes alias:'_kmp_malloc_'::kmp_malloc +!dec$ attributes alias:'_kmp_aligned_malloc_'::kmp_aligned_malloc !dec$ attributes alias:'_kmp_calloc_'::kmp_calloc !dec$ attributes alias:'_kmp_realloc_'::kmp_realloc !dec$ attributes alias:'_kmp_free_'::kmp_free Index: openmp/trunk/runtime/src/include/41/omp_lib.f90.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp_lib.f90.var +++ openmp/trunk/runtime/src/include/41/omp_lib.f90.var @@ -464,6 +464,13 @@ integer (kind=kmp_size_t_kind), value :: size end function kmp_malloc + function kmp_aligned_malloc(size, alignment) bind(c) + use omp_lib_kinds + integer (kind=kmp_pointer_kind) kmp_aligned_malloc + integer (kind=kmp_size_t_kind), value :: size + integer (kind=kmp_size_t_kind), value :: alignment + end function kmp_aligned_malloc + function kmp_calloc(nelem, elsize) bind(c) use omp_lib_kinds integer (kind=kmp_pointer_kind) kmp_calloc Index: openmp/trunk/runtime/src/kmp.h =================================================================== --- openmp/trunk/runtime/src/kmp.h +++ openmp/trunk/runtime/src/kmp.h @@ -3214,6 +3214,7 @@ extern void __kmp_finalize_bget( kmp_info_t *th ); KMP_EXPORT void *kmpc_malloc( size_t size ); +KMP_EXPORT void *kmpc_aligned_malloc( size_t size, size_t alignment ); KMP_EXPORT void *kmpc_calloc( size_t nelem, size_t elsize ); KMP_EXPORT void *kmpc_realloc( void *ptr, size_t size ); KMP_EXPORT void kmpc_free( void *ptr ); Index: openmp/trunk/runtime/src/kmp_alloc.c =================================================================== --- openmp/trunk/runtime/src/kmp_alloc.c +++ openmp/trunk/runtime/src/kmp_alloc.c @@ -1427,7 +1427,37 @@ kmpc_malloc( size_t size ) { void * ptr; - ptr = bget( __kmp_entry_thread(), (bufsize) size ); + ptr = bget( __kmp_entry_thread(), (bufsize)(size + sizeof(ptr)) ); + if( ptr != NULL ) { + // save allocated pointer just before one returned to user + *(void**)ptr = ptr; + ptr = (void**)ptr + 1; + } + return ptr; +} + +#define IS_POWER_OF_TWO(n) (((n)&((n)-1))==0) + +void * +kmpc_aligned_malloc( size_t size, size_t alignment ) +{ + void * ptr; + void * ptr_allocated; + KMP_DEBUG_ASSERT( alignment < 32 * 1024 ); // Alignment should not be too big + if( !IS_POWER_OF_TWO(alignment) ) { + // AC: do we need to issue a warning here? + errno = EINVAL; + return NULL; + } + size = size + sizeof( void* ) + alignment; + ptr_allocated = bget( __kmp_entry_thread(), (bufsize)size ); + if( ptr_allocated != NULL ) { + // save allocated pointer just before one returned to user + ptr = (void*)(((kmp_uintptr_t)ptr_allocated + sizeof( void* ) + alignment) & ~(alignment - 1)); + *((void**)ptr - 1) = ptr_allocated; + } else { + ptr = NULL; + } return ptr; } @@ -1435,7 +1465,12 @@ kmpc_calloc( size_t nelem, size_t elsize ) { void * ptr; - ptr = bgetz( __kmp_entry_thread(), (bufsize) (nelem * elsize) ); + ptr = bgetz( __kmp_entry_thread(), (bufsize) (nelem * elsize + sizeof(ptr)) ); + if( ptr != NULL ) { + // save allocated pointer just before one returned to user + *(void**)ptr = ptr; + ptr = (void**)ptr + 1; + } return ptr; } @@ -1445,14 +1480,24 @@ void * result = NULL; if ( ptr == NULL ) { // If pointer is NULL, realloc behaves like malloc. - result = bget( __kmp_entry_thread(), (bufsize) size ); + result = bget( __kmp_entry_thread(), (bufsize)(size + sizeof(ptr)) ); + // save allocated pointer just before one returned to user + if( result != NULL ) { + *(void**)result = result; + result = (void**)result + 1; + } } else if ( size == 0 ) { // If size is 0, realloc behaves like free. // The thread must be registered by the call to kmpc_malloc() or kmpc_calloc() before. // So it should be safe to call __kmp_get_thread(), not __kmp_entry_thread(). - brel( __kmp_get_thread(), ptr ); + KMP_ASSERT(*((void**)ptr - 1)); + brel( __kmp_get_thread(), *((void**)ptr - 1) ); } else { - result = bgetr( __kmp_entry_thread(), ptr, (bufsize) size ); + result = bgetr( __kmp_entry_thread(), *((void**)ptr - 1), (bufsize)(size + sizeof(ptr)) ); + if( result != NULL ) { + *(void**)result = result; + result = (void**)result + 1; + } }; // if return result; } @@ -1468,7 +1513,9 @@ if ( ptr != NULL ) { kmp_info_t *th = __kmp_get_thread(); __kmp_bget_dequeue( th ); /* Release any queued buffers */ - brel( th, ptr ); + // extract allocated pointer and free it + KMP_ASSERT(*((void**)ptr - 1)); + brel( th, *((void**)ptr - 1) ); }; } Index: openmp/trunk/runtime/src/kmp_ftn_entry.h =================================================================== --- openmp/trunk/runtime/src/kmp_ftn_entry.h +++ openmp/trunk/runtime/src/kmp_ftn_entry.h @@ -1142,6 +1142,13 @@ } void * FTN_STDCALL +FTN_ALIGNED_MALLOC( size_t KMP_DEREF size, size_t KMP_DEREF alignment ) +{ + // kmpc_aligned_malloc initializes the library if needed + return kmpc_aligned_malloc( KMP_DEREF size, KMP_DEREF alignment ); +} + +void * FTN_STDCALL FTN_CALLOC( size_t KMP_DEREF nelem, size_t KMP_DEREF elsize ) { // kmpc_calloc initializes the library if needed Index: openmp/trunk/runtime/src/kmp_ftn_os.h =================================================================== --- openmp/trunk/runtime/src/kmp_ftn_os.h +++ openmp/trunk/runtime/src/kmp_ftn_os.h @@ -45,6 +45,7 @@ #define FTN_GET_AFFINITY_MASK_PROC kmp_get_affinity_mask_proc #define FTN_MALLOC kmp_malloc + #define FTN_ALIGNED_MALLOC kmp_aligned_malloc #define FTN_CALLOC kmp_calloc #define FTN_REALLOC kmp_realloc #define FTN_FREE kmp_free @@ -151,6 +152,7 @@ #define FTN_GET_AFFINITY_MASK_PROC kmp_get_affinity_mask_proc_ #define FTN_MALLOC kmp_malloc_ + #define FTN_ALIGNED_MALLOC kmp_aligned_malloc_ #define FTN_CALLOC kmp_calloc_ #define FTN_REALLOC kmp_realloc_ #define FTN_FREE kmp_free_ @@ -258,6 +260,7 @@ #define FTN_GET_AFFINITY_MASK_PROC KMP_GET_AFFINITY_MASK_PROC #define FTN_MALLOC KMP_MALLOC + #define FTN_ALIGNED_MALLOC KMP_ALIGNED_MALLOC #define FTN_CALLOC KMP_CALLOC #define FTN_REALLOC KMP_REALLOC #define FTN_FREE KMP_FREE @@ -365,6 +368,7 @@ #define FTN_GET_AFFINITY_MASK_PROC KMP_GET_AFFINITY_MASK_PROC_ #define FTN_MALLOC KMP_MALLOC_ + #define FTN_ALIGNED_MALLOC KMP_ALIGNED_MALLOC_ #define FTN_CALLOC KMP_CALLOC_ #define FTN_REALLOC KMP_REALLOC_ #define FTN_FREE KMP_FREE_ Index: openmp/trunk/runtime/src/kmp_stub.c =================================================================== --- openmp/trunk/runtime/src/kmp_stub.c +++ openmp/trunk/runtime/src/kmp_stub.c @@ -42,6 +42,7 @@ #define kmp_set_library kmpc_set_library #define kmp_set_defaults kmpc_set_defaults #define kmp_malloc kmpc_malloc +#define kmp_aligned_malloc kmpc_aligned_malloc #define kmp_calloc kmpc_calloc #define kmp_realloc kmpc_realloc #define kmp_free kmpc_free @@ -102,6 +103,17 @@ /* KMP memory management functions. */ void * kmp_malloc( size_t size ) { i; return malloc( size ); } +void * kmp_aligned_malloc( size_t sz, size_t a ) { + i; +#if KMP_OS_WINDOWS + errno = ENOSYS; // not supported + return NULL; // no standard aligned allocator on Windows (pre - C11) +#else + void **res; + errno = posix_memalign( res, a, sz ); + return *res; +#endif +} void * kmp_calloc( size_t nelem, size_t elsize ) { i; return calloc( nelem, elsize ); } void * kmp_realloc( void *ptr, size_t size ) { i; return realloc( ptr, size ); } void kmp_free( void * ptr ) { i; free( ptr ); } Index: openmp/trunk/runtime/test/api/kmp_aligned_malloc.c =================================================================== --- openmp/trunk/runtime/test/api/kmp_aligned_malloc.c +++ openmp/trunk/runtime/test/api/kmp_aligned_malloc.c @@ -0,0 +1,62 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include +#include "omp_testsuite.h" + +int alignments[] = {64, 128, 256, 512, 1024, 2048, 4096}; + +unsigned aligned_by(uint64_t addr) { + uint64_t alignment = 1; + while((addr & (alignment-1)) == 0) { + alignment <<= 1; + } + return (alignment >> 1); +} + +int test_kmp_aligned_malloc() +{ + int err = 0; + #pragma omp parallel shared(err) + { + int i; + int* ptr; + uint64_t addr; + int tid = omp_get_thread_num(); + + for(i = 0; i < sizeof(alignments)/sizeof(int); i++) { + int alignment = alignments[i]; + // allocate 64 bytes with 64-byte alignment + // allocate 128 bytes with 128-byte alignment, etc. + ptr = (int*)kmp_aligned_malloc(alignment, alignment); + addr = (uint64_t)ptr; + if(addr & (alignment-1)) { + printf("thread %d: addr = %p (aligned to %u bytes) but expected " + " alignment = %d\n", tid, ptr, aligned_by(addr), alignment); + err = 1; + } + kmp_free(ptr); + } + + ptr = kmp_aligned_malloc(128, 127); + if (ptr != NULL) { + printf("thread %d: kmp_aligned_malloc() didn't return NULL when " + "alignment was not power of 2\n", tid); + err = 1; + } + } /* end of parallel */ + return !err; +} + +int main() +{ + int i; + int num_failed=0; + + for(i = 0; i < REPETITIONS; i++) { + if(!test_kmp_aligned_malloc()) { + num_failed++; + } + } + return num_failed; +}