xenia-cpu-ppc-tests is now building on linux

This commit is contained in:
DrChat
2017-02-10 23:54:10 -06:00
parent 11ae05155d
commit d43e2c7ff8
21 changed files with 471 additions and 51 deletions

View File

@@ -0,0 +1,46 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2017 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/clock.h"
#include <sys/time.h>
#include <time.h>
namespace xe {
uint64_t Clock::host_tick_frequency() {
timespec res;
clock_getres(CLOCK_MONOTONIC_RAW, &res);
return uint64_t(res.tv_sec) + uint64_t(res.tv_nsec) * 1000000000ull;
}
uint64_t Clock::QueryHostTickCount() {
timespec res;
clock_gettime(CLOCK_MONOTONIC_RAW, &res);
return uint64_t(res.tv_sec) + uint64_t(res.tv_nsec) * 1000000000ull;
}
uint64_t Clock::QueryHostSystemTime() {
struct timeval tv;
gettimeofday(&tv, NULL);
uint64_t ret = tv.tv_usec;
ret /= 1000; // usec -> msec
ret += (tv.tv_sec * 1000); // sec -> msec
return ret;
}
uint32_t Clock::QueryHostUptimeMillis() {
return uint32_t(QueryHostTickCount() / (host_tick_frequency() / 1000));
}
} // namespace xe

View File

@@ -0,0 +1,33 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2017 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/debugging.h"
#include <signal.h>
#include "xenia/base/string_buffer.h"
namespace xe {
namespace debugging {
bool IsDebuggerAttached() { return false; }
void Break() { raise(SIGTRAP); }
void DebugPrint(const char* fmt, ...) {
StringBuffer buff;
va_list va;
va_start(va, fmt);
buff.AppendVarargs(fmt, va);
va_end(va);
// OutputDebugStringA(buff.GetString());
}
} // namespace debugging
} // namespace xe

View File

@@ -0,0 +1,18 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2017 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/exception_handler.h"
namespace xe {
// TODO(DrChat): Exception handling on linux.
void ExceptionHandler::Install(Handler fn, void* data) {}
void ExceptionHandler::Uninstall(Handler fn, void* data) {}
} // namespace xe

View File

@@ -0,0 +1,63 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2017 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/filesystem.h"
#include "xenia/base/logging.h"
#include "xenia/base/string.h"
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace xe {
namespace filesystem {
bool PathExists(const std::wstring& path) {
struct stat st;
return stat(xe::to_string(path).c_str(), &st) == 0;
}
FILE* OpenFile(const std::wstring& path, const char* mode) {
auto fixed_path = xe::fix_path_separators(path);
return fopen(xe::to_string(fixed_path).c_str(), mode);
}
bool CreateFolder(const std::wstring& path) {
return mkdir(xe::to_string(path).c_str(), 0774);
}
std::vector<FileInfo> ListFiles(const std::wstring& path) {
std::vector<FileInfo> result;
DIR* dir = opendir(xe::to_string(path).c_str());
if (!dir) {
return result;
}
while (auto ent = readdir(dir)) {
FileInfo info;
std::memset(&info, 0, sizeof(info));
if (ent->d_type == DT_DIR) {
info.type = FileInfo::Type::kDirectory;
info.total_size = 0;
} else {
info.type = FileInfo::Type::kFile;
info.total_size = 0; // TODO(DrChat): Find a way to get this
}
info.name = xe::to_wstring(ent->d_name);
result.push_back(info);
}
return result;
}
} // namespace filesystem
} // namespace xe

View File

@@ -53,7 +53,6 @@ class Logger {
file_ = xe::filesystem::OpenFile(file_path, "wt");
}
flush_event_ = xe::threading::Event::CreateAutoResetEvent(false);
write_thread_ =
xe::threading::Thread::Create({}, [this]() { WriteThread(); });
write_thread_->set_name("xe::FileLogSink Writer");
@@ -61,7 +60,6 @@ class Logger {
~Logger() {
running_ = false;
flush_event_->Set();
xe::threading::Wait(write_thread_.get(), true);
fflush(file_);
fclose(file_);
@@ -113,9 +111,6 @@ class Logger {
continue;
}
}
// Kick the consumer thread
flush_event_->Set();
}
private:
@@ -139,6 +134,7 @@ class Logger {
void WriteThread() {
RingBuffer rb(buffer_, kBufferSize);
uint32_t idle_loops = 0;
while (running_) {
bool did_write = false;
rb.set_write_offset(write_tail_);
@@ -197,9 +193,16 @@ class Logger {
if (FLAGS_flush_log) {
fflush(file_);
}
idle_loops = 0;
} else {
if (idle_loops > 1000) {
// Introduce a waiting period.
xe::threading::Sleep(std::chrono::milliseconds(50));
}
idle_loops++;
}
xe::threading::Wait(flush_event_.get(), true,
std::chrono::milliseconds(1));
}
}
@@ -210,7 +213,6 @@ class Logger {
FILE* file_ = nullptr;
std::atomic<bool> running_;
std::unique_ptr<xe::threading::Event> flush_event_;
std::unique_ptr<xe::threading::Thread> write_thread_;
};

View File

@@ -74,4 +74,10 @@ std::unique_ptr<MappedMemory> MappedMemory::Open(const std::wstring& path,
return std::move(mm);
}
std::unique_ptr<ChunkedMappedMemoryWriter> ChunkedMappedMemoryWriter::Open(
const std::wstring& path, size_t chunk_size, bool low_address_space) {
// TODO(DrChat)
return nullptr;
}
} // namespace xe

