summaryrefslogtreecommitdiffstats
path: root/openmp/runtime/src/kmp_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'openmp/runtime/src/kmp_alloc.c')
-rw-r--r--openmp/runtime/src/kmp_alloc.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/openmp/runtime/src/kmp_alloc.c b/openmp/runtime/src/kmp_alloc.c
index 668c8b556df..af3f1db958b 100644
--- a/openmp/runtime/src/kmp_alloc.c
+++ b/openmp/runtime/src/kmp_alloc.c
@@ -1427,7 +1427,37 @@ void *
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 @@ void *
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 @@ kmpc_realloc( void * ptr, size_t size )
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 @@ kmpc_free( void * ptr )
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) );
};
}
OpenPOWER on IntegriCloud