Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement __aligned_malloc() and __aligned_free() #59

Merged
merged 6 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sys/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ __Z_EXPORT int flock(int fd, int operation) __asm("__flock");
}
#endif
#else
#include <sys/file.h>
#include_next <sys/file.h>
#endif

#endif
22 changes: 16 additions & 6 deletions include/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,22 @@ __Z_EXPORT extern int (*nanosleep)(const struct timespec*, struct timespec*);

#include_next <time.h>

typedef enum {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
CLOCK_HIGHRES,
CLOCK_THREAD_CPUTIME_ID
} clockid_t;
// __clockid_t is defined in sys/types.h #if __EDC_TARGET >= __EDC_LE4205 as
#ifndef __clockid_t
#define __clockid_t 1
typedef unsigned int clockid_t;
#endif

// These are defined in the system's time.h #if __EDC_TARGET >= __EDC_LE4205
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#endif
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC 1
#endif
// These are not defined anywhere as of LE 3.1:
#define CLOCK_HIGHRES 2
#define CLOCK_THREAD_CPUTIME_ID 3

#if defined(__cplusplus)
extern "C" {
Expand Down
14 changes: 14 additions & 0 deletions include/zos-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,20 @@ __Z_EXPORT void __mainTerminating();
*/
__Z_EXPORT char* __getprogramdir();

/**
* Reserve aligned storage block
* \param [in] alignment - must be a power of two and a multiple of
* sizeof(void*)
* \param [in] size - number of bytes to allocate
* \return pointer to the beginning of newly allocated memory
*/
__Z_EXPORT void *__aligned_malloc(size_t size, size_t alignment);

/**
* \param [in] ptr - pointer to the memory to deallocate
*/
__Z_EXPORT void __aligned_free(void *ptr);

#ifdef __cplusplus
}
#endif
Expand Down
30 changes: 29 additions & 1 deletion src/zos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// US Government Users Restricted Rights - Use, duplication
// or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
///////////////////////////////////////////////////////////////////////////////

#define _AE_BIMODAL 1
#undef _ENHANCED_ASCII_EXT
#define _ENHANCED_ASCII_EXT 0xFFFFFFFF
Expand All @@ -26,6 +25,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <features.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you included other system headers you don't need to include this one directly.

#include <iconv.h>
#include <libgen.h>
#include <poll.h>
Expand Down Expand Up @@ -3098,6 +3098,34 @@ extern "C" char* __getprogramdir() {
return NULL;
}

extern "C" void *__aligned_malloc(size_t size, size_t alignment) {
#if (__TARGET_LIB__ >= 0x43010000)
void *ptr;
if (posix_memalign(&ptr, alignment, size) == 0)
return ptr;
return nullptr;
#else
size_t req_size = size + alignment;
void *ptr = malloc(req_size);
if (ptr == nullptr)
return nullptr;
size_t sptr = reinterpret_cast<size_t>(ptr);
size_t mod = sptr % alignment;
size_t offset = alignment - mod;
void **ptr_aligned = reinterpret_cast<void**>(sptr + offset);
ptr_aligned[-1] = ptr;
return ptr_aligned;
#endif
}

extern "C" void __aligned_free(void *ptr) {
#if (__TARGET_LIB__ >= 0x43010000)
free(ptr);
#else
free((reinterpret_cast<void**>(ptr))[-1]);
#endif
}

#if defined(ZOSLIB_INITIALIZE)
__init_zoslib __zoslib;
#endif
56 changes: 56 additions & 0 deletions test/test-aligned-malloc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "zos.h"
#include "gtest/gtest.h"

#include <math.h>
#include <unistd.h>

namespace {

constexpr int KB = 1024;
constexpr int MB = KB * 1024;

#if (__TARGET_LIB__ >= 0x43010000)
#define AlignedAlloc posix_memalign
#else
#define AlignedAlloc AlignedAlloc
#endif

TEST(AlignedAlloc, TestOne) {
size_t alignment = sysconf(_SC_PAGESIZE);
size_t size = 123;
void *ptr = __aligned_malloc(size, alignment);
ASSERT_NE(ptr, nullptr);
ASSERT_EQ(reinterpret_cast<size_t>(ptr) % alignment, 0);
__aligned_free(ptr);
}

TEST(AlignedAlloc, TestTwo) {
size_t alignment;
size_t size = 4096;
void *ptr;
for (int i=3; i<=30; i++) {
alignment = powl(2, i);
ASSERT_EQ(alignment % sizeof(void*), 0);
ptr = __aligned_malloc(size, alignment);
ASSERT_NE(ptr, nullptr);
ASSERT_EQ(reinterpret_cast<size_t>(ptr) % alignment, 0);
__aligned_free(ptr);
}
}

TEST(AlignedAlloc, TestThree) {
size_t alignment;
void *ptr;
for (int i=3; i<=20; i++) {
alignment = powl(2, i);
ASSERT_EQ(alignment % sizeof(void*), 0);
for (size_t size=1; size <= MB; size+=10) {
ptr = __aligned_malloc(size, alignment);
ASSERT_NE(ptr, nullptr);
ASSERT_EQ(reinterpret_cast<size_t>(ptr) % alignment, 0);
__aligned_free(ptr);
}
}
}

} // namespace