-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from googleprojectzero/concurrence_release
Add Concurrence
- Loading branch information
Showing
70 changed files
with
5,436 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
BasedOnStyle: Google | ||
AllowShortBlocksOnASingleLine: false | ||
AllowShortFunctionsOnASingleLine: Inline | ||
ReflowComments: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
Checks: > | ||
*, | ||
-altera-*, | ||
-bugprone-easily-swappable-parameters, | ||
-bugprone-reserved-identifier, | ||
-cert-*, | ||
-cppcoreguidelines-*, | ||
-fuchsia-*, | ||
-hicpp-*, | ||
-llvm-*, | ||
-llvmlibc-*, | ||
-google-objc-function-naming, | ||
-misc-const-correctness, | ||
-misc-no-recursion, | ||
-misc-non-private-member-variables-in-classes, | ||
-misc-unused-parameters, | ||
-modernize-avoid-c-arrays, | ||
-modernize-deprecated-headers, | ||
-modernize-use-nodiscard, | ||
-modernize-use-trailing-return-type, | ||
-modernize-use-using, | ||
-performance-no-int-to-ptr, | ||
-readability-function-cognitive-complexity, | ||
-readability-identifier-length, | ||
-readability-implicit-bool-conversion, | ||
-readability-magic-numbers, | ||
WarningsAsErrors: '' | ||
HeaderFilterRegex: '' | ||
AnalyzeTemporaryDtors: false | ||
FormatStyle: none | ||
User: sockfuzzer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Copyright 2022 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# third_party ignored | ||
files: ^((?!third_party).)*$ | ||
repos: | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
rev: v3.2.0 | ||
hooks: | ||
- id: trailing-whitespace | ||
- id: end-of-file-fixer | ||
- id: check-yaml | ||
- id: check-added-large-files | ||
- id: check-merge-conflict | ||
- id: requirements-txt-fixer | ||
- repo: https://github.com/psf/black | ||
rev: '22.8.0' | ||
hooks: | ||
- id: black | ||
- repo: https://github.com/jlebar/pre-commit-hooks.git | ||
rev: 62ca83ba4958da48ea44d9f24cd0aa58633376c7 | ||
hooks: | ||
- id: bazel-buildifier | ||
- id: clang-format-whole-file | ||
types_or: [c++, c, proto] | ||
- repo: https://github.com/koalaman/shellcheck-precommit | ||
rev: v0.7.2 | ||
hooks: | ||
- id: shellcheck | ||
args: ["--severity=warning"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Copyright 2022 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
cc_library( | ||
name = "headers", | ||
srcs = ["coroutine_executor.h"], | ||
visibility = [ | ||
"//fuzz/host:__pkg__", | ||
], | ||
deps = [ | ||
"//third_party/libco:co", | ||
], | ||
) | ||
|
||
cc_library( | ||
name = "coroutine_executor", | ||
srcs = ["coroutine_executor.cc"], | ||
hdrs = ["coroutine_executor.h"], | ||
visibility = [ | ||
"//fuzz/host:__pkg__", | ||
], | ||
deps = [ | ||
":headers", | ||
"//executor", | ||
"//scheduler:fuzzed_scheduler", | ||
"@com_google_absl//absl/container:flat_hash_map", | ||
], | ||
) | ||
|
||
cc_test( | ||
name = "coroutine_executor_test", | ||
size = "small", | ||
srcs = ["coroutine_executor_test.cc"], | ||
deps = [ | ||
":coroutine_executor", | ||
"//executor:executor_test_template", | ||
"//scheduler:fuzzed_scheduler_test_template", | ||
"@com_google_googletest//:gtest_main", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2022 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// #define _GNU_SOURCE | ||
#include "fuzz/executor/coroutine_executor.h" | ||
|
||
#include <functional> | ||
#include <string> | ||
#include <utility> | ||
|
||
#include "absl/meta/type_traits.h" | ||
|
||
#if __has_feature(address_sanitizer) | ||
#include <sanitizer/common_interface_defs.h> | ||
#endif | ||
|
||
const int KERNEL_STACK_SIZE = 4096 * 16; | ||
|
||
#include "third_party/libco/libco.h" | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
#include <sys/mman.h> | ||
|
||
static CoroutineExecutor *g_coroutine_executor; | ||
|
||
static void ThreadStart() { | ||
g_coroutine_executor->CallPendingFunctionThenSwap(); | ||
} | ||
|
||
CoroutineExecutor::CoroutineExecutor() : main_thread_(co_active()) { | ||
g_current_thread = reinterpret_cast<ThreadHandle>(co_active()); | ||
g_coroutine_executor = this; | ||
} | ||
|
||
CoroutineExecutor::~CoroutineExecutor() { g_coroutine_executor = nullptr; } | ||
|
||
ThreadHandle CoroutineExecutor::CreateThread(std::function<void()> target) { | ||
void *mapping = | ||
mmap(nullptr, 0x1000 + KERNEL_STACK_SIZE, PROT_READ | PROT_WRITE, | ||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||
if (mapping == MAP_FAILED) { | ||
abort(); | ||
} | ||
if (mprotect(mapping, 0x1000, PROT_NONE)) { | ||
abort(); | ||
} | ||
cothread_t thread = co_derive(static_cast<uint8_t *>(mapping) + 0x1000, | ||
KERNEL_STACK_SIZE, ThreadStart); | ||
pending_functions_[thread] = std::move(target); | ||
return reinterpret_cast<ThreadHandle>(thread); | ||
} | ||
|
||
void CoroutineExecutor::CallPendingFunctionThenSwap() { | ||
#if __has_feature(address_sanitizer) | ||
__sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr); | ||
#endif | ||
cothread_t active = co_active(); | ||
g_current_thread = reinterpret_cast<ThreadHandle>(active); | ||
if (active == main_thread_) { | ||
abort(); | ||
} | ||
|
||
auto it = pending_functions_.find(active); | ||
if (it == pending_functions_.end()) { | ||
abort(); | ||
} | ||
|
||
auto pending_function = std::move(it->second); | ||
pending_functions_.erase(it); | ||
|
||
pending_function(); | ||
|
||
// TODO(nedwill): only notify destroyed once the thread actually gets | ||
// destroyed explicitly | ||
callbacks()->ThreadDestroyed(reinterpret_cast<ThreadHandle>(active)); | ||
SwitchToMainThread(); | ||
} | ||
|
||
void CoroutineExecutor::DeleteThread(ThreadHandle handle) { | ||
// co_delete(cothread); | ||
DeleteBacktrace(handle); | ||
munmap(reinterpret_cast<uint8_t *>(handle - 0x1000), | ||
KERNEL_STACK_SIZE + 0x1000); | ||
} | ||
|
||
void CoroutineExecutor::SwitchToMainThread() { | ||
SwitchTo(reinterpret_cast<ThreadHandle>(main_thread_)); | ||
} | ||
|
||
void CoroutineExecutor::SwitchTo(ThreadHandle handle) { | ||
auto *cothread = reinterpret_cast<cothread_t>(handle); | ||
|
||
if (co_active() == cothread) { | ||
// Already on requested thread | ||
return; | ||
} | ||
|
||
#if __has_feature(address_sanitizer) | ||
// TODO(nedwill): track first argument to support stack use after return | ||
// detection | ||
__sanitizer_start_switch_fiber(nullptr, cothread, KERNEL_STACK_SIZE); | ||
#endif | ||
co_switch(cothread); | ||
g_current_thread = reinterpret_cast<ThreadHandle>(co_active()); | ||
#if __has_feature(address_sanitizer) | ||
__sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr); | ||
#endif | ||
} | ||
|
||
ThreadHandle CoroutineExecutor::GetCurrentThreadHandle() { | ||
// For performance, prefer to access g_current_thread directly. | ||
// This global is set in SwitchTo. | ||
return g_current_thread; | ||
} | ||
|
||
ThreadHandle CoroutineExecutor::GetMainThreadHandle() { | ||
return reinterpret_cast<ThreadHandle>(main_thread_); | ||
} | ||
|
||
// TODO(nedwill): support naming fibers | ||
void CoroutineExecutor::SetThreadName(ThreadHandle handle, | ||
const std::string &name) {} | ||
|
||
std::string CoroutineExecutor::DescribeThreadHandle(ThreadHandle handle) { | ||
return {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef COROUTINE_EXECUTOR_H_ | ||
#define COROUTINE_EXECUTOR_H_ | ||
|
||
#include <functional> | ||
#include <string> | ||
|
||
#include "absl/container/flat_hash_map.h" | ||
#include "executor/executor.h" | ||
#include "third_party/libco/libco.h" | ||
|
||
class CoroutineExecutor : public Executor { | ||
public: | ||
explicit CoroutineExecutor(); | ||
~CoroutineExecutor() override; | ||
|
||
ThreadHandle CreateThread(std::function<void()> target) override; | ||
void DeleteThread(ThreadHandle handle) override; | ||
|
||
void SwitchToMainThread() override; | ||
void SwitchTo(ThreadHandle handle) override; | ||
|
||
ThreadHandle GetCurrentThreadHandle() override; | ||
ThreadHandle GetMainThreadHandle() override; | ||
|
||
void SetThreadName(ThreadHandle handle, const std::string &name) override; | ||
|
||
std::string DescribeThreadHandle(ThreadHandle handle) override; | ||
|
||
void CallPendingFunctionThenSwap(); | ||
|
||
private: | ||
cothread_t main_thread_; | ||
|
||
// Map from cothread_t to target functions | ||
absl::flat_hash_map<cothread_t, std::function<void()>> pending_functions_; | ||
}; | ||
|
||
#endif /* COROUTINE_EXECUTOR_H_ */ |
Oops, something went wrong.