Skip to content

Commit 3aef908

Browse files
Merge pull request #27 from nickwanninger/25-decouple-barriers-from-the-core-runtime
25 decouple barriers from the core runtime
2 parents dc30c2a + 9be04da commit 3aef908

19 files changed

+158
-137
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*.o
66
/.config
77
/build
8+
/build-*
89
# nix
910
/result
1011
/.clangd

CMakeLists.txt

+25-11
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ set(Red "${Esc}[31m")
55
set(ColorReset "${Esc}[m")
66

77
function(alaska_switch OPT DEFAULT)
8-
if (${OPT})
9-
message(STATUS "${OPT} DEFINED")
10-
endif()
11-
12-
138
set(${OPT} ${DEFAULT} CACHE BOOL "")
149

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

29+
function(alaska_option_nodef OPT DEFAULT)
30+
set(${OPT} ${DEFAULT} CACHE STRING "")
31+
message(STATUS "${Purple}OPTION${ColorReset} ${OPT} ${Green}${${OPT}}${ColorReset}")
32+
endfunction()
33+
3434

3535
alaska_switch(ALASKA_ENABLE_COMPILER ON)
3636
alaska_switch(ALASKA_ENABLE_TESTING ON)
37+
alaska_switch(ALASKA_CORE_ONLY OFF)
3738

3839
alaska_option(ALASKA_SIZE_BITS 24)
3940
alaska_option(CMAKE_BUILD_TYPE Release)
41+
alaska_option_nodef(ALASKA_ENABLE_COMPONENTS "compiler;compiler-rts")
4042

4143
set(ALASKA_VERSION 2)
4244

@@ -45,6 +47,24 @@ set(CMAKE_C_COMPILER_WORKS 1)
4547
set(CMAKE_CXX_COMPILER_WORKS 1)
4648

4749

50+
# Check if the build type is Release
51+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
52+
add_compile_definitions(ALASKA_ENABLE_LOGGING=1)
53+
endif()
54+
55+
56+
57+
list(FIND ALASKA_ENABLE_COMPONENTS "compiler" INDEX)
58+
if (NOT INDEX EQUAL -1)
59+
message(STATUS "compiler")
60+
endif()
61+
62+
63+
list(FIND ALASKA_ENABLE_COMPONENTS "compiler-rts" INDEX)
64+
if (NOT INDEX EQUAL -1)
65+
message(STATUS "compiler-rts")
66+
endif()
67+
4868

4969
# -------------------------------------------------------------------------------------------
5070

@@ -59,12 +79,6 @@ else()
5979
set(ALASKA_ENABLE_COMPILER FALSE)
6080
endif()
6181

