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

25 decouple barriers from the core runtime #27

Merged
merged 15 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.o
/.config
/build
/build-*
# nix
/result
/.clangd
Expand Down
36 changes: 25 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ set(Red "${Esc}[31m")
set(ColorReset "${Esc}[m")

function(alaska_switch OPT DEFAULT)
if (${OPT})
message(STATUS "${OPT} DEFINED")
endif()


set(${OPT} ${DEFAULT} CACHE BOOL "")

if(${OPT} MATCHES "ON|On|on|TRUE|true|1")
Expand All @@ -31,12 +26,19 @@ function(alaska_option OPT DEFAULT)
message(STATUS "${Purple}OPTION${ColorReset} ${OPT} ${Green}${${OPT}}${ColorReset}")
endfunction()

function(alaska_option_nodef OPT DEFAULT)
set(${OPT} ${DEFAULT} CACHE STRING "")
message(STATUS "${Purple}OPTION${ColorReset} ${OPT} ${Green}${${OPT}}${ColorReset}")
endfunction()


alaska_switch(ALASKA_ENABLE_COMPILER ON)
alaska_switch(ALASKA_ENABLE_TESTING ON)
alaska_switch(ALASKA_CORE_ONLY OFF)

alaska_option(ALASKA_SIZE_BITS 24)
alaska_option(CMAKE_BUILD_TYPE Release)
alaska_option_nodef(ALASKA_ENABLE_COMPONENTS "compiler;compiler-rts")

set(ALASKA_VERSION 2)

Expand All @@ -45,6 +47,24 @@ set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)


# Check if the build type is Release
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_definitions(ALASKA_ENABLE_LOGGING=1)
endif()



list(FIND ALASKA_ENABLE_COMPONENTS "compiler" INDEX)
if (NOT INDEX EQUAL -1)
message(STATUS "compiler")
endif()


list(FIND ALASKA_ENABLE_COMPONENTS "compiler-rts" INDEX)
if (NOT INDEX EQUAL -1)
message(STATUS "compiler-rts")
endif()


# -------------------------------------------------------------------------------------------

Expand All @@ -59,12 +79,6 @@ else()
set(ALASKA_ENABLE_COMPILER FALSE)
endif()


# If we are building the core only, don't enable the compiler!
if(ALASKA_CORE_ONLY)
set(ALASKA_ENABLE_COMPILER FALSE)
endif()

