Skip to content

Commit

Permalink
48 move garbagecollector to open source (#50)
Browse files Browse the repository at this point in the history
* Add Epoch

* Add GarbageCollector
  • Loading branch information
oathdruid authored Aug 20, 2024
1 parent a7d4268 commit e031e7e
Show file tree
Hide file tree
Showing 56 changed files with 1,243 additions and 281 deletions.
10 changes: 10 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,21 @@ alias(
actual = '//src/babylon/concurrent:counter',
)

alias(
name = 'concurrent_epoch',
actual = '//src/babylon/concurrent:epoch',
)

alias(
name = 'concurrent_execution_queue',
actual = '//src/babylon/concurrent:execution_queue',
)

alias(
name = 'concurrent_garbage_collector',
actual = '//src/babylon/concurrent:garbage_collector',
)

alias(
name = 'concurrent_id_allocator',
actual = '//src/babylon/concurrent:id_allocator',
Expand Down
11 changes: 9 additions & 2 deletions copts.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ BABYLON_CLANG_COPTS = ['-faligned-new', '-Weverything', '-Wno-unknown-warning-op
'-Wno-gnu-zero-variadic-macro-arguments',
# 零长度数组用来做可变长结构是一种常用手段
'-Wno-zero-length-array',
# BABYLON_SERIALIZABLE宏内部定义的一些辅助成员在继承场景下会发生同名隐藏
# 但是这个场景下的隐藏本身是无害的,目前也还没有很好的方法做命名区分
'-Wno-shadow-field',
# TODO(lijiang01): 逐步梳理清除
'-Wno-old-style-cast', '-Wno-shadow-field',
'-Wno-exit-time-destructors', '-Wno-sign-conversion',
'-Wno-shadow-field-in-constructor', '-Wno-gnu-anonymous-struct', '-Wno-nested-anon-types',
'-Wno-shadow-uncaptured-local', '-Wno-weak-vtables', '-Wno-float-conversion', '-Wno-switch-enum',
'-Wno-shadow', '-Wno-array-bounds-pointer-arithmetic', '-Wno-cast-align', '-Wno-vla-extension',
Expand All @@ -34,3 +35,9 @@ BABYLON_COPTS = select({
'//:enable_werror': ['-Werror', '-DBABYLON_INCLUDE_EXTERNAL_AS_SYSTEM=1'],
'//conditions:default': [],
})

BABYLON_TEST_COPTS = BABYLON_COPTS + select({
'//:compiler_gcc': [],
'//:compiler_clang': ['-Wno-exit-time-destructors', '-Wno-sign-conversion'],
'//conditions:default': [],
})
13 changes: 13 additions & 0 deletions src/babylon/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ cc_library(
],
)

cc_library(
name = 'garbage_collector',
srcs = ['garbage_collector.cpp'],
hdrs = ['garbage_collector.h'],
copts = BABYLON_COPTS,
includes = ['//src'],
strip_include_prefix = '//src',
deps = [
'//src/babylon/concurrent:bounded_queue',
'//src/babylon/concurrent:id_allocator',
],
)

cc_library(
name = 'mlock',
srcs = ['mlock.cpp'],
Expand Down
37 changes: 15 additions & 22 deletions src/babylon/any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,28 +334,21 @@ inline bool Any::is_reference() const noexcept {
template <typename T>
inline T Any::as() const noexcept {
switch (_meta.m.type) {
case Type::INT64:
return *reinterpret_cast<const int64_t*>(const_raw_pointer());
case Type::INT32:
return *reinterpret_cast<const int32_t*>(const_raw_pointer());
case Type::INT16:
return *reinterpret_cast<const int16_t*>(const_raw_pointer());
case Type::INT8:
return *reinterpret_cast<const int8_t*>(const_raw_pointer());
case Type::BOOLEAN:
return *reinterpret_cast<const bool*>(const_raw_pointer());
case Type::UINT64:
return *reinterpret_cast<const uint64_t*>(const_raw_pointer());
case Type::UINT32:
return *reinterpret_cast<const uint32_t*>(const_raw_pointer());
case Type::UINT16:
return *reinterpret_cast<const uint16_t*>(const_raw_pointer());
case Type::UINT8:
return *reinterpret_cast<const uint8_t*>(const_raw_pointer());
case Type::DOUBLE:
return *reinterpret_cast<const double*>(const_raw_pointer());
case Type::FLOAT:
return *reinterpret_cast<const float*>(const_raw_pointer());
#define __BABYLON_TMP_GEN(etype, ctype) \
case Type::etype: \
return static_cast<T>(*reinterpret_cast<const ctype*>(const_raw_pointer()));
__BABYLON_TMP_GEN(INT64, int64_t)
__BABYLON_TMP_GEN(INT32, int32_t)
__BABYLON_TMP_GEN(INT16, int16_t)
__BABYLON_TMP_GEN(INT8, int8_t)
__BABYLON_TMP_GEN(BOOLEAN, bool)
__BABYLON_TMP_GEN(UINT64, uint64_t)
__BABYLON_TMP_GEN(UINT32, uint32_t)
__BABYLON_TMP_GEN(UINT16, uint16_t)
__BABYLON_TMP_GEN(UINT8, uint8_t)
__BABYLON_TMP_GEN(DOUBLE, double)
__BABYLON_TMP_GEN(FLOAT, float)
#undef __BABYLON_TMP_GEN
default:
return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions src/babylon/anyflow/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ ssize_t GraphVertexBuilder::index_for_named_dependency(
if (ABSL_PREDICT_FALSE(iter == _dependency_index_by_name.end())) {
return -1;
}
return iter->second;
return static_cast<ssize_t>(iter->second);
}

ssize_t GraphVertexBuilder::index_for_named_emit(
Expand All @@ -157,7 +157,7 @@ ssize_t GraphVertexBuilder::index_for_named_emit(
if (ABSL_PREDICT_FALSE(iter == _emit_index_by_name.end())) {
return -1;
}
return iter->second;
return static_cast<ssize_t>(iter->second);
}

void GraphVertexBuilder::set_graph(GraphBuilder& graph) noexcept {
Expand Down
8 changes: 4 additions & 4 deletions src/babylon/anyflow/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ template <typename C>
inline void GraphVertexBuilder::for_each_dependency(
C&& callback) const noexcept {
for (auto& dependency : _named_dependencies) {
callback(static_cast<const GraphDependencyBuilder&>(*dependency));
callback(const_cast<const GraphDependencyBuilder&>(*dependency));
}
for (auto& dependency : _anonymous_dependencies) {
callback(static_cast<const GraphDependencyBuilder&>(*dependency));
callback(const_cast<const GraphDependencyBuilder&>(*dependency));
}
}

Expand All @@ -98,10 +98,10 @@ inline void GraphVertexBuilder::for_each_emit(C&& callback) noexcept {
template <typename C>
inline void GraphVertexBuilder::for_each_emit(C&& callback) const noexcept {
for (auto& emit : _named_emits) {
callback(static_cast<const GraphEmitBuilder&>(*emit));
callback(const_cast<const GraphEmitBuilder&>(*emit));
}
for (auto& emit : _anonymous_emits) {
callback(static_cast<const GraphEmitBuilder&>(*emit));
callback(const_cast<const GraphEmitBuilder&>(*emit));
}
}

Expand Down
33 changes: 30 additions & 3 deletions src/babylon/anyflow/builtin/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,15 @@ class UnaryOperator : public Operator {
size_t _operand_index;
GetOperandFunction _get_operand;
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
::std::unordered_map<::std::string, ::std::function<::std::unique_ptr<Operator>(
const Operator::ValueIndex&,
const Operator::ValueIndex&)>>
UnaryOperator::_s_registry;
#pragma GCC diagnostic pop

// 二元运算符基类,自带注册表
class BinaryOperator : public Operator {
Expand Down Expand Up @@ -225,13 +230,18 @@ class BinaryOperator : public Operator {
size_t _roperand_index;
GetOperandFunction _get_roperand;
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
::std::vector<::std::tuple<size_t, Any::Type>> BinaryOperator::TYPE_LEVEL =
BinaryOperator::generate_type_level();
::std::unordered_map<
::std::string, ::std::function<::std::unique_ptr<Operator>(
const Operator::ValueIndex&, const Operator::ValueIndex&,
const Operator::ValueIndex&)>>
BinaryOperator::_s_registry;
#pragma GCC diagnostic pop

// 定义并注册一个一元运算符
#define __BABYLON_DEFINE_UNARY_OPERATOR(name, op) \
Expand Down Expand Up @@ -284,7 +294,7 @@ ::std::unordered_map<
if (ABSL_PREDICT_TRUE(value != nullptr)) { \
result = op !value->empty(); \
} else { \
result = op(bool) operand; \
result = op static_cast<bool>(operand); \
} \
break; \
} \
Expand Down Expand Up @@ -363,6 +373,10 @@ ::std::unordered_map<
BinaryOperator::Register<name_prefix##Operator> \
name_prefix##Operator::_s_register(#op);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
// 定义这些运算符
__BABYLON_DEFINE_UNARY_OPERATOR(Not, !);
__BABYLON_DEFINE_UNARY_OPERATOR(Neg, -);
Expand All @@ -381,6 +395,7 @@ __BABYLON_DEFINE_BINARY_OPERATOR(Ne, !=, 1);
#pragma GCC diagnostic pop
__BABYLON_DEFINE_BINARY_OPERATOR(And, &&, 0);
__BABYLON_DEFINE_BINARY_OPERATOR(Or, ||, 0);
#pragma GCC diagnostic pop

#undef __BABYLON_DEFINE_UNARY_OPERATOR
#undef __BABYLON_DEFINE_BINARY_OPERATOR
Expand Down Expand Up @@ -410,6 +425,10 @@ struct Option {
::std::vector<::std::unique_ptr<Operator>> operators;
};

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
static struct QuotedString : public grammar<const char*, ::std::string()> {
QuotedString() noexcept : base_type(start, "quoted_string") {
start = '"' >> *(escaped_slash | escaped_quote | common_char) >> '"';
Expand All @@ -423,6 +442,7 @@ static struct QuotedString : public grammar<const char*, ::std::string()> {
rule<const char*, char()> escaped_quote;
rule<const char*, char()> common_char;
} quoted_string;
#pragma GCC diagnostic pop

struct Variable : public grammar<const char*, ::std::string()> {
Variable() noexcept : base_type(start, "variable") {
Expand Down Expand Up @@ -850,8 +870,13 @@ int32_t ExpressionProcessor::expend_conditional_expression(
unsolved_expressions,
const ::std::string& result_name,
const ::std::string& expression_string) noexcept {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
static expression::ConditionalExpression conditional_expression;
static expression::Expression expression;
#pragma GCC diagnostic pop

::std::tuple<::std::string, ::std::string, ::std::string> result;
auto begin = expression_string.c_str();
Expand All @@ -868,7 +893,8 @@ int32_t ExpressionProcessor::expend_conditional_expression(
::boost::spirit::qi::space);
// 也不是一般表达式则报错
if (!ret || begin < end) {
::std::string pointer(begin - expression_string.c_str(), ' ');
::std::string pointer(
static_cast<size_t>(begin - expression_string.c_str()), ' ');
pointer += '^';
BABYLON_LOG(WARNING) << "error exp = " << expression_string;
BABYLON_LOG(WARNING) << " " << pointer;
Expand Down Expand Up @@ -923,7 +949,8 @@ int32_t ExpressionProcessor::expend_non_conditional_expression(

// 完整解析才算成功
if (!ret || begin < end) {
::std::string pointer(begin - expression_string.c_str(), ' ');
::std::string pointer(
static_cast<size_t>(begin - expression_string.c_str()), ' ');
pointer += '^';
BABYLON_LOG(WARNING) << "error exp = " << expression_string;
BABYLON_LOG(WARNING) << " " << pointer;
Expand Down
5 changes: 5 additions & 0 deletions src/babylon/anyflow/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ int InplaceGraphExecutor::run(ClosureContext* closure,
}

InplaceGraphExecutor& InplaceGraphExecutor::instance() noexcept {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
static InplaceGraphExecutor instance;
#pragma GCC diagnostic pop
return instance;
}
////////////////////////////////////////////////////////////////////////////////
Expand Down
11 changes: 5 additions & 6 deletions src/babylon/anyflow/vertex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,13 @@ int GraphVertex::activate(DataStack& activating_data,
_closure = closure;

// 无依赖直接记入可执行列表
int64_t waiting_num = _dependencies.size();
auto waiting_num = _dependencies.size();
if (waiting_num == 0) {
runnable_vertexes.emplace_back(this);
return 0;
}
_waiting_num.store(waiting_num, ::std::memory_order_relaxed);
_waiting_num.store(static_cast<int64_t>(waiting_num),
::std::memory_order_relaxed);

if (0 != _processor->on_activate()) {
return -1;
Expand All @@ -200,9 +201,9 @@ int GraphVertex::activate(DataStack& activating_data,

// 去掉已经就绪的数目,如果全部就绪,节点加入待运行集合
if (finished > 0) {
waiting_num =
waiting_num = static_cast<size_t>(
_waiting_num.fetch_sub(finished, ::std::memory_order_acq_rel) -
finished;
finished);
if (waiting_num == 0) {
runnable_vertexes.emplace_back(this);
return 0;
Expand Down Expand Up @@ -242,7 +243,5 @@ void GraphVertex::invoke(VertexStack& runnable_vertexes) noexcept {
}
}

GraphProcessor GraphVertex::DEFAULT_EMPTY_PROCESSOR;

} // namespace anyflow
BABYLON_NAMESPACE_END
58 changes: 28 additions & 30 deletions src/babylon/anyflow/vertex.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,6 @@ class GraphVertex {
inline VertexStack* runnable_vertexes() noexcept;

private:
static GraphProcessor DEFAULT_EMPTY_PROCESSOR;

const GraphVertexBuilder* _builder {nullptr};

Graph* _graph {nullptr};
Expand Down Expand Up @@ -299,34 +297,34 @@ BABYLON_NAMESPACE_END
BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(0, args), 0), \
__ANYFLOW_DECLARE_DEPEND args, __ANYFLOW_DECLARE_EMIT args)

#define __ANYFLOW_DECLARE_DEPEND(r, type, name, is_channel, is_mutable, \
essential_level, is_va_args, ...) \
{ \
BOOST_PP_IF( \
BOOST_PP_EQUAL(is_va_args, 0), \
auto index = vertex().index_for_named_dependency(#name); \
if (index < 0 && essential_level > 0) { \
BABYLON_LOG(WARNING) \
<< "no depend bind to " #name " for " << vertex(); \
return -1; \
} if (index >= 0) { \
auto depend = vertex().named_dependency(index); \
if (is_mutable) { \
depend->declare_mutable(); \
} \
depend->declare_essential(essential_level == 1); \
BOOST_PP_IF( \
is_channel, \
depend->declare_channel<__ANYFLOW_TYPE_FOR_NAME(name)>(); \
, depend->declare_type<__ANYFLOW_TYPE_FOR_NAME(name)>();) \
} __anyflow_index_for_##name = index; \
, \
size_t anonymous_depends_size = vertex().anonymous_dependency_size(); \
name.resize(anonymous_depends_size); \
for (size_t index = 0; index < anonymous_depends_size; index++) { \
auto depend = vertex().anonymous_dependency(index); \
depend->declare_type<__ANYFLOW_TYPE_FOR_NAME(name)>(); \
}) \
#define __ANYFLOW_DECLARE_DEPEND(r, type, name, is_channel, is_mutable, \
essential_level, is_va_args, ...) \
{ \
BOOST_PP_IF( \
BOOST_PP_EQUAL(is_va_args, 0), \
auto index = vertex().index_for_named_dependency(#name); \
if (index < 0 && essential_level > 0) { \
BABYLON_LOG(WARNING) \
<< "no depend bind to " #name " for " << vertex(); \
return -1; \
} if (index >= 0) { \
auto depend = vertex().named_dependency(static_cast<size_t>(index)); \
if (is_mutable) { \
depend->declare_mutable(); \
} \
depend->declare_essential(essential_level == 1); \
BOOST_PP_IF( \
is_channel, \
depend->declare_channel<__ANYFLOW_TYPE_FOR_NAME(name)>(); \
, depend->declare_type<__ANYFLOW_TYPE_FOR_NAME(name)>();) \
} __anyflow_index_for_##name = index; \
, \
size_t anonymous_depends_size = vertex().anonymous_dependency_size(); \
name.resize(anonymous_depends_size); \
for (size_t index = 0; index < anonymous_depends_size; index++) { \
auto depend = vertex().anonymous_dependency(index); \
depend->declare_type<__ANYFLOW_TYPE_FOR_NAME(name)>(); \
}) \
}

#define __ANYFLOW_DECLARE_EMIT(r, type, name, is_channel, is_mutable, \
Expand Down
Loading

0 comments on commit e031e7e

Please sign in to comment.