[components][kconfig] 整理Kconfig目录名称和结构 (#5698)

This commit is contained in:
Man, Jianting (Meco)
2022-03-25 23:07:18 +08:00
committed by GitHub
parent 851d16b18f
commit a514b3bd16
46 changed files with 32 additions and 58 deletions
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-27 flybreak the first version.
*/
#pragma once
#include <cstdlib>
#include <system_error>
#include <chrono>
#include <ratio>
#include <rtthread.h>
#define RT_USING_CPP_EXCEPTION
inline void throw_system_error(int err, const char *what_msg)
{
#ifdef RT_USING_CPP_EXCEPTION
throw std::system_error(std::error_code(err, std::system_category()), what_msg);
#else
(void)err;
(void)what_msg;
::abort();
#endif
}
class tick_clock
{
public:
typedef clock_t rep;
typedef std::ratio<1, RT_TICK_PER_SECOND> period;
typedef std::chrono::duration<tick_clock::rep, tick_clock::period> duration;
typedef std::chrono::time_point<tick_clock> time_point;
constexpr static bool is_ready = true;
static time_point now();
};
class real_time_clock
{
public:
typedef std::chrono::nanoseconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<real_time_clock, duration> time_point;
static constexpr bool is_steady = true;
static time_point
now() noexcept;
};
@@ -0,0 +1,222 @@
#pragma once
#if __cplusplus < 201103L
#error "C++ version lower than C++11"
#endif
#include <pthread.h>
#include <system_error>
#include <chrono>
#include <utility>
#include <functional>
#include <memory>
#include "__utils.h"
#include "mutex"
#define rt_cpp_cond_var pthread_cond_t
namespace std
{
enum class cv_status
{
no_timeout,
timeout
};
class condition_variable
{
public:
typedef rt_cpp_cond_var *native_handle_type;
condition_variable(const condition_variable &) = delete;
condition_variable &operator=(const condition_variable &) = delete;
condition_variable() = default;
~condition_variable()
{
pthread_cond_destroy(&_m_cond);
}
void wait(unique_lock<mutex> &lock);
void notify_one() noexcept
{
pthread_cond_signal(&_m_cond);
}
void notify_all() noexcept
{
pthread_cond_broadcast(&_m_cond);
}
template <class Predicate>
void wait(unique_lock<mutex> &lock, Predicate pred)
{
while (!pred())
wait(lock);
}
template <class Clock, class Duration>
cv_status wait_until(unique_lock<mutex> &lock,
const chrono::time_point<Clock, Duration> &abs_time)
{
if (!lock.owns_lock())
throw_system_error((int)errc::operation_not_permitted,
"condition_variable::wailt_until: waiting on unlocked lock");
auto secs = chrono::time_point_cast<chrono::seconds>(abs_time);
auto nano_secs = chrono::duration_cast<chrono::nanoseconds>(abs_time - secs);
struct timespec c_abs_time = {static_cast<time_t>(secs.time_since_epoch().count()),
static_cast<long>(nano_secs.count())};
pthread_cond_timedwait(&_m_cond, lock.mutex()->native_handle(), &c_abs_time);
return (Clock::now() < abs_time) ? cv_status::no_timeout : cv_status::timeout;
}
template <class Clock, class Duration, class Predicate>
bool wait_until(unique_lock<mutex> &lock,
const chrono::time_point<Clock, Duration> &abs_time,
Predicate pred)
{
while (!pred())
if (wait_until(lock, abs_time) == cv_status::timeout)
return pred();
return true;
}
template <class Rep, class Period>
cv_status wait_for(unique_lock<mutex> &lock,
const chrono::duration<Rep, Period> &rel_time)
{
return wait_until(lock, real_time_clock::now() + rel_time);
}
template <class Rep, class Period, class Predicate>
bool wait_for(unique_lock<mutex> &lock,
const chrono::duration<Rep, Period> &rel_time,
Predicate pred)
{
return wait_until(lock, real_time_clock::now() + rel_time, std::move(pred));
}
native_handle_type native_handle()
{
return &_m_cond;
}
private:
rt_cpp_cond_var _m_cond = PTHREAD_COND_INITIALIZER;
};
// Lockable is only required to have `lock()` and `unlock()`
class condition_variable_any
{
private:
condition_variable _m_cond;
shared_ptr<mutex> _m_mtx;
// so that Lockable automatically unlocks when waiting and locks after waiting
template <class Lockable>
struct unlocker
{
Lockable &_m_lock;
explicit unlocker(Lockable &lk)
: _m_lock(lk)
{
_m_lock.unlock();
}
~unlocker()
{
_m_lock.lock();
}
unlocker(const unlocker &) = delete;
unlocker &operator=(const unlocker &) = delete;
};
public:
condition_variable_any() : _m_mtx(std::make_shared<mutex>()) {}
~condition_variable_any() = default;
condition_variable_any(const condition_variable_any &) = delete;
condition_variable_any &operator=(const condition_variable_any &) = delete;
void notify_one() noexcept
{
lock_guard<mutex> lk(*_m_mtx);
_m_cond.notify_one();
}
void notify_all() noexcept
{
lock_guard<mutex> lk(*_m_mtx);
_m_cond.notify_all();
}
template <class Lock>
void wait(Lock &lock)
{
shared_ptr<mutex> mut = _m_mtx;
unique_lock<mutex> lk(*mut);
unlocker<Lock> auto_lk(lock); // unlock here
unique_lock<mutex> lk2(std::move(lk));
_m_cond.wait(lk2);
} // mut.unlock(); lock.lock();
template <class Lock, class Predicate>
void wait(Lock &lock, Predicate pred)
{
while (!pred())
wait(lock);
}
template <class Lock, class Clock, class Duration>
cv_status wait_until(Lock &lock,
const chrono::time_point<Clock, Duration> &abs_time)
{
shared_ptr<mutex> mut = _m_mtx;
unique_lock<mutex> lk(*mut);
unlocker<Lock> auto_lk(lock); // unlock here
unique_lock<mutex> lk2(std::move(lk));
return _m_cond.wait_until(lk2, abs_time);
}
template <class Lock, class Clock, class Duration, class Predicate>
bool wait_until(Lock &lock,
const chrono::time_point<Clock, Duration> &abs_time,
Predicate pred)
{
while (!pred())
if (wait_until(lock, abs_time) == cv_status::timeout)
return pred();
return true;
}
template <class Lock, class Rep, class Period>
cv_status wait_for(Lock &lock,
const chrono::duration<Rep, Period> &rel_time)
{
return wait_until(lock, real_time_clock::now() + rel_time);
}
template <class Lock, class Rep, class Period, class Predicate>
bool wait_for(Lock &lock,
const chrono::duration<Rep, Period> &rel_time,
Predicate pred)
{
return wait_until(lock, real_time_clock::now() + rel_time, std::move(pred));
}
};
void notify_all_at_thread_exit(condition_variable &cond, unique_lock<mutex> lk);
} // namespace std
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-27 flybreak the first version.
*/
#include "condition_variable"
namespace std
{
void condition_variable::wait(unique_lock<mutex>& lock)
{
int err = pthread_cond_wait(&_m_cond, lock.mutex()->native_handle());
if (err)
{
throw_system_error(err, "condition_variable::wait: failed to wait on a condition");
}
}
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
{
// TLS currently not available
mutex* mut = lk.release();
mut->unlock();
cond.notify_all();
}
} // namespace std
+336
View File
@@ -0,0 +1,336 @@
#pragma once
#if __cplusplus < 201103L
#error "C++ version lower than C++11"
#endif
#include <mutex>
#include <condition_variable>
#include <memory>
#include <chrono>
#include <cassert>
namespace std {
enum class future_status {
ready,
timeout,
deferred
};
namespace detail {
class shared_state_base {
protected:
typedef void (*deleter_fn)(void *v);
using scoped_lock = std::lock_guard<std::mutex>;
using unique_lock = std::unique_lock<std::mutex>;
public:
explicit shared_state_base(deleter_fn d) : v_(nullptr), d_(d), valid_(true) {}
~shared_state_base() { d_(v_); }
shared_state_base(shared_state_base &&other) = delete;
shared_state_base(const shared_state_base &other) = delete;
shared_state_base &operator=(shared_state_base &&other) = delete;
shared_state_base &operator=(const shared_state_base &other) = delete;
void wait() {
unique_lock lock(m_);
c_.wait(lock, [this] { return has_value(); });
}
template <class Rep, class Period>
std::future_status
wait_for(const std::chrono::duration<Rep, Period> &rel_time) {
unique_lock lock(m_);
if (c_.wait_for(lock, rel_time, [this] { return has_value(); })) {
return std::future_status::ready;
}
return std::future_status::timeout;
}
template <class Clock, class Duration>
std::future_status
wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) {
unique_lock lock(m_);
if (c_.wait_until(lock, abs_time, [this] { return has_value(); })) {
return std::future_status::ready;
}
return std::future_status::timeout;
}
protected:
bool has_value() { return v_ != nullptr; }
protected:
std::mutex m_;
std::condition_variable c_;
void *v_;
deleter_fn d_;
bool valid_;
};
template <typename R>
class shared_state: public shared_state_base {
public:
shared_state() :shared_state_base(default_deleter_) {}
~shared_state() {}
R &get() {
wait();
scoped_lock lock(m_);
assert(valid_);
valid_ = false;
return *(static_cast<R *>(v_));
}
void set(const R &v) {
scoped_lock lock(m_);
assert(!has_value());
v_ = new R(v);
valid_ = true;
c_.notify_one();
}
void set(R &&v) {
scoped_lock lock(m_);
assert(!has_value());
v_ = new R(std::move(v));
valid_ = true;
c_.notify_one();
}
bool valid() {
scoped_lock lock(m_);
return valid_;
}
private:
static void default_deleter_(void *v) { delete static_cast<R *>(v); }
};
} // namespace detail
template <typename R>
class shared_future {
};
template <typename R>
class future {
using state_type = std::shared_ptr<detail::shared_state<R>>;
public:
future() {}
explicit future(const state_type &state) : state_(state) {}
future(future &&other) noexcept: state_(std::move(other.state_)) {
other.state_.reset();
}
future(const future &other) = delete;
~future() {}
future &operator=(future &&other) noexcept {
if (&other != this) {
state_ = std::move(other.state_);
other.state_.reset();
}
return *this;
}
future &operator=(const future &other) = delete;
void swap(future &other) noexcept {
std::swap(state_, other.state_);
}
std::shared_future<R> share() noexcept { return std::shared_future<R>(); }
R get() { return state_->get(); }
bool valid() const noexcept { return state_->valid(); }
void wait() const { state_->wait(); }
template <class Rep, class Period>
std::future_status
wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
return state_->wait_for(rel_time);
}
template <class Clock, class Duration>
std::future_status
wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
return state_->wait_until(abs_time);
}
private:
state_type state_;
};
template <>
class future<void> {
using state_type = std::shared_ptr<detail::shared_state<int>>;
public:
future() {}
explicit future(const state_type &state) : state_(state) {}
future(future &&other) noexcept: state_(std::move(other.state_)) {
other.state_.reset();
}
future(const future &other) = delete;
~future() {}
future &operator=(future &&other) noexcept {
if (&other != this) {
state_ = std::move(other.state_);
other.state_.reset();
}
return *this;
}
future &operator=(const future &other) = delete;
void swap(future &other) noexcept {
std::swap(state_, other.state_);
}
std::shared_future<void> share() noexcept { return std::shared_future<void>(); }
void get() { state_->get(); }
bool valid() const noexcept { return state_->valid(); }
void wait() const { state_->wait(); }
template <class Rep, class Period>
std::future_status
wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
return state_->wait_for(rel_time);
}
template <class Clock, class Duration>
std::future_status
wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
return state_->wait_until(abs_time);
}
private:
state_type state_;
};
template <typename R>
class promise {
using state_type = std::shared_ptr<detail::shared_state<R>>;
public:
promise() : state_(new detail::shared_state<R>()) {}
promise(promise &&other) noexcept: state_(std::move(other.state_)) {
other.state_.reset();
}
promise(const promise &other) = delete;
~promise() {}
promise &operator=(promise &&other) noexcept {
if (&other != this) {
state_ = std::move(other.state_);
other.state_.reset();
}
return *this;
}
promise &operator=(const promise &other) = delete;
void swap(promise &other) noexcept {
std::swap(state_, other.state_);
}
std::future<R> get_future() { return std::future<R>(state_); }
void set_value(const R &value) { state_->set(value); }
void set_value(R &&value) { state_->set(std::move(value)); }
void set_value_at_thread_exit(const R &value);
void set_value_at_thread_exit(R &&value);
void set_exception(std::exception_ptr p);
void set_exception_at_thread_exit(std::exception_ptr p);
private:
state_type state_;
};
template <>
class promise<void> {
using state_type = std::shared_ptr<detail::shared_state<int>>;
public:
promise() : state_(new detail::shared_state<int>()) {}
promise(promise &&other) noexcept: state_(std::move(other.state_)) {
other.state_.reset();
}
promise(const promise &other) = delete;
~promise() {}
promise &operator=(promise &&other) noexcept {
if (&other != this) {
state_ = std::move(other.state_);
other.state_.reset();
}
return *this;
}
promise &operator=(const promise &other) = delete;
void swap(promise &other) noexcept {
std::swap(state_, other.state_);
}
std::future<void> get_future() { return std::future<void>(state_); }
void set_value() { state_->set(0); }
void set_value_at_thread_exit();
void set_exception(std::exception_ptr p);
void set_exception_at_thread_exit(std::exception_ptr p);
private:
state_type state_;
};
template <class R>
void swap(std::future<R> &lhs, std::future<R> &rhs) noexcept {
lhs.swap(rhs);
}
template <class R>
void swap(std::promise<R> &lhs, std::promise<R> &rhs) noexcept {
lhs.swap(rhs);
}
} // namespace std
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-27 flybreak the first version.
*/
#include "mutex"
namespace std
{
// use a set of global and static objects
// a proxy function to pthread_once
function<void()> once_functor;
mutex& get_once_mutex()
{
static mutex once_mutex;
return once_mutex;
}
inline unique_lock<mutex>*& get_once_functor_lock_ptr()
{
static unique_lock<mutex>* once_functor_mutex_ptr = nullptr;
return once_functor_mutex_ptr;
}
void set_once_functor_lock_ptr(unique_lock<mutex>* m_ptr)
{
get_once_functor_lock_ptr() = m_ptr;
}
extern "C"
{
void once_proxy()
{
// need to first transfer the functor's ownership so as to call it
function<void()> once_call = std::move(once_functor);
// no need to hold the lock anymore
unique_lock<mutex>* lock_ptr = get_once_functor_lock_ptr();
get_once_functor_lock_ptr() = nullptr;
lock_ptr->unlock();
once_call();
}
}
}
+239
View File
@@ -0,0 +1,239 @@
#pragma once
#if __cplusplus < 201103L
#error "C++ version lower than C++11"
#endif
//#if defined(RT_USING_PTHREADS)
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <rtthread.h>
#include <cstddef>
#include <cerrno>
#include <ostream>
#include <functional>
#include <utility>
#include <chrono>
#include <memory>
#define rt_cpp_thread_t pthread_t
#ifndef PTHREAD_NUM_MAX
#define PTHREAD_NUM_MAX 32
#endif
#define CPP_UNJOINABLE_THREAD PTHREAD_NUM_MAX
namespace std
{
#define __STDCPP_THREADS__ __cplusplus
class thread
{
public:
typedef rt_cpp_thread_t native_handle_type;
struct invoker_base;
typedef shared_ptr<invoker_base> invoker_base_ptr;
class id
{
// basically a wrapper around native_handle_type
native_handle_type __cpp_thread_t;
public:
id() noexcept : __cpp_thread_t(CPP_UNJOINABLE_THREAD) {}
explicit id(native_handle_type hid)
: __cpp_thread_t(hid) {}
private:
friend class thread;
friend class hash<thread::id>;
friend bool operator==(thread::id x, thread::id y) noexcept;
friend bool operator<(thread::id x, thread::id y) noexcept;
template <class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id);
};
thread() noexcept = default;
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
~thread();
template <class F, class ...Args>
explicit thread(F&& f, Args&&... args)
{
start_thread(make_invoker_ptr(std::bind(
std::forward<F>(f),
std::forward<Args>(args)...
)));
}
thread(thread&& t) noexcept
{
swap(t);
}
thread& operator=(thread&& t) noexcept
{
if (joinable())
terminate();
swap(t);
return *this;
}
// member functions
void swap(thread& t) noexcept
{
std::swap(_m_thr, t._m_thr);
}
bool joinable() const noexcept
{
return (_m_thr.__cpp_thread_t < PTHREAD_NUM_MAX);
}
void join();
void detach();
id get_id() const noexcept { return _m_thr; }
native_handle_type native_handle() { return _m_thr.__cpp_thread_t; }
// static members
static unsigned hardware_concurrency() noexcept;
private:
id _m_thr;
void start_thread(invoker_base_ptr b);
public:
struct invoker_base
{
invoker_base_ptr this_ptr;
virtual ~invoker_base() = default;
virtual void invoke() = 0;
};
template<typename Callable>
struct invoker : public invoker_base
{
Callable func;
invoker(Callable&& F) : func(std::forward<Callable>(F)) { }
void invoke() { func(); }
};
template <typename Callable>
shared_ptr<invoker<Callable>> make_invoker_ptr(Callable&& F)
{
return std::make_shared<invoker<Callable>>(std::forward<Callable>(F));
}
};
inline void swap(thread& x, thread& y) noexcept
{
x.swap(y);
}
inline bool operator==(thread::id x, thread::id y) noexcept
{
// From POSIX for pthread_equal:
//"If either t1 or t2 are not valid thread IDs, the behavior is undefined."
return x.__cpp_thread_t == y.__cpp_thread_t;
}
inline bool operator!=(thread::id x, thread::id y) noexcept
{
return !(x == y);
}
inline bool operator<(thread::id x, thread::id y) noexcept
{
return x.__cpp_thread_t < y.__cpp_thread_t;
}
inline bool operator<=(thread::id x, thread::id y) noexcept
{
return !(y < x);
}
inline bool operator>(thread::id x, thread::id y) noexcept
{
return !(x <= y);
}
inline bool operator>=(thread::id x, thread::id y) noexcept
{
return !(x < y);
}
template <class charT, class traits>
inline basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id)
{
if (id == thread::id()) // id is invalid, representing no pthread
out << "thread::id of a non-executing thread";
else
out << id.__cpp_thread_t;
return out;
}
template <>
struct hash<thread::id>
{
typedef size_t result_type;
typedef thread::id argument_type;
size_t operator()(const thread::id& id) const noexcept
{
return hash<rt_cpp_thread_t>()(id.__cpp_thread_t);
}
};
namespace this_thread
{
inline thread::id get_id() noexcept
{
return thread::id(pthread_self());
}
inline void yield() noexcept
{
sched_yield();
}
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& rel_time)
{
if (rel_time <= rel_time.zero()) // less than zero, no need to sleep
return;
auto milli_secs = chrono::duration_cast<chrono::milliseconds>(rel_time);
// the precision is limited by rt-thread thread API
rt_thread_mdelay(milli_secs.count());
}
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& abs_time)
{
auto now = Clock::now();
if (abs_time > now)
sleep_for(abs_time - now);
}
}
}
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-27 flybreak the first version.
*/
#include "thread"
#include "__utils.h"
#define _RT_NPROCS 0
namespace std
{
extern "C"
{
static void* execute_native_thread_routine(void *p)
{
thread::invoker_base* t = static_cast<thread::invoker_base*>(p);
thread::invoker_base_ptr local;
local.swap(t->this_ptr); // tranfer the ownership of the invoker into the thread entry
local->invoke();
return NULL;
}
}
void thread::start_thread(invoker_base_ptr b)
{
auto raw_ptr = b.get();
// transfer the ownership of the invoker to the new thread
raw_ptr->this_ptr = std::move(b);
int err = pthread_create(&_m_thr.__cpp_thread_t, NULL,
&execute_native_thread_routine, raw_ptr);
if (err)
{
raw_ptr->this_ptr.reset();
throw_system_error(err, "Failed to create a thread");
}
}
thread::~thread()
{
if (joinable()) // when either not joined or not detached
terminate();
}
void thread::join()
{
int err = EINVAL;
if (joinable())
err = pthread_join(native_handle(), NULL);
if (err)
{
throw_system_error(err, "thread::join failed");
}
_m_thr = id();
}
void thread::detach()
{
int err = EINVAL;
if (joinable())
err = pthread_detach(native_handle());
if (err)
{
throw_system_error(err, "thread::detach failed");
}
_m_thr = id();
}
// TODO: not yet actually implemented.
// The standard states that the returned value should only be considered a hint.
unsigned thread::hardware_concurrency() noexcept
{
int __n = _RT_NPROCS;
if (__n < 0)
__n = 0;
return __n;
}
}
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-27 flybreak the first version.
*/
#include "__utils.h"
#include <sys/time.h>
tick_clock::time_point tick_clock::now()
{
tick_clock::rep cur_tk = clock();
tick_clock::duration cur_time(cur_tk);
return tick_clock::time_point(cur_time);
}
real_time_clock::time_point real_time_clock::now() noexcept
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return time_point(duration(std::chrono::seconds(tp.tv_sec))
+ std::chrono::nanoseconds(tp.tv_nsec));
}