62-
63-
# If we are building the core only, don't enable the compiler!
64-
if(ALASKA_CORE_ONLY)
65-
set(ALASKA_ENABLE_COMPILER FALSE)
66-
endif()
67-
6882
add_compile_definitions("ALASKA_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
6983
add_definitions(-include "${CMAKE_CURRENT_SOURCE_DIR}/runtime/include/alaska/config.h")
7084

Makefile

+9-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ sanity: alaska
3333
test: alaska
3434
@build/runtime/alaska_test
3535

36-
.PHONY: alaska all
36+
.PHONY: alaska all
3737

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

46+
47+
# Defer to CMake to clean itself, if the build folder exists
4648
clean:
47-
rm -rf build .*.o*
49+
[ -d $(BUILD) ] && make -C $(BUILD) clean
50+
rm -f .*.o*
51+
52+
mrproper:
53+
rm -rf $(BUILD) .*.o*
54+
4855

4956
docker:
5057
docker build -t alaska .

runtime/CMakeLists.txt

+5-7
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ set(CORE_SOURCES
5656
core/SizedPage.cpp
5757
core/LocalityPage.cpp
5858

59-
60-
core/barrier.cpp
61-
6259
# liballoc is a simple, small, malloc implementation that we embed
6360
# so alaska can temporially allocate objects w/o implementing a non-handle
6461
# allocator as well
@@ -69,16 +66,14 @@ set(CORE_SOURCES
6966
)
7067

7168

72-
find_library(LIBUNWIND_LIBRARIES NAMES unwind )
73-
message(STATUS "UNWIND: ${LIBUNWIND_LIBRARIES}")
7469

75-
add_library(alaska_core STATIC ${CORE_SOURCES})
70+
add_library(alaska_core SHARED ${CORE_SOURCES})
7671

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

7974
set_target_properties(alaska_core PROPERTIES LINKER_LANGUAGE C)
8075
set_target_properties(alaska_core PROPERTIES SOVERSION ${ALASKA_VERSION})
81-
target_link_libraries(alaska_core ${LIBUNWIND_LIBRARIES})
76+
# target_link_libraries(alaska_core ${LIBUNWIND_LIBRARIES})
8277

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

100+
find_library(LIBUNWIND_LIBRARIES NAMES unwind )
101+
message(STATUS "UNWIND: ${LIBUNWIND_LIBRARIES}")
105102

106103
add_library(alaska SHARED
107104
rt/init.cpp
108105
rt/halloc.cpp
109106
rt/threads.cpp
110107
rt/compat.c
108+
rt/barrier.cpp
111109
)
112110

113111
target_include_directories(alaska PUBLIC include/)

runtime/core/HandleTable.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
* This is free software. You are permitted to use, redistribute,
99
* and modify it as specified in the file "LICENSE".
1010
*/
11+
#ifndef _GNU_SOURCE
12+
#define _GNU_SOURCE
13+
#endif
1114

1215

1316
#include <alaska/HandleTable.hpp>
@@ -132,7 +135,7 @@ namespace alaska {
132135
return m_slabs[idx];
133136
}
134137

135-
slabidx_t HandleTable::mapping_slab_idx(Mapping *m) {
138+
slabidx_t HandleTable::mapping_slab_idx(Mapping *m) const {
136139
auto byte_distance = (uintptr_t)m - (uintptr_t)m_table;
137140
return byte_distance / HandleTable::slab_size;
138141
}
@@ -151,6 +154,10 @@ namespace alaska {
151154
}
152155

153156

157+
bool HandleTable::valid_handle(Mapping *m) const {
158+
return mapping_slab_idx(m) < (slabidx_t)m_slabs.size();
159+
}
160+
154161
void HandleTable::put(Mapping *m, alaska::ThreadCache *owner) {
155162
log_trace("Putting handle %p", m);
156163
// Validate that the handle is in this table

runtime/core/LocalityPage.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace alaska {
3434
md_bump_next--;
3535

3636

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

runtime/core/Runtime.cpp

+9-63
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,31 @@
1212

1313
#include <alaska/Runtime.hpp>
1414
#include <alaska/SizeClass.hpp>
15+
#include <alaska/BarrierManager.hpp>
1516
#include "alaska/alaska.hpp"
1617
#include <stdlib.h>
1718

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

2125

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

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

2937
Runtime::~Runtime() {
3038
log_debug("Destroying Alaska Runtime");
39+
// Unset the global instance so another runtime can be allocated
3140
g_runtime = nullptr;
3241
}
3342

@@ -38,69 +47,6 @@ namespace alaska {
3847
}
3948

4049

41-
// void* Runtime::halloc(size_t sz, bool zero) {
42-
// auto& rt = *this;
43-
// log_trace("halloc: allocating %lu bytes (zero=%d)", sz, zero);
44-
// // Just some big number.
45-
// if (sz > (1LLU << (uint64_t)(ALASKA_SIZE_BITS - ALASKA_SQUEEZE_BITS - 1)) - 1) {
46-
// log_debug(
47-
// "Allocation of size %zu deemed too big - using the system allocator instead...", sz);
48-
// return ::malloc(sz);
49-
// }
50-
51-
52-
53-
// int sc = alaska::size_to_class(sz);
54-
// size_t rsz = alaska::class_to_size(sc);
55-
// log_trace("sz = %zu, sc = %d, rsz = %zu\n", sz, sc, rsz);
56-
57-
// alaska::Mapping* m = rt.handle_table.get();
58-
// if (m == nullptr) {
59-
// log_fatal("halloc: out of handles");
60-
// abort();
61-
// }
62-
63-
// void* p = rt.page.alloc(*m, sz);
64-
65-
// if (p == nullptr) {
66-
// log_fatal("halloc: out of memory");
67-
// abort();
68-
// }
69-
// if (zero) {
70-
// memset(p, 0, sz);
71-
// }
72-
73-
// m->set_pointer(p);
74-
75-
// void* out = (void*)m->to_handle(0);
76-
// log_trace("halloc handle %p -> %p", out, p);
77-
// return out;
78-
// }
79-
80-
// void Runtime::hfree(void* ptr) {
81-
// auto* m = alaska::Mapping::from_handle_safe(ptr);
82-
83-
// log_trace("hfree: freeing %p (%p)", ptr, m->get_pointer());
84-
// this->page.release(*m, m->get_pointer());
85-
// }
86-
87-
88-
89-
// void* Runtime::hrealloc(void* ptr, size_t size) {
90-
// log_trace("hrealloc(%p, %zu)", ptr, size);
91-
// if (size == 0) {
92-
// hfree(ptr);
93-
// return nullptr;
94-
// }
95-
96-
// // TODO: Implement hrealloc function
97-
// log_fatal("hrealloc: not implemented");
98-
// abort();
99-
// return nullptr;
100-
// }
101-
102-
103-
10450
void Runtime::dump(FILE *stream) {
10551
//
10652
fprintf(stream, "Alaska Runtime Information:\n");

runtime/core/ThreadCache.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ namespace alaska {
5959
ALASKA_ASSERT(page != NULL, "calling hfree should always return a heap page");
6060

6161
if (page->is_owned_by(this)) {
62-
log_trace("Free handle %p locally", handle);
62+
log_trace("Free handle %p locally (ptr = %p)", &m, ptr);
6363
page->release_local(m, ptr);
6464
} else {
65-
log_trace("Free handle %p remotely", handle);
65+
log_trace("Free handle %p remotely (ptr = %p)", &m, ptr);
6666
page->release_remote(m, ptr);
6767
}
6868
}
@@ -186,8 +186,11 @@ namespace alaska {
186186
void ThreadCache::hfree(void *handle) {
187187
alaska::Mapping *m = alaska::Mapping::from_handle_safe(handle);
188188
if (unlikely(m == nullptr)) {
189+
190+
// printf("attempt to free non handle %p\n", handle);
189191
bool worked = this->runtime.heap.huge_allocator.free(handle);
190-
ALASKA_ASSERT(worked, "huge free failed");
192+
(void)worked;
193+
// ALASKA_ASSERT(worked, "huge free failed");
191194
return;
192195
}
193196
// Free the allocation behind a mapping
@@ -199,7 +202,10 @@ namespace alaska {
199202

200203

201204
size_t ThreadCache::get_size(void *handle) {
202-
alaska::Mapping *m = alaska::Mapping::from_handle(handle);
205+
alaska::Mapping *m = alaska::Mapping::from_handle_safe(handle);
206+
if (m == nullptr) {
207+
return this->runtime.heap.huge_allocator.size_of(handle);
208+
}
203209
void *ptr = m->get_pointer();
204210
auto *page = this->runtime.heap.pt.get_unaligned(ptr);
205211
if (page == nullptr) return this->runtime.heap.huge_allocator.size_of(ptr);
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <alaska/alaska.hpp>
4+
5+
6+
namespace alaska {
7+
8+
9+
// A BarrierManager exists to abstract the delivery of "barrier" events in alaksa. This is needed
10+
// because different configurations of alaska require different mechanisms to "stop the world" and
11+
// track all the pinned handles at a point in time. Some systems require sending signals to every
12+
// thread, some don't require anything. Therefore, when a Runtime is constructed, a BarrierManager
13+
// can be attached to it, effectively injecting the requirements of the runtime system into the
14+
// core runtime's capabilities.
15+
//
16+
// This class also records some statistics about barrier events as they occur.
17+
// The only requirement of this class is that when `::begin()` returns, all pinned handles must
18+
// be marked as such, and when `::end()` returns they should be released. The core runtime relies
19+
// on this to be the case for safe operation. If the user of the core runtime does not need to
20+
// pin any handles, the barrier does not need to do anything.
21+
struct BarrierManager : public alaska::InternalHeapAllocated {
22+
virtual ~BarrierManager() = default;
23+
virtual void begin(void){};
24+
virtual void end(void){};
25+
26+
unsigned long barrier_count = 0;
27+
};
28+
} // namespace alaska

runtime/include/alaska/HandleTable.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,15 @@ namespace alaska {
9999
alaska::HandleSlab *new_slab(ThreadCache *new_owner);
100100
alaska::HandleSlab *get_slab(slabidx_t idx);
101101
// Given a mapping, return the index of the slab it belongs to.
102-
slabidx_t mapping_slab_idx(Mapping *m);
102+
slabidx_t mapping_slab_idx(Mapping *m) const;
103103

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

107107
void dump(FILE *stream);
108108

109+
bool valid_handle(alaska::Mapping *m) const;
110+
109111

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

0 commit comments

Comments
 (0)