mirror of
https://github.com/RPCSX/orbis-kernel.git
synced 2024-11-23 11:19:42 +00:00
[logs] Basic implementation
This commit is contained in:
parent
0a6f130e95
commit
ab5a289045
@ -57,6 +57,8 @@ add_library(obj.orbis-kernel OBJECT
|
||||
src/sys/sys_vfs.cpp
|
||||
src/sys/sys_vm_mmap.cpp
|
||||
src/sys/sys_vm_unix.cpp
|
||||
|
||||
src/utils/Logs.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(obj.orbis-kernel PUBLIC orbis::kernel::config)
|
||||
@ -76,4 +78,3 @@ add_library(orbis::kernel-shared ALIAS orbis-kernel-shared)
|
||||
|
||||
target_link_libraries(orbis-kernel PUBLIC obj.orbis-kernel)
|
||||
target_link_libraries(orbis-kernel-shared PUBLIC obj.orbis-kernel)
|
||||
|
||||
|
104
include/orbis/utils/Logs.hpp
Normal file
104
include/orbis/utils/Logs.hpp
Normal file
@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
namespace orbis {
|
||||
inline namespace logs {
|
||||
enum class LogLevel : unsigned char {
|
||||
Always,
|
||||
Fatal,
|
||||
Error,
|
||||
Todo,
|
||||
Success,
|
||||
Warning,
|
||||
Notice,
|
||||
Trace
|
||||
};
|
||||
|
||||
// Currently enabled log level
|
||||
inline std::atomic<LogLevel> logs_level = LogLevel::Notice;
|
||||
|
||||
template <typename T, typename = void> struct log_class_string {
|
||||
static const T &get_object(const void *arg) {
|
||||
return *static_cast<const T *>(arg);
|
||||
}
|
||||
static void format(std::string &out, const void *arg);
|
||||
};
|
||||
|
||||
template <> struct log_class_string<const void *, void> {
|
||||
static void format(std::string &out, const void *arg);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct log_class_string<T *, void> : log_class_string<const void *, void> {};
|
||||
|
||||
template <> struct log_class_string<const char *, void> {
|
||||
static void format(std::string &out, const void *arg);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct log_class_string<char *, void> : log_class_string<const char *> {};
|
||||
|
||||
template <>
|
||||
struct log_class_string<const char8_t *, void>
|
||||
: log_class_string<const char *> {};
|
||||
|
||||
template <>
|
||||
struct log_class_string<char8_t *, void> : log_class_string<const char8_t *> {};
|
||||
|
||||
template <typename... Args>
|
||||
using log_args_t = const void *(&&)[sizeof...(Args) + 1];
|
||||
|
||||
struct log_type_info {
|
||||
decltype(&log_class_string<int>::format) log_string;
|
||||
|
||||
template <typename T> static constexpr log_type_info make() {
|
||||
return log_type_info{
|
||||
&log_class_string<T>::format,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
constexpr const log_type_info type_info_v[sizeof...(Args) + 1]{
|
||||
log_type_info::make<std::decay_t<Args>>()...};
|
||||
|
||||
void _orbis_log_print(LogLevel lvl, const char *msg, std::string_view names,
|
||||
const log_type_info *sup, ...);
|
||||
|
||||
template <typename... Args>
|
||||
void _orbis_log_impl(LogLevel lvl, const char *msg, const char *names,
|
||||
const Args &...args) {
|
||||
// Fast filtering
|
||||
if (logs_level.load(std::memory_order::relaxed) < lvl)
|
||||
return;
|
||||
|
||||
_orbis_log_print(lvl, msg, names, type_info_v<Args...>,
|
||||
static_cast<const void *>(&args)...);
|
||||
}
|
||||
|
||||
} // namespace logs
|
||||
} // namespace orbis
|
||||
|
||||
#define ORBIS_LOG_FATAL(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Fatal, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_ERROR(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Error, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_TODO(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Todo, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_SUCCESS(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Success, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_WARNING(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Warning, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_NOTICE(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Notice, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
||||
#define ORBIS_LOG_TRACE(msg, ...) \
|
||||
::orbis::_orbis_log_impl(::orbis::LogLevel::Trace, (msg), #__VA_ARGS__, \
|
||||
##__VA_ARGS__)
|
@ -1,4 +1,5 @@
|
||||
#include "sys/sysproto.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
|
||||
orbis::SysResult orbis::sys_sync(Thread *thread) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_quotactl(Thread *thread, ptr<char> path, sint cmd, sint uid, caddr_t arg) { return ErrorCode::NOSYS; }
|
||||
@ -9,6 +10,7 @@ orbis::SysResult orbis::sys_fchdir(Thread *thread, sint fd) { return ErrorCode::
|
||||
orbis::SysResult orbis::sys_chdir(Thread *thread, ptr<char> path) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_chroot(Thread *thread, ptr<char> path) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_open(Thread *thread, ptr<char> path, sint flags, sint mode) {
|
||||
ORBIS_LOG_NOTICE("sys_open", path, flags, mode);
|
||||
if (auto open = thread->tproc->ops->open) {
|
||||
return open(thread, path, flags, mode);
|
||||
}
|
||||
|
172
src/utils/Logs.cpp
Normal file
172
src/utils/Logs.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include "utils/Logs.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
|
||||
static void append_hex(std::string &out, std::uintmax_t value) {
|
||||
std::ostringstream buf;
|
||||
buf << "0x" << std::hex << value;
|
||||
out += buf.str();
|
||||
}
|
||||
|
||||
namespace orbis::logs {
|
||||
void log_class_string<const void *>::format(std::string &out, const void *arg) {
|
||||
const void *ptr = *reinterpret_cast<const void *const *>(arg);
|
||||
append_hex(out, reinterpret_cast<std::uintptr_t>(ptr));
|
||||
}
|
||||
|
||||
void log_class_string<const char *>::format(std::string &out, const void *arg) {
|
||||
out += *reinterpret_cast<const char *const *>(arg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::string>::format(std::string &out, const void *arg) {
|
||||
out += get_object(arg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::string_view>::format(std::string &out,
|
||||
const void *arg) {
|
||||
out += get_object(arg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::vector<char>>::format(std::string &out,
|
||||
const void *arg) {
|
||||
const std::vector<char> &obj = get_object(arg);
|
||||
out.append(obj.cbegin(), obj.cend());
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::u8string>::format(std::string &out,
|
||||
const void *arg) {
|
||||
const std::u8string &obj = get_object(arg);
|
||||
out.append(obj.cbegin(), obj.cend());
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::u8string_view>::format(std::string &out,
|
||||
const void *arg) {
|
||||
const std::u8string_view &obj = get_object(arg);
|
||||
out.append(obj.cbegin(), obj.cend());
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<std::vector<char8_t>>::format(std::string &out,
|
||||
const void *arg) {
|
||||
const std::vector<char8_t> &obj = get_object(arg);
|
||||
out.append(obj.cbegin(), obj.cend());
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<char>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<unsigned char>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<unsigned char>::format(std::string &out,
|
||||
const void *arg) {
|
||||
append_hex(out, get_object(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<signed char>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<unsigned char>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<short>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<unsigned short>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<ushort>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, get_object(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<int>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<uint>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<uint>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, get_object(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<long>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<unsigned long>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<ulong>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, get_object(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<long long>::format(std::string &out, const void *arg) {
|
||||
append_hex(out, static_cast<unsigned long long>(get_object(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<unsigned long long>::format(std::string &out,
|
||||
const void *arg) {
|
||||
append_hex(out, get_object(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<float>::format(std::string &out, const void *arg) {
|
||||
std::ostringstream buf(out, std::ios_base::ate);
|
||||
buf << get_object(arg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<double>::format(std::string &out, const void *arg) {
|
||||
std::ostringstream buf(out, std::ios_base::ate);
|
||||
buf << get_object(arg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void log_class_string<bool>::format(std::string &out, const void *arg) {
|
||||
out += get_object(arg) ? "1" : "0";
|
||||
}
|
||||
|
||||
void _orbis_log_print(LogLevel lvl, const char *msg, std::string_view names,
|
||||
const log_type_info *sup, ...) {
|
||||
|
||||
/*constinit thread_local*/ std::string text;
|
||||
/*constinit thread_local*/ std::vector<const void *> args;
|
||||
|
||||
std::size_t args_count = 0;
|
||||
for (auto v = sup; v && v->log_string; v++)
|
||||
args_count++;
|
||||
|
||||
text.reserve(50000);
|
||||
args.resize(args_count);
|
||||
|
||||
va_list c_args;
|
||||
va_start(c_args, sup);
|
||||
for (const void *&arg : args)
|
||||
arg = va_arg(c_args, const void *);
|
||||
va_end(c_args);
|
||||
|
||||
text += msg;
|
||||
text += "(";
|
||||
for (std::size_t i = 0; i < args_count; i++) {
|
||||
if (i)
|
||||
text += ", ";
|
||||
names.remove_prefix(names.find_first_not_of(" \t\n\r"));
|
||||
std::string_view name = names.substr(0, names.find_first_of(","));
|
||||
names.remove_prefix(name.size() + 1);
|
||||
text += name;
|
||||
text += "=";
|
||||
sup[i].log_string(text, args[i]);
|
||||
}
|
||||
text += ")";
|
||||
|
||||
std::fprintf(stderr, "%s\n", text.c_str());
|
||||
}
|
||||
} // namespace orbis::logs
|
Loading…
Reference in New Issue
Block a user