Skip to content

Commit

Permalink
once again I forget to include new files :)
Browse files Browse the repository at this point in the history
  • Loading branch information
nic-donaldson committed Jun 28, 2020
1 parent c309566 commit c7d1a41
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 118 deletions.
49 changes: 2 additions & 47 deletions include/EXTLLVM.h
Expand Up @@ -64,53 +64,8 @@ extern "C"

// this added for dodgy continuations support

namespace extemp
{

namespace EXTLLVM
{

const unsigned LLVM_ZONE_ALIGN = 32; // MUST BE POWER OF 2!
const unsigned LLVM_ZONE_ALIGNPAD = LLVM_ZONE_ALIGN - 1;

inline llvm_zone_t* llvm_zone_create(uint64_t size)
{
auto zone(static_cast<llvm_zone_t*>(malloc(sizeof(llvm_zone_t))));
if (unlikely(!zone)) {
abort(); // in case a leak can be analyzed post-mortem
}
#ifdef _WIN32
if (size == 0) {
zone->memory = NULL;
}
else {
// this crashes extempore but I have no idea why????
// zone->memory = _aligned_malloc((size_t)size, (size_t)LLVM_ZONE_ALIGN);
zone->memory = malloc(size_t(size));
}
#else
posix_memalign(&zone->memory, LLVM_ZONE_ALIGN, size_t(size));
#endif
zone->mark = 0;
zone->offset = 0;
if (unlikely(!zone->memory)) {
size = 0;
}
zone->size = size;
zone->cleanup_hooks = nullptr;
zone->memories = nullptr;
return zone;
}

EXPORT void llvm_zone_destroy(llvm_zone_t* Zone);

inline llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone)
{
Zone->offset = 0;
return Zone;
}

EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size);
namespace extemp {
namespace EXTLLVM {

inline llvm_zone_stack* llvm_threads_get_zone_stack()
{
Expand Down
50 changes: 50 additions & 0 deletions include/EXTZONES.h
@@ -0,0 +1,50 @@
#pragma once

#include <UNIV.h>
#include <cinttypes>

#define DEBUG_ZONE_STACK 0
#define DEBUG_ZONE_ALLOC 0

struct zone_hooks_t {
uint64_t space; // here just so we don't get <i8*,i8*>
void* hook; // xtlang closure of type [void]*
zone_hooks_t* hooks;
};

// WARNING WARNING WARNING - HERE BE DRAGONS
// THIS STRUCTURE IS REFERENCED FROM GENERATED CODE
// DO NOT ALTER IT!!!

struct llvm_zone_t {
void* memory;
uint64_t offset;
uint64_t mark;
uint64_t size;
zone_hooks_t* cleanup_hooks;
llvm_zone_t* memories;
};

struct llvm_zone_stack
{
llvm_zone_t* head;
llvm_zone_stack* tail;
};

struct closure_address_table;

extern THREAD_LOCAL llvm_zone_stack* tls_llvm_zone_stack;
extern THREAD_LOCAL uint64_t tls_llvm_zone_stacksize;

namespace extemp {
namespace EXTLLVM {
const unsigned LLVM_ZONE_ALIGN = 32; // MUST BE POWER OF 2!
const unsigned LLVM_ZONE_ALIGNPAD = LLVM_ZONE_ALIGN - 1;

llvm_zone_t* llvm_zone_create(uint64_t size);
EXPORT void llvm_zone_destroy(llvm_zone_t* Zone);
llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone);
EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size);

}
}
72 changes: 1 addition & 71 deletions src/EXTLLVM.cpp
Expand Up @@ -99,8 +99,6 @@

#define DEBUG_ZONE_STACK 0
#define DEBUG_ZONE_ALLOC 0
#define LEAKY_ZONES 1
#define EXTENSIBLE_ZONES 1

EXPORT void* malloc16(size_t Size)
{
Expand Down Expand Up @@ -664,17 +662,7 @@ EXPORT void free_after_delay(char* Data, double Delay)
&FreeWithDelayCM, Data));
}

EXPORT void llvm_zone_destroy(llvm_zone_t* Zone)
{
#if DEBUG_ZONE_ALLOC
printf("DestroyZone: %p:%p:%lld:%lld\n", Zone, Zone->memory, Zone->offset, Zone->size);
#endif
if (Zone->memories) {
llvm_zone_destroy(Zone->memories);
}
free(Zone->memory);
free(Zone);
}


EXPORT llvm_zone_t* llvm_pop_zone_stack()
{
Expand All @@ -700,64 +688,6 @@ EXPORT llvm_zone_t* llvm_pop_zone_stack()
return head;
}

EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size)
{
static extemp::EXTMutex alloc_mutex("alloc mutex");
// TODO: is this thread-safe?
if (!alloc_mutex.initialised()) {
alloc_mutex.init();
}

extemp::EXTMutex::ScopedLock lock(alloc_mutex);
#if DEBUG_ZONE_ALLOC
printf("MallocZone: %p:%p:%lld:%lld:%lld\n",zone,zone->memory,zone->offset,zone->size,size);
#endif
size += LLVM_ZONE_ALIGN; // for storing size information
if (unlikely(zone->offset + size >= zone->size)) {
#if EXTENSIBLE_ZONES // if extensible_zones is true then extend zone size by zone->size
int old_zone_size = zone->size;
bool iszero(!zone->size);
if (size > zone->size) {
zone->size = size;
}
zone->size *= 2; // keep doubling zone size for each new allocation // TODO: 1.5???
if (zone->size < 1024) {
zone->size = 1024; // allocate a min size of 1024 bytes
}
llvm_zone_t* newzone = llvm_zone_create(zone->size);
void* tmp = newzone->memory;
if (iszero) { // if initial zone is 0 - then replace don't extend
zone->memory = tmp;
free(newzone);
} else {
// printf("adding new memory %p:%lld to existing %p:%lld\n",newzone,newzone->size,zone,zone->size);
newzone->memories = zone->memories;
newzone->memory = zone->memory;
newzone->size = old_zone_size;
zone->memory = tmp;
zone->memories = newzone;
}
llvm_zone_reset(zone);
#elif LEAKY_ZONES // if LEAKY ZONE is TRUE then just print a warning and just leak the memory
printf("\nZone:%p size:%lld is full ... leaking %lld bytes\n",zone,zone->size,size);
printf("Leaving a leaky zone can be dangerous ... particularly for concurrency\n");
fflush(NULL);
return malloc((size_t)size); // TODO: what about the stored size????
#else
printf("\nZone:%p size:%lld is full ... exiting!\n",zone,zone->size,size);
fflush(NULL);
exit(1);
#endif
}
size = (size + LLVM_ZONE_ALIGNPAD) & ~LLVM_ZONE_ALIGNPAD;
auto newptr = reinterpret_cast<void*>(reinterpret_cast<char*>(zone->memory) + zone->offset);
memset(newptr, 0, size); // clear memory
newptr = reinterpret_cast<char*>(newptr) + LLVM_ZONE_ALIGN; // skip past size
*(reinterpret_cast<uint64_t*>(newptr) - 1) = size;
zone->offset += size;
return newptr;
}

EXPORT void* llvm_zone_malloc_from_current_zone(uint64_t size)
{
return llvm_zone_malloc(llvm_peek_zone_stack(), size);
Expand Down
107 changes: 107 additions & 0 deletions src/EXTZONES.cpp
@@ -0,0 +1,107 @@
#include "EXTZONES.h"

#include <EXTMutex.h>

#include <cstring>

namespace extemp {
namespace EXTLLVM {

llvm_zone_t* llvm_zone_create(uint64_t size)
{
auto zone(static_cast<llvm_zone_t*>(malloc(sizeof(llvm_zone_t))));
if (unlikely(!zone)) {
abort(); // in case a leak can be analyzed post-mortem
}
#ifdef _WIN32
if (size == 0) {
zone->memory = NULL;
}
else {
// this crashes extempore but I have no idea why????
// zone->memory = _aligned_malloc((size_t)size, (size_t)LLVM_ZONE_ALIGN);
zone->memory = malloc(size_t(size));
}
#else
posix_memalign(&zone->memory, LLVM_ZONE_ALIGN, size_t(size));
#endif
zone->mark = 0;
zone->offset = 0;
if (unlikely(!zone->memory)) {
size = 0;
}
zone->size = size;
zone->cleanup_hooks = nullptr;
zone->memories = nullptr;
return zone;
}

EXPORT void llvm_zone_destroy(llvm_zone_t* Zone)
{
#if DEBUG_ZONE_ALLOC
printf("DestroyZone: %p:%p:%lld:%lld\n", Zone, Zone->memory, Zone->offset, Zone->size);
#endif
if (Zone->memories) {
llvm_zone_destroy(Zone->memories);
}
free(Zone->memory);
free(Zone);
}

llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone)
{
Zone->offset = 0;
return Zone;
}

EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size)
{
static extemp::EXTMutex alloc_mutex("alloc mutex");
// TODO: is this thread-safe?
if (!alloc_mutex.initialised()) {
alloc_mutex.init();
}

extemp::EXTMutex::ScopedLock lock(alloc_mutex);

#if DEBUG_ZONE_ALLOC
printf("MallocZone: %p:%p:%lld:%lld:%lld\n", zone, zone->memory, zone->offset, zone->size, size);
#endif

size += LLVM_ZONE_ALIGN; // for storing size information
if (unlikely(zone->offset + size >= zone->size)) {
int old_zone_size = zone->size;
bool iszero(!zone->size);
if (size > zone->size) {
zone->size = size;
}
zone->size *= 2; // keep doubling zone size for each new allocation // TODO: 1.5???
if (zone->size < 1024) {
zone->size = 1024; // allocate a min size of 1024 bytes
}
llvm_zone_t* newzone = llvm_zone_create(zone->size);
void* tmp = newzone->memory;
if (iszero) { // if initial zone is 0 - then replace don't extend
zone->memory = tmp;
free(newzone);
} else {
// printf("adding new memory %p:%lld to existing %p:%lld\n",newzone,newzone->size,zone,zone->size);
newzone->memories = zone->memories;
newzone->memory = zone->memory;
newzone->size = old_zone_size;
zone->memory = tmp;
zone->memories = newzone;
}
llvm_zone_reset(zone);
}
size = (size + LLVM_ZONE_ALIGNPAD) & ~LLVM_ZONE_ALIGNPAD;
auto newptr = reinterpret_cast<void*>(reinterpret_cast<char*>(zone->memory) + zone->offset);
memset(newptr, 0, size); // clear memory
newptr = reinterpret_cast<char*>(newptr) + LLVM_ZONE_ALIGN; // skip past size
*(reinterpret_cast<uint64_t*>(newptr) - 1) = size;
zone->offset += size;
return newptr;
}

} // namespace EXTLLVM
} // namespace extemp

0 comments on commit c7d1a41

Please sign in to comment.