View File

@@ -0,0 +1,57 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2017 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/memory.h"
#include <unistd.h>
namespace xe {
namespace memory {
size_t page_size() { return getpagesize(); }
size_t allocation_granularity() { return page_size(); }
void* AllocFixed(void* base_address, size_t length,
AllocationType allocation_type, PageAccess access) {
return nullptr;
}
bool DeallocFixed(void* base_address, size_t length,
DeallocationType deallocation_type) {
return false;
}
bool Protect(void* base_address, size_t length, PageAccess access,
PageAccess* out_old_access) {
return false;
}
bool QueryProtect(void* base_address, size_t& length, PageAccess& access_out) {
return false;
}
FileMappingHandle CreateFileMappingHandle(std::wstring path, size_t length,
PageAccess access, bool commit) {
return nullptr;
}
void CloseFileMappingHandle(FileMappingHandle handle) {}
void* MapFileView(FileMappingHandle handle, void* base_address, size_t length,
PageAccess access, size_t file_offset) {
return nullptr;
}
bool UnmapFileView(FileMappingHandle handle, void* base_address,
size_t length) {
return false;
}
} // namespace memory
} // namespace xe

View File

View File

@@ -7,20 +7,24 @@
******************************************************************************
*/
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/threading.h"
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
namespace xe {
namespace threading {
// uint64_t ticks() { return mach_absolute_time(); }
// uint32_t current_thread_id() {
// mach_port_t tid = pthread_mach_thread_np(pthread_self());
// return static_cast<uint32_t>(tid);
// }
uint32_t current_thread_system_id() {
return static_cast<uint32_t>(syscall(SYS_gettid));
}
void set_name(const std::string& name) {
pthread_setname_np(pthread_self(), name.c_str());
@@ -36,5 +40,103 @@ void Sleep(std::chrono::microseconds duration) {
// TODO(benvanik): spin while rmtp >0?
}
template <typename T>
class PosixHandle : public T {
public:
explicit PosixHandle(pthread_t handle) : handle_(handle) {}
~PosixHandle() override {}
protected:
void* native_handle() const override {
return reinterpret_cast<void*>(handle_);
}
pthread_t handle_;
};
class PosixThread : public PosixHandle<Thread> {
public:
explicit PosixThread(pthread_t handle) : PosixHandle(handle) {}
~PosixThread() = default;
void set_name(std::string name) override {
// TODO(DrChat)
}
uint32_t system_id() const override { return 0; }
// TODO(DrChat)
uint64_t affinity_mask() override { return 0; }
void set_affinity_mask(uint64_t mask) override { assert_always(); }
int priority() override {
int policy;
struct sched_param param;
int ret = pthread_getschedparam(handle_, &policy, &param);
if (ret != 0) {
return -1;
}
return param.sched_priority;
}
void set_priority(int new_priority) override {
struct sched_param param;
param.sched_priority = new_priority;
int ret = pthread_setschedparam(handle_, SCHED_FIFO, &param);
}
// TODO(DrChat)
void QueueUserCallback(std::function<void()> callback) override {
assert_always();
}
bool Resume(uint32_t* out_new_suspend_count = nullptr) override {
assert_always();
return false;
}
bool Suspend(uint32_t* out_previous_suspend_count = nullptr) override {
assert_always();
return false;
}
void Terminate(int exit_code) override {}
};
thread_local std::unique_ptr<PosixThread> current_thread_ = nullptr;
struct ThreadStartData {
std::function<void()> start_routine;
};
void* ThreadStartRoutine(void* parameter) {
current_thread_ = std::make_unique<PosixThread>(::pthread_self());
auto start_data = reinterpret_cast<ThreadStartData*>(parameter);
start_data->start_routine();
delete start_data;
return 0;
}
std::unique_ptr<Thread> Thread::Create(CreationParameters params,
std::function<void()> start_routine) {
auto start_data = new ThreadStartData({std::move(start_routine)});
assert_false(params.create_suspended);
pthread_t handle;
pthread_attr_t attr;
pthread_attr_init(&attr);
int ret = pthread_create(&handle, &attr, ThreadStartRoutine, start_data);
if (ret != 0) {
// TODO(benvanik): pass back?
auto last_error = errno;
XELOGE("Unable to pthread_create: %d", last_error);
delete start_data;
return nullptr;
}
return std::make_unique<PosixThread>(handle);
}
} // namespace threading
} // namespace xe