diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 050f2d1..a91a5f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,10 @@ add_subdirectory(core_test) #add_subdirectory(klotski_core) #include_directories(klotski_core) -#add_executable(cli main.c) -#target_link_libraries(cli PRIVATE klotski absl::flat_hash_map) +set(CMAKE_C_STANDARD 90) + +add_executable(klotski_cli main.c) +target_link_libraries(klotski_cli PRIVATE klotski-core) +#target_link_libraries(klotski_cli PRIVATE klotski absl::flat_hash_map) # -labsl_hash -labsl_city -labsl_low_level_hash -labsl_raw_hash_set diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bab542f..c0fb277 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -6,8 +6,11 @@ project(klotski-core VERSION 0.1.2 LANGUAGES CXX) add_compile_options(-fno-exceptions) +#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + include_directories(utils) +include_directories(all_cases) -add_library(${PROJECT_NAME} all_cases/basic_ranges.cc all_cases/all_cases.cc) +add_library(${PROJECT_NAME} all_cases/basic_ranges.cc all_cases/all_cases.cc ffi/all_cases.cc) -#add_executable(${PROJECT_NAME} main.cc all_cases/basic_ranges.cc all_cases/all_cases.cc) +add_executable(${PROJECT_NAME}_cli main.cc all_cases/basic_ranges.cc all_cases/all_cases.cc) diff --git a/src/core/all_cases/all_cases.h b/src/core/all_cases/all_cases.h index 375ebf4..c20e9e6 100644 --- a/src/core/all_cases/all_cases.h +++ b/src/core/all_cases/all_cases.h @@ -68,7 +68,7 @@ class BasicRanges { public: void Build() noexcept; const Ranges& Fetch() noexcept; - bool IsAvailable() const noexcept; + [[nodiscard]] bool IsAvailable() const noexcept; DISALLOW_COPY_AND_ASSIGN(BasicRanges); static BasicRanges& Instance() noexcept; @@ -86,10 +86,11 @@ private: class AllCases { public: void Build() noexcept; - bool IsAvailable() const noexcept; - const RangesUnion& Fetch() noexcept; void BuildParallel(Executor &&executor) noexcept; + const RangesUnion& Fetch() noexcept; + [[nodiscard]] bool IsAvailable() const noexcept; + DISALLOW_COPY_AND_ASSIGN(AllCases); static AllCases& Instance() noexcept; diff --git a/src/core/ffi/all_cases.cc b/src/core/ffi/all_cases.cc new file mode 100644 index 0000000..065a136 --- /dev/null +++ b/src/core/ffi/all_cases.cc @@ -0,0 +1,27 @@ +#include "klotski.h" +#include "all_cases.h" + +#include +#include + +using klotski::cases::AllCases; +using klotski::cases::BasicRanges; + +void all_cases_prebuild() { + BasicRanges::Instance().Build(); +} + +void all_cases_prebuild_async(executor_t executor, notifier_t callback) { + executor([](void *cb) { + all_cases_prebuild(); + ((notifier_t)cb)(); + }, (void*)callback); +} + +int is_all_cases_prebuild_available() { + if (BasicRanges::Instance().IsAvailable()) { + return KLOTSKI_TRUE; + } else { + return KLOTSKI_FALSE; + } +} diff --git a/src/core/ffi/klotski.h b/src/core/ffi/klotski.h new file mode 100644 index 0000000..db2e9af --- /dev/null +++ b/src/core/ffi/klotski.h @@ -0,0 +1,47 @@ +#ifndef KLOTSKI_H_ +#define KLOTSKI_H_ + +#ifdef __cplusplus +#include +#else +#include +#endif + +#define KLOTSKI_TRUE 1 +#define KLOTSKI_FALSE 0 + +#define EXTERN extern + +typedef void (*notifier_t)(); +typedef void (*executor_t)(void (*fn)(void*), void *arg); + +#ifdef __cplusplus +extern "C" { +#endif + +/// Execute all_cases pre-build work, blocking until the end of the build. If +/// the build has been completed, the function will return directly. +EXTERN void all_cases_prebuild(); + +/// Execute all_cases pre-build work, the function will return directly without +/// blocking, and will be notified with callback when completed. If the build +/// has been completed, the parameter function will still be called. +EXTERN void all_cases_prebuild_async(executor_t executor, notifier_t callback); + +/// Returns the pre-build status of all_cases without any block, value is 0 if +/// not completed, non-0 otherwise. +EXTERN int is_all_cases_prebuild_available(); + +//EXTERN void all_cases_build(); +//EXTERN int is_all_cases_available(); + +//extern const uint32_t ALL_CASES_SIZE; +//EXTERN_FUNC void export_all_cases(uint64_t *buffer); + +//extern const uint32_t BASIC_RANGES_SIZE; +//EXTERN_FUNC void export_basic_ranges(uint32_t *buffer); +#ifdef __cplusplus +} +#endif + +#endif /* KLOTSKI_H_ */ diff --git a/src/main.c b/src/main.c index 1f26c8e..8b9dfbb 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,59 @@ -#include "klotski.h" +#include +#include +#include +#include +#include "core/ffi/klotski.h" + +struct pthread_wrapper_t { + void (*fn)(void*); + void *arg; +}; + +void* pthread_wrapper(void *arg) { + + printf("enter wrapper\n"); + + struct pthread_wrapper_t *kk = (struct pthread_wrapper_t*)arg; + + kk->fn(kk->arg); + + return NULL; +} + +void callback() { + printf("enter callback\n"); +} + +void executor(void(*fn)(void*), void *arg) { + printf("executor receive task\n"); +// fn(arg); + + struct pthread_wrapper_t *kk = (struct pthread_wrapper_t*)malloc(sizeof(struct pthread_wrapper_t)); + + kk->fn = fn; + kk->arg = arg; + + pthread_t pp; + pthread_create(&pp, NULL, pthread_wrapper, (void*)kk); + +} int main() { - tmain(); + printf("prebuild available -> %d\n", is_all_cases_prebuild_available()); + +// printf("prebuild begin\n"); +// all_cases_prebuild(); +// printf("prebuild complete\n"); + + printf("prebuild begin\n"); + all_cases_prebuild_async(executor, callback); + printf("prebuild func exited\n"); + printf("prebuild available -> %d\n", is_all_cases_prebuild_available()); + + printf("start sleep 3s\n"); + sleep(3); + + printf("prebuild available -> %d\n", is_all_cases_prebuild_available()); + return 0; }