add_compile_definitions("ALASKA_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
add_definitions(-include "${CMAKE_CURRENT_SOURCE_DIR}/runtime/include/alaska/config.h")

Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sanity: alaska
test: alaska
@build/runtime/alaska_test

.PHONY: alaska all
.PHONY: alaska all

# Run compilation unit tests to validate that the compiler can
# handle all the funky control flow in the GCC test suite
Expand All @@ -43,8 +43,15 @@ unit: alaska FORCE
docs:
@doxygen Doxyfile


# Defer to CMake to clean itself, if the build folder exists
clean:
rm -rf build .*.o*
[ -d $(BUILD) ] && make -C $(BUILD) clean
rm -f .*.o*

mrproper:
rm -rf $(BUILD) .*.o*


docker:
docker build -t alaska .
Expand Down
12 changes: 5 additions & 7 deletions runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ set(CORE_SOURCES
core/SizedPage.cpp
core/LocalityPage.cpp


core/barrier.cpp

# liballoc is a simple, small, malloc implementation that we embed
# so alaska can temporially allocate objects w/o implementing a non-handle
# allocator as well
Expand All @@ -69,16 +66,14 @@ set(CORE_SOURCES
)


find_library(LIBUNWIND_LIBRARIES NAMES unwind )
message(STATUS "UNWIND: ${LIBUNWIND_LIBRARIES}")

add_library(alaska_core STATIC ${CORE_SOURCES})
add_library(alaska_core SHARED ${CORE_SOURCES})

target_compile_options(alaska_core PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-nostdlib++ -nostdinc++>)

set_target_properties(alaska_core PROPERTIES LINKER_LANGUAGE C)
set_target_properties(alaska_core PROPERTIES SOVERSION ${ALASKA_VERSION})
target_link_libraries(alaska_core ${LIBUNWIND_LIBRARIES})
# target_link_libraries(alaska_core ${LIBUNWIND_LIBRARIES})

set_property(TARGET alaska_core PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(alaska_core dl pthread)
Expand All @@ -102,12 +97,15 @@ install(
# This defines the runtime that compiled code is linked against
if(NOT ALASKA_CORE_ONLY) # -----------------------------------------------------------------------------------

find_library(LIBUNWIND_LIBRARIES NAMES unwind )
message(STATUS "UNWIND: ${LIBUNWIND_LIBRARIES}")

add_library(alaska SHARED
rt/init.cpp
rt/halloc.cpp
rt/threads.cpp
rt/compat.c
rt/barrier.cpp
)

target_include_directories(alaska PUBLIC include/)
Expand Down
9 changes: 8 additions & 1 deletion runtime/core/HandleTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* This is free software. You are permitted to use, redistribute,
* and modify it as specified in the file "LICENSE".
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif


#include <alaska/HandleTable.hpp>
Expand Down Expand Up @@ -132,7 +135,7 @@ namespace alaska {
return m_slabs[idx];
}

slabidx_t HandleTable::mapping_slab_idx(Mapping *m) {
slabidx_t HandleTable::mapping_slab_idx(Mapping *m) const {
auto byte_distance = (uintptr_t)m - (uintptr_t)m_table;
return byte_distance / HandleTable::slab_size;
}
Expand All @@ -151,6 +154,10 @@ namespace alaska {
}


bool HandleTable::valid_handle(Mapping *m) const {
return mapping_slab_idx(m) < (slabidx_t)m_slabs.size();
}

void HandleTable::put(Mapping *m, alaska::ThreadCache *owner) {
log_trace("Putting handle %p", m);
// Validate that the handle is in this table
Expand Down
2 changes: 1 addition & 1 deletion runtime/core/LocalityPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace alaska {
md_bump_next--;


log_trace("setting md to %08lx", m.to_compact());
log_trace("setting md to %p", &m);
md->mapping = const_cast<alaska::Mapping *>(&m);
log_trace("set md!");

Expand Down
72 changes: 9 additions & 63 deletions runtime/core/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,31 @@

#include <alaska/Runtime.hpp>
#include <alaska/SizeClass.hpp>
#include <alaska/BarrierManager.hpp>
#include "alaska/alaska.hpp"
#include <stdlib.h>

namespace alaska {
// The default instance of a barrier manager.
static BarrierManager global_nop_barrier_manager;
// The current global instance of the runtime, since we can only have one at a time
static Runtime *g_runtime = nullptr;


Runtime::Runtime() {
// Validate that there is not already a runtime (TODO: atomics?)
ALASKA_ASSERT(g_runtime == nullptr, "Cannot create more than one runtime");
// Assign the global runtime to be this instance
g_runtime = this;
// Attach a default barrier manager
this->barrier_manager = &global_nop_barrier_manager;

log_debug("Created a new Alaska Runtime @ %p", this);
}

Runtime::~Runtime() {
log_debug("Destroying Alaska Runtime");
// Unset the global instance so another runtime can be allocated
g_runtime = nullptr;
}

Expand All @@ -38,69 +47,6 @@ namespace alaska {
}


// void* Runtime::halloc(size_t sz, bool zero) {
// auto& rt = *this;
// log_trace("halloc: allocating %lu bytes (zero=%d)", sz, zero);
// // Just some big number.
// if (sz > (1LLU << (uint64_t)(ALASKA_SIZE_BITS - ALASKA_SQUEEZE_BITS - 1)) - 1) {
// log_debug(
// "Allocation of size %zu deemed too big - using the system allocator instead...", sz);
// return ::malloc(sz);
// }



// int sc = alaska::size_to_class(sz);
// size_t rsz = alaska::class_to_size(sc);
// log_trace("sz = %zu, sc = %d, rsz = %zu\n", sz, sc, rsz);

// alaska::Mapping* m = rt.handle_table.get();
// if (m == nullptr) {
// log_fatal("halloc: out of handles");
// abort();
// }

// void* p = rt.page.alloc(*m, sz);

// if (p == nullptr) {
// log_fatal("halloc: out of memory");
// abort();
// }
// if (zero) {
// memset(p, 0, sz);
// }

// m->set_pointer(p);

// void* out = (void*)m->to_handle(0);
// log_trace("halloc handle %p -> %p", out, p);
// return out;
// }

// void Runtime::hfree(void* ptr) {
// auto* m = alaska::Mapping::from_handle_safe(ptr);

// log_trace("hfree: freeing %p (%p)", ptr, m->get_pointer());
// this->page.release(*m, m->get_pointer());
// }



// void* Runtime::hrealloc(void* ptr, size_t size) {
// log_trace("hrealloc(%p, %zu)", ptr, size);
// if (size == 0) {
// hfree(ptr);
// return nullptr;
// }

// // TODO: Implement hrealloc function
// log_fatal("hrealloc: not implemented");
// abort();
// return nullptr;
// }



void Runtime::dump(FILE *stream) {
//
fprintf(stream, "Alaska Runtime Information:\n");
Expand Down
14 changes: 10 additions & 4 deletions runtime/core/ThreadCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ namespace alaska {
ALASKA_ASSERT(page != NULL, "calling hfree should always return a heap page");

if (page->is_owned_by(this)) {
log_trace("Free handle %p locally", handle);
log_trace("Free handle %p locally (ptr = %p)", &m, ptr);
page->release_local(m, ptr);
} else {
log_trace("Free handle %p remotely", handle);
log_trace("Free handle %p remotely (ptr = %p)", &m, ptr);
page->release_remote(m, ptr);
}
}
Expand Down Expand Up @@ -186,8 +186,11 @@ namespace alaska {
void ThreadCache::hfree(void *handle) {
alaska::Mapping *m = alaska::Mapping::from_handle_safe(handle);
if (unlikely(m == nullptr)) {

// printf("attempt to free non handle %p\n", handle);
bool worked = this->runtime.heap.huge_allocator.free(handle);
ALASKA_ASSERT(worked, "huge free failed");
(void)worked;
// ALASKA_ASSERT(worked, "huge free failed");
return;
}
// Free the allocation behind a mapping
Expand All @@ -199,7 +202,10 @@ namespace alaska {


size_t ThreadCache::get_size(void *handle) {
alaska::Mapping *m = alaska::Mapping::from_handle(handle);
alaska::Mapping *m = alaska::Mapping::from_handle_safe(handle);
if (m == nullptr) {
return this->runtime.heap.huge_allocator.size_of(handle);
}
void *ptr = m->get_pointer();
auto *page = this->runtime.heap.pt.get_unaligned(ptr);
if (page == nullptr) return this->runtime.heap.huge_allocator.size_of(ptr);
Expand Down
28 changes: 28 additions & 0 deletions runtime/include/alaska/BarrierManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <alaska/alaska.hpp>


namespace alaska {


// A BarrierManager exists to abstract the delivery of "barrier" events in alaksa. This is needed
// because different configurations of alaska require different mechanisms to "stop the world" and
// track all the pinned handles at a point in time. Some systems require sending signals to every
// thread, some don't require anything. Therefore, when a Runtime is constructed, a BarrierManager
// can be attached to it, effectively injecting the requirements of the runtime system into the
// core runtime's capabilities.
//
// This class also records some statistics about barrier events as they occur.
// The only requirement of this class is that when `::begin()` returns, all pinned handles must
// be marked as such, and when `::end()` returns they should be released. The core runtime relies
// on this to be the case for safe operation. If the user of the core runtime does not need to
// pin any handles, the barrier does not need to do anything.
struct BarrierManager : public alaska::InternalHeapAllocated {
virtual ~BarrierManager() = default;
virtual void begin(void){};
virtual void end(void){};

unsigned long barrier_count = 0;
};
} // namespace alaska
4 changes: 3 additions & 1 deletion runtime/include/alaska/HandleTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,15 @@ namespace alaska {
alaska::HandleSlab *new_slab(ThreadCache *new_owner);
alaska::HandleSlab *get_slab(slabidx_t idx);
// Given a mapping, return the index of the slab it belongs to.
slabidx_t mapping_slab_idx(Mapping *m);
slabidx_t mapping_slab_idx(Mapping *m) const;

auto slab_count() const { return m_slabs.size(); }
auto capacity() const { return m_capacity; }

void dump(FILE *stream);

bool valid_handle(alaska::Mapping *m) const;


// Free/release *some* mapping
void put(alaska::Mapping *m, alaska::ThreadCache *owner = (alaska::ThreadCache *)0x1000UL);
Expand Down
Loading