#include "thread.hpp" #include // va_start, va_end #include #include // strlen extern "C" { #include // _exit, getpid #include #include // dlopen, dlsym #include // backtrace, messages } #include #include using thrdlib::thread_t; thread_t (*thrdlib::create)( void (*main)( thread_t ) ) = nullptr; void (*thrdlib::join)( thread_t handle ) = nullptr; void (*thrdlib::park)( thread_t handle ) = nullptr; void (*thrdlib::unpark)( thread_t handle ) = nullptr; void (*thrdlib::yield)( void ) = nullptr; void (*lib_clean)(void) = nullptr; typedef void (*fptr_t)(); static fptr_t open_symbol( void * library, const char * symbol, bool required ) { void * ptr = dlsym( library, symbol ); const char * error = dlerror(); if ( required && error ) { std::cerr << "Fetching symbol '" << symbol << "' failed with error '" << error << "'\n"; std::abort(); } return (fptr_t)ptr; } //-------------------- // Basic kernel features void thrdlib::init( const char * name, int procs ) { std::string file = __FILE__; std::size_t found = file.find_last_of("/"); std::string libname = file.substr(0,found+1) + name + ".so"; std::cout << "Use framework " << name << "(" << libname << ")\n"; void * library = dlopen( libname.c_str(), RTLD_NOW ); if ( const char * error = dlerror() ) { std::cerr << "Could not open library '" << libname << "' from name '" << name <<"'\n"; std::cerr << "Error was : '" << error << "'\n"; std::abort(); } void (*lib_init)( int ) = (void (*)( int ))open_symbol( library, "thrdlib_init", false ); lib_clean = open_symbol( library, "thrdlib_clean" , false ); thrdlib::create = (typeof(thrdlib::create))open_symbol( library, "thrdlib_create", true ); thrdlib::join = (typeof(thrdlib::join ))open_symbol( library, "thrdlib_join" , true ); thrdlib::park = (typeof(thrdlib::park ))open_symbol( library, "thrdlib_park" , true ); thrdlib::unpark = (typeof(thrdlib::unpark))open_symbol( library, "thrdlib_unpark", true ); thrdlib::yield = (typeof(thrdlib::yield ))open_symbol( library, "thrdlib_yield" , true ); lib_init( procs ); } void thrdlib::clean( void ) { if(lib_clean) lib_clean(); }