From c676dfa238248350d6d39fff2a7082e82de45c15 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Thu, 31 Dec 2020 21:58:53 -0600 Subject: [PATCH] Progress: begin writing thread support and fix a problem in fss_extended_read project. This is an end of the year progress commit (at least end of the year in my timezone). The thread functionality is only barely implemented and one should expect a lot of future changes. --- build/level_0/settings | 6 +- build/level_1/settings | 2 +- build/level_2/settings | 2 +- build/monolithic/settings | 6 +- build/scripts/bootstrap-example.sh | 2 +- documents/threads.txt | 10 ++ level_0/f_status/c/status.h | 2 + level_0/f_thread/c/private-thread.c | 31 ++++ level_0/f_thread/c/private-thread.h | 69 +++++++++ level_0/f_thread/c/thread-common.h | 124 ++++++++++++++++ level_0/f_thread/c/thread.c | 114 +++++++++++++++ level_0/f_thread/c/thread.h | 158 +++++++++++++++++++++ level_0/f_thread/data/build/defines | 2 + level_0/f_thread/data/build/dependencies | 5 + level_0/f_thread/data/build/settings | 55 +++++++ level_1/fl_status/c/status.c | 6 + level_1/fl_status/c/status.h | 4 + level_2/fll_status/c/status.c | 10 ++ level_3/controller/data/build/dependencies | 1 + level_3/controller/data/build/settings | 4 +- .../c/private-fss_extended_read.h | 4 +- 21 files changed, 604 insertions(+), 13 deletions(-) create mode 100644 documents/threads.txt create mode 100644 level_0/f_thread/c/private-thread.c create mode 100644 level_0/f_thread/c/private-thread.h create mode 100644 level_0/f_thread/c/thread-common.h create mode 100644 level_0/f_thread/c/thread.c create mode 100644 level_0/f_thread/c/thread.h create mode 100644 level_0/f_thread/data/build/defines create mode 100644 level_0/f_thread/data/build/dependencies create mode 100644 level_0/f_thread/data/build/settings diff --git a/build/level_0/settings b/build/level_0/settings index 210815a..8f5dda5 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c build_libraries -lc -lcap build_libraries-level -build_sources_library account.c private-account.c capability.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c process.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c +build_sources_library account.c private-account.c capability.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c serialize.c private-serialize.c signal.c socket.c thread.c private-thread.c utf.c private-utf.c build_sources_program -build_sources_headers account.h account-common.h capability.h capability-common.h color.h console.h console-common.h control_group.h control_group-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h process.h process-common.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h type.h type_array.h utf.h utf-common.h +build_sources_headers account.h account-common.h capability.h capability-common.h color.h console.h console-common.h control_group.h control_group-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h thread.h thread-common.h type.h type_array.h utf.h utf-common.h build_sources_script build_sources_setting build_script yes @@ -47,7 +47,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always +flags_all -z now -g -fdiagnostics-color=always -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/level_1/settings b/build/level_1/settings index 94f4a28..5c4c216 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -46,7 +46,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always +flags_all -z now -g -fdiagnostics-color=always -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/level_2/settings b/build/level_2/settings index 4ba2922..b2a7158 100644 --- a/build/level_2/settings +++ b/build/level_2/settings @@ -47,7 +47,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always +flags_all -z now -g -fdiagnostics-color=always -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/monolithic/settings b/build/monolithic/settings index 093c43e..b418701 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c build_libraries -lc -lcap build_libraries-monolithic -build_sources_library level_0/account.c level_0/private-account.c level_0/capability.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/process.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/control_group.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/private-print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/type.c level_1/private-type.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/control_group.c level_2/environment.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c +build_sources_library level_0/account.c level_0/private-account.c level_0/capability.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/thread.c level_0/private-thread.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/control_group.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/private-print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/type.c level_1/private-type.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/control_group.c level_2/environment.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c build_sources_program -build_sources_headers level_0/account.h level_0/account-common.h level_0/capability.h level_0/capability-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/control_group.h level_0/control_group-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/process.h level_0/process-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/control_group.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/control_group.h level_2/environment.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h +build_sources_headers level_0/account.h level_0/account-common.h level_0/capability.h level_0/capability-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/control_group.h level_0/control_group-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/thread.h level_0/thread-common.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/control_group.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/control_group.h level_2/environment.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h build_sources_script build_sources_setting build_script yes @@ -47,7 +47,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always +flags_all -z now -g -fdiagnostics-color=always -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/scripts/bootstrap-example.sh b/build/scripts/bootstrap-example.sh index 4a578e4..7f34fc5 100644 --- a/build/scripts/bootstrap-example.sh +++ b/build/scripts/bootstrap-example.sh @@ -41,7 +41,7 @@ if [[ $1 == "individual" ]] ; then bash build/scripts/package.sh $verbose $color build -i if [[ $? -eq 0 ]] ; then - for i in f_type f_status f_memory f_string f_utf f_account f_capability f_color f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_path f_pipe f_print f_process f_serialize f_signal f_socket fl_color fl_console fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_control_group fll_environment fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do + for i in f_type f_status f_memory f_string f_utf f_account f_capability f_color f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_path f_pipe f_print f_serialize f_signal f_socket f_thread fl_color fl_console fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_control_group fll_environment fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do echo && echo "Processing $i." && cd package/individual/$i-$2/ && diff --git a/documents/threads.txt b/documents/threads.txt new file mode 100644 index 0000000..aaebabf --- /dev/null +++ b/documents/threads.txt @@ -0,0 +1,10 @@ +# fss-002 + +Threads Documentation: + With the inclusion of the f_thread project, the Featureless Linux Library supports and uses threads by default. + This essentially adds -pthread to all level and monolithic builds with all projects depending on f_thread requiring passing -pthread. + + To compile without this thread support, remove all occurances of "-pthread" from each of the build settings files. + Be sure to remove f_thread project from the compile list as well (which can be found either in the individual projects build settings file or the appropriate level or monolithic build settings file). + + Any project or library depending on f_thread must have -pthread passed to guarantee a correct and valid compilation. diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index d16afd3..fc02664 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -269,6 +269,8 @@ extern "C" { F_supported_not, F_syntax, F_syntax_not, + F_thread, + F_thread_not, F_user, F_user_not, F_utf, diff --git a/level_0/f_thread/c/private-thread.c b/level_0/f_thread/c/private-thread.c new file mode 100644 index 0000000..d3a6273 --- /dev/null +++ b/level_0/f_thread/c/private-thread.c @@ -0,0 +1,31 @@ +#include "thread.h" +#include "private-thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_delete_) + f_return_status private_f_thread_sets_delete(f_thread_sets_t *thread_sets) { + f_status_t status = F_none; + + f_macro_thread_sets_t_delete(status, (*thread_sets)); + + return status; + } +#endif // !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_delete_) + +#if !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_increase_) || !defined(_di_f_thread_sets_increase_by_) + f_return_status private_f_thread_sets_resize(const f_array_length_t length, f_thread_sets_t *thread_sets) { + f_status_t status = F_none; + + f_macro_thread_sets_t_resize(status, (*thread_sets), length); + + return status; + } +#endif // !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_increase_) || !defined(_di_f_thread_sets_increase_by_) + + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_thread/c/private-thread.h b/level_0/f_thread/c/private-thread.h new file mode 100644 index 0000000..4163516 --- /dev/null +++ b/level_0/f_thread/c/private-thread.h @@ -0,0 +1,69 @@ +/** + * FLL - Level 1 + * + * Project: String + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_thread_h +#define _PRIVATE_F_thread_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation of f_thread_sets_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param thread_sets + * The thread_sets to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_threads_t_delete(). + * + * @see f_macro_threads_t_delete() + * @see f_thread_sets_decrease() + * @see f_thread_sets_decrease_by() + * @see f_thread_sets_delete() + */ +#if !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_delete_) + extern f_return_status private_f_thread_sets_delete(f_thread_sets_t *thread_sets) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param thread_sets + * The thread_sets to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_threads_t_resize(). + * + * @see f_macro_threads_t_resize() + * @see f_thread_sets_decrease() + * @see f_thread_sets_decrease_by() + * @see f_thread_sets_increase() + * @see f_thread_sets_increase_by() + */ +#if !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_increase_) || !defined(_di_f_thread_sets_increase_by_) + extern f_return_status private_f_thread_sets_resize(const f_array_length_t length, f_thread_sets_t *thread_sets) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_sets_decrease_) || !defined(_di_f_thread_sets_decrease_by_) || !defined(_di_f_thread_sets_increase_) || !defined(_di_f_thread_sets_increase_by_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_thread_h diff --git a/level_0/f_thread/c/thread-common.h b/level_0/f_thread/c/thread-common.h new file mode 100644 index 0000000..3ac5b2f --- /dev/null +++ b/level_0/f_thread/c/thread-common.h @@ -0,0 +1,124 @@ +/** + * FLL - Level 0 + * + * Project: Thread + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Defines common data to be used for/by POSIX thread related functionality. + * + * This is auto-included by thread.h and should not need to be explicitly included. + */ +#ifndef _F_thread_common_h +#define _F_thread_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A structure containing basic thread information. + * + * attributes: The thread attributes (which is a union). + * id: The thread identifier. + * result: The result of the thread on exit. + */ +#ifndef _di_f_thread_set_t_ + typedef struct { + pthread_attr_t attributes; + pthread_t id; + int result; + } f_thread_set_t; + + #define f_thread_set_t_initialize { { 0 }, 0, 0 } + + // This does not clear the thread.attributes.__size array (may need to memset() against a sizeof(pthread_attr_t)). + #define f_macro_thread_set_t_clear(thread) \ + thread.attributes.__align = 0; \ + thread.id = 0; +#endif // _di_f_thread_set_t_ + +/** + * An array of f_thread_set_t. + * + * array: the array of f_thread_set_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_sets_t_ + typedef struct { + f_thread_set_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_sets_t; + + #define f_thread_sets_t_initialize { 0, 0, 0 } + + #define f_macro_thread_sets_t_clear(threads) \ + threads.array = 0; \ + threads.size = 0; \ + threads.used = 0; + + #define f_macro_threads_new(status, threads, length) \ + f_macro_thread_sets_t_clear(threads) \ + status = f_memory_new((void **) & threads.array, sizeof(f_thread_set_t), length); \ + if (status == F_none) { \ + threads.size = length; \ + threads.used = 0; \ + } + + #define f_macro_thread_sets_t_delete(status, threads) \ + status = f_memory_delete((void **) & threads.array, sizeof(f_thread_set_t), threads.size); \ + if (status == F_none) { \ + threads.used = 0; \ + threads.size = 0; \ + } + + #define f_macro_thread_sets_t_destroy(status, threads) \ + status = f_memory_destroy((void **) & threads.array, sizeof(f_thread_set_t), threads.size); \ + if (status == F_none) { \ + threads.used = 0; \ + threads.size = 0; \ + } + + #define f_macro_thread_sets_t_delete_simple(threads) \ + f_memory_delete((void **) & threads.array, sizeof(f_thread_set_t), threads.size); \ + threads.used = 0; \ + threads.size = 0; + + #define f_macro_thread_sets_t_destroy_simple(threads) \ + f_memory_destroy((void **) & threads.array, sizeof(f_thread_set_t), threads.size); \ + threads.used = 0; \ + threads.size = 0; + + #define f_macro_thread_sets_t_resize(status, threads, new_length) \ + status = f_memory_resize((void **) & threads.array, sizeof(f_thread_set_t), threads.size, new_length); \ + if (status == F_none) { \ + if (new_length > threads.size) { \ + for (f_array_length_t _macro__i = threads.size; _macro__i < new_length; _macro__i++) { \ + memset(&threads.array[_macro__i], 0, sizeof(f_thread_set_t)); \ + } \ + } \ + threads.size = new_length; \ + if (threads.used > threads.size) threads.used = new_length; \ + } + + #define f_macro_thread_sets_t_adjust(status, threads, new_length) \ + status = f_memory_adjust((void **) & threads.array, sizeof(f_thread_set_t), threads.size, new_length); \ + if (status == F_none) { \ + if (new_length > threads.size) { \ + for (f_array_length_t _macro__i = threads.size; _macro__i < new_length; _macro__i++) { \ + memset(&threads.array[_macro__i], 0, sizeof(f_thread_set_t)); \ + } \ + } \ + threads.size = new_length; \ + if (threads.used > threads.size) threads.used = new_length; \ + } +#endif // _di_f_thread_sets_t_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_thread_common_h diff --git a/level_0/f_thread/c/thread.c b/level_0/f_thread/c/thread.c new file mode 100644 index 0000000..4a1e20a --- /dev/null +++ b/level_0/f_thread/c/thread.c @@ -0,0 +1,114 @@ +#include "thread.h" +#include "private-thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_thread_create_ + f_return_status f_thread_create(const pthread_attr_t *attribute, pthread_t *id, void *(*routine) (void *), void *argument) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + if (!id) return F_status_set_error(F_parameter); + if (!routine) return F_status_set_error(F_parameter); + if (!argument) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_create(id, attribute, routine, argument); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == EPERM) return F_status_set_error(F_prohibited); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_create_ + +#ifndef _di_f_thread_sets_decrease_ + f_return_status f_thread_sets_decrease(f_thread_sets_t *thread_sets) { + #ifndef _di_level_0_parameter_checking_ + if (!thread_sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (thread_sets->size > 1) { + return private_f_thread_sets_resize(thread_sets->size - 1, thread_sets); + } + + return private_f_thread_sets_delete(thread_sets); + } +#endif // _di_f_thread_sets_decrease_ + +#ifndef _di_f_thread_sets_decrease_by_ + f_return_status f_thread_sets_decrease_by(const f_array_length_t amount, f_thread_sets_t *thread_sets) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!thread_sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (thread_sets->size - amount > 0) { + return private_f_thread_sets_resize(thread_sets->size - amount, thread_sets); + } + + return private_f_thread_sets_delete(thread_sets); + } +#endif // _di_f_thread_sets_decrease_by_ + +#ifndef _di_f_thread_sets_delete_ + f_return_status f_thread_sets_delete(f_thread_sets_t *thread_sets) { + #ifndef _di_level_0_parameter_checking_ + if (!thread_sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_sets_delete(thread_sets); + } +#endif // _di_f_thread_sets_delete_ + +#ifndef _di_f_thread_sets_increase_ + f_return_status f_thread_sets_increase(f_thread_sets_t *thread_sets) { + #ifndef _di_level_0_parameter_checking_ + if (!thread_sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (thread_sets->used + 1 > thread_sets->size) { + f_array_length_t size = thread_sets->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (thread_sets->used + 1 > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + size = f_array_length_t_size; + } + + return private_f_thread_sets_resize(size, thread_sets); + } + + return F_none; + } +#endif // _di_f_thread_sets_increase_ + +#ifndef _di_f_thread_sets_increase_by_ + f_return_status f_thread_sets_increase_by(const f_array_length_t amount, f_thread_sets_t *thread_sets) { + #ifndef _di_level_0_parameter_checking_ + if (!thread_sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (thread_sets->used + amount > thread_sets->size) { + if (thread_sets->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_sets_resize(thread_sets->used + amount, thread_sets); + } + + return F_none; + } +#endif // _di_f_thread_sets_increase_by_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_thread/c/thread.h b/level_0/f_thread/c/thread.h new file mode 100644 index 0000000..93271c1 --- /dev/null +++ b/level_0/f_thread/c/thread.h @@ -0,0 +1,158 @@ +/** + * FLL - Level 0 + * + * Project: Thread + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Provides POSIX thread_sets related functionality. + */ +#ifndef _F_thread_h +#define _F_thread_h + +// libc includes +#include +#include +#include + +// fll-0 includes +#include +#include +#include + +// fll-0 thread includes +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the user account by the user id. + * + * @param attribute + * The thread attributes. + * @param id + * The thread ID. + * This gets populated with the created thread ID (aka: the "child" thread). + * @param routine + * The function to execute. + * @param argument + * The structure containing all arguments to pass to the routine. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if not allowed to set the scheduling policy and parameters specified in attribute. + * F_resource_not (with error bit) if there are not enough resources to create another thread. + * F_failure (with error bit) on any other error. + * + * @see pthread_create() + */ +#ifndef _di_f_thread_create_ + extern f_return_status f_thread_create(const pthread_attr_t *attribute, pthread_t *id, void *(*routine) (void *), void *argument); +#endif // _di_f_thread_create_ + +/** + * Resize the thread set array to a smaller size, by 1. + * + * This will shrink the size by size - 1. + * This will not shrink the size to less than 0. + * + * @param thread_sets + * The string array to resize. + * + * @return + * F_none on success. + * F_memory_allocation (with error bit) on memory allocation error. + * F_memory_reallocation (with error bit) on memory reallocation error. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_thread_sets_decrease_ + extern f_return_status f_thread_sets_decrease(f_thread_sets_t *thread_sets); +#endif // _di_f_thread_sets_decrease_ + +/** + * Resize the thread set array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to less than 0. + * + * @param amount + * A positive number representing how much to decrease the size by. + * @param thread_sets + * The string array to resize. + * + * @return + * F_none on success. + * F_memory_allocation (with error bit) on memory allocation error. + * F_memory_reallocation (with error bit) on memory reallocation error. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_thread_sets_decrease_by_ + extern f_return_status f_thread_sets_decrease_by(const f_array_length_t amount, f_thread_sets_t *thread_sets); +#endif // _di_f_thread_sets_decrease_by_ + +/** + * Delete the thread set array. + * + * @param string + * The string to delete. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_thread_sets_delete_ + extern f_return_status f_thread_sets_delete(f_thread_sets_t *thread_sets); +#endif // _di_f_thread_sets_delete_ + +/** + * Increase the size of the thread set array, but only if necessary. + * + * If the given length is too large for the buffer, then attempt to set max buffer size (f_array_length_t_size). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param thread_sets + * The string array to resize. + * + * @return + * F_none on success. + * F_memory_allocation (with error bit) on memory allocation error. + * F_memory_reallocation (with error bit) on memory reallocation error. + * F_parameter (with error bit) if a parameter is invalid. + * F_array_too_large (with error bit) if the new array length is too large. + */ +#ifndef _di_f_thread_sets_increase_ + extern f_return_status f_thread_sets_increase(f_thread_sets_t *thread_sets); +#endif // _di_f_thread_sets_increase_ + +/** + * Resize the thread set array to a larger size. + * + * This will resize making the array larger based on the given length. + * If the given length is too large for the buffer, then attempt to set max buffer size (f_array_length_t_size). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param thread_sets + * The string array to resize. + * + * @return + * F_none on success. + * F_memory_allocation (with error bit) on memory allocation error. + * F_memory_reallocation (with error bit) on memory reallocation error. + * F_parameter (with error bit) if a parameter is invalid. + * F_array_too_large (with error bit) if the new array length is too large. + */ +#ifndef _di_f_thread_sets_increase_by_ + extern f_return_status f_thread_sets_increase_by(const f_array_length_t amount, f_thread_sets_t *thread_sets); +#endif // _di_f_thread_sets_increase_by_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_thread_h diff --git a/level_0/f_thread/data/build/defines b/level_0/f_thread/data/build/defines new file mode 100644 index 0000000..c665317 --- /dev/null +++ b/level_0/f_thread/data/build/defines @@ -0,0 +1,2 @@ +# fss-0000 + diff --git a/level_0/f_thread/data/build/dependencies b/level_0/f_thread/data/build/dependencies new file mode 100644 index 0000000..66dca29 --- /dev/null +++ b/level_0/f_thread/data/build/dependencies @@ -0,0 +1,5 @@ +# fss-0000 + +f_type +f_status +f_memory diff --git a/level_0/f_thread/data/build/settings b/level_0/f_thread/data/build/settings new file mode 100644 index 0000000..a9ad903 --- /dev/null +++ b/level_0/f_thread/data/build/settings @@ -0,0 +1,55 @@ +# fss-0001 + +project_name f_thread + +version_major 0 +version_minor 5 +version_micro 2 +version_target major + +environment + +process_pre +process_post + +modes individual +modes_default individual + +build_compiler gcc +build_indexer ar +build_language c +build_libraries -lc +build_libraries-individual -lf_memory +build_sources_library thread.c private-thread.c +build_sources_program +build_sources_headers thread.h thread-common.h +build_sources_script +build_sources_setting +build_script yes +build_shared yes +build_static yes + +path_headers level_0 +path_headers_preserve no +path_library_script script +path_library_shared shared +path_library_static static +path_program_script script +path_program_shared shared +path_program_static static +path_sources +path_standard yes + +search_exclusive yes +search_shared yes +search_static yes + +defines_all +defines_static +defines_shared + +flags_all -z now -g -fdiagnostics-color=always -pthread +flags_shared +flags_static +flags_library -fPIC +flags_program -fPIE diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index aae9382..69520e1 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -584,6 +584,12 @@ extern "C" { case F_syntax_not: *string = FL_status_string_syntax_not; break; + case F_thread: + *string = FL_status_string_thread; + break; + case F_thread_not: + *string = FL_status_string_thread_not; + break; case F_known: *string = FL_status_string_known; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index 9a3710f..7b53a6c 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -286,6 +286,8 @@ extern "C" { #define FL_status_string_string_too_small "F_string_too_small" #define FL_status_string_syntax "F_syntax" #define FL_status_string_syntax_not "F_syntax_not" + #define FL_status_string_thread "F_thread" + #define FL_status_string_thread_not "F_thread_not" #define FL_status_string_supported "F_supported" #define FL_status_string_supported_not "F_supported_not" #define FL_status_string_user "F_user" @@ -431,6 +433,8 @@ extern "C" { #define FL_status_string_supported_not_length 15 #define FL_status_string_syntax_length 8 #define FL_status_string_syntax_not_length 12 + #define FL_status_string_thread_length 8 + #define FL_status_string_thread_not_length 12 #define FL_status_string_user_length 6 #define FL_status_string_user_not_length 10 #define FL_status_string_utf_length 5 diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index 41cfd2d..419dd1f 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -986,6 +986,16 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_thread, length, FL_status_string_thread_length) == F_equal_to) { + *code = F_thread; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_thread_not, length, FL_status_string_thread_not_length) == F_equal_to) { + *code = F_thread_not; + return F_none; + } + if (fl_string_compare(string, FL_status_string_user, length, FL_status_string_user_length) == F_equal_to) { *code = F_user; return F_none; diff --git a/level_3/controller/data/build/dependencies b/level_3/controller/data/build/dependencies index 3f87592..530b45d 100644 --- a/level_3/controller/data/build/dependencies +++ b/level_3/controller/data/build/dependencies @@ -21,6 +21,7 @@ f_path f_pipe f_print f_signal +f_thread fl_color fl_console fl_control_group diff --git a/level_3/controller/data/build/settings b/level_3/controller/data/build/settings index d780fc7..7ad9871 100644 --- a/level_3/controller/data/build/settings +++ b/level_3/controller/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfll_control_group -lfll_environment -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf +build_libraries-individual -lfll_control_group -lfll_environment -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_thread -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library controller.c private-control.c private-controller.c private-entry.c private-rule.c @@ -51,7 +51,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always +flags_all -z now -g -fdiagnostics-color=always -pthread flags_shared flags_static flags_library -fPIC diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.h b/level_3/fss_extended_read/c/private-fss_extended_read.h index 9b2d407..6c4249f 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.h +++ b/level_3/fss_extended_read/c/private-fss_extended_read.h @@ -50,8 +50,8 @@ extern "C" { structure.value_at = 0; \ f_macro_string_dynamic_t_clear(structure.value_name) - #define fss_extended_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(structure.value_name) - #define fss_extended_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(structure.value_name) + #define fss_extended_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(&structure.value_name) + #define fss_extended_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(&structure.value_name) #endif // _di_fss_extended_read_depth_t_ /** -- 1.8.3.1