From: Kevin Day Date: Sun, 3 Jan 2021 03:11:02 +0000 (-0600) Subject: Update: thread support. X-Git-Tag: 0.5.3~138 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=33b03bbdcea9e6a356fa2f70cc557536e82b5114;p=fll Update: thread support. Finish wrapping the pthread functions using f_thread. I have observed some problems under GLIBC where static linking and -pthreads do not appear to work. This is a problem with GLIBC as far as I can tell and I must ignore it to the extend that I can. That said, because of the problems I decided to disable static compiling by default. Either a better libc should be used or the static libraries should be compiled with thread support disabled. I have not yet decided whether or not I intend to have thread suppot enabled or disabled by default. The current default as of this commit is enabled. There are some tweaks to the build settings to make things slightly easier when building with threads disabled vs threads enabled. Completely separate f_signal from f_thread (where previously f_signal has conditional thread support). Add a threadsafe option to fl_execute_parameter_t to conditionally use a threadsafe signal handler or not. --- diff --git a/build/level_0/settings b/build/level_0/settings index a679e21..68b9c74 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -12,7 +12,7 @@ environment process_pre process_post -modes level +modes level level_threadless modes_default level build_compiler gcc @@ -20,14 +20,17 @@ 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 serialize.c private-serialize.c signal.c socket.c thread.c private-thread.c utf.c private-utf.c +build_libraries-level_threadless +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 utf.c private-utf.c +build_sources_library-level thread.c private-thread.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 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_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 type.h type_array.h utf.h utf-common.h +build_sources_headers-level thread.h thread-common.h build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no @@ -44,10 +47,12 @@ search_static yes #defines_all -D_di_libcap_ defines_all +defines_all-level_threadless -D_di_pthread_support_ defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -pthread +flags_all -z now -g -fdiagnostics-color=always +flags_all-level -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/level_1/settings b/build/level_1/settings index d251db6..be2ce79 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -12,14 +12,15 @@ environment process_pre process_post -modes level +modes level level_threadless modes_default level build_compiler gcc build_indexer ar build_language c -build_libraries -lc +build_libraries -lc -lcap build_libraries-level -lfll_0 +build_libraries-level_threadless -lfll_0 build_sources_library color.c console.c control_group.c conversion.c directory.c private-directory.c environment.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c iki.c print.c private-print.c status.c string.c private-string.c type.c private-type.c utf.c private-utf.c utf_file.c private-utf_file.c build_sources_program build_sources_headers color.h console.h control_group.h conversion.h directory.h environment.h execute.h execute-common.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h print.h status.h string.h type.h utf.h utf_file.h @@ -27,7 +28,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no @@ -42,11 +43,14 @@ search_exclusive yes search_shared yes search_static yes +#defines_all -D_di_libcap_ defines_all +defines_all-level_threadless -D_di_pthread_support_ defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -pthread +flags_all -z now -g -fdiagnostics-color=always +flags_all-level -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/level_2/settings b/build/level_2/settings index 1c0b033..59a660c 100644 --- a/build/level_2/settings +++ b/build/level_2/settings @@ -12,14 +12,15 @@ environment process_pre process_post -modes level +modes level level_threadless modes_default level build_compiler gcc build_indexer ar build_language c -build_libraries -lc -lcap +build_libraries -lc -lcap -lfll_1 -lfll_0 build_libraries-level -lfll_1 -lfll_0 +build_libraries-level_threadless -lfll_1 -lfll_0 build_sources_library control_group.c environment.c error.c private-error.c execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c build_sources_program build_sources_headers control_group.h environment.h error.h error-common.h execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h path.h program.h status.h @@ -27,7 +28,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no @@ -44,10 +45,12 @@ search_static yes #defines_all -D_di_libcap_ defines_all +defines_all-level_threadless -D_di_pthread_support_ defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -pthread +flags_all -z now -g -fdiagnostics-color=always +flags_all-level -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/monolithic/settings b/build/monolithic/settings index e1ebd75..5be10cf 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -12,7 +12,7 @@ environment process_pre process_post -modes monolithic +modes monolithic monolithic-threadless modes_default monolithic build_compiler gcc @@ -20,14 +20,17 @@ 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/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_libraries-monolithic_threadless +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/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-monolithic level_0/thread.c level_0/private-thread.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/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_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/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-monolithic level_0/thread.h level_0/thread-common.h build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers path_headers_preserve yes @@ -44,10 +47,12 @@ search_static yes #defines_all -D_di_libcap_ defines_all +defines_all-monolithic_threadless -D_di_pthread_support_ defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -pthread +flags_all -z now -g -fdiagnostics-color=always +flags_all-monolithic -pthread flags_shared flags_static flags_library -fPIC diff --git a/build/scripts/bootstrap-example.sh b/build/scripts/bootstrap-example.sh index 7f34fc5..275b122 100644 --- a/build/scripts/bootstrap-example.sh +++ b/build/scripts/bootstrap-example.sh @@ -9,8 +9,8 @@ # This only accepts two arguments, followed by two optional arguments (first two are required and in the specified order): # 1) One of "individual", "level", "monolithic", "fake-individual", "fake-level", or "fake-monolithic". # 2) The version number of the project, such as "0.5.2". -# 3) Optional, may be one of: +V, +q, +n, +l, +d. -# 4) Optional, may be one of: +V, +q, +n, +l, +d. +# 3) Optional, may be one of: +V, +q, +n, +l, +d, --enable-shared, --enable-static, --disable-shared, --disable-static. +# 4) Optional, may be one of: +V, +q, +n, +l, +d, --enable-shared, --enable-static, --disable-shared, --disable-static. # # This will create a directory at he present working directory of the script caller called "fll" where everything will be installed. # This assumes the shell script is GNU bash. @@ -20,20 +20,35 @@ original_path="$PWD/" install_path="${original_path}fll/" verbose= -if [[ $3 == "+V" || $4 == "+V" ]] ; then - verbose="+V" -elif [[ $3 == "+q" || $4 == "+q" ]] ; then - verbose="+q" -fi - color= -if [[ $3 == "+d" || $4 == "+d" ]] ; then - color="+d" -elif [[ $3 == "+l" || $4 == "+l" ]] ; then - color="+l" -elif [[ $3 == "+n" || $4 == "+n" ]] ; then - color="+n" -fi +shared= +static= + +let i=3 + +while [[ $i -le $# ]] ; do + if [[ ${!i} == "+V" ]] ; then + verbose="+V" + elif [[ ${!i} == "+q" ]] ; then + verbose="+q" + elif [[ ${!i} == "+d" ]] ; then + verbose="+d" + elif [[ ${!i} == "+l" ]] ; then + verbose="+l" + elif [[ ${!i} == "+n" ]] ; then + verbose="+n" + elif [[ ${!i} == "--enable-static" ]] ; then + static="--enable-static" + elif [[ ${!i} == "--disable-static" ]] ; then + static="--disable-static" + elif [[ ${!i} == "--enable-shared" ]] ; then + shared="--enable-shared" + elif [[ ${!i} == "--disable-shared" ]] ; then + shared="--disable-shared" + fi + + let i++ +done mkdir -vp $install_path @@ -48,9 +63,9 @@ if [[ $1 == "individual" ]] ; then ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh build $verbose $color -w $install_path -m individual && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m individual && - ./install.sh $verbose $color -w $install_path && + ./install.sh $verbose $color $shared $static -w $install_path && cd $original_path || break done @@ -62,31 +77,31 @@ if [[ $1 == "level" ]] ; then cd package/level/fll-level_0-$2/ && - ./bootstrap.sh $verbose $color clean && + ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh $verbose $color build -w $install_path -m level && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m level && - ./install.sh $verbose $color -w $install_path && + ./install.sh $verbose $color $shared $static -w $install_path && cd $original_path && cd package/level/fll-level_1-$2/ && - ./bootstrap.sh $verbose $color clean && + ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh $verbose $color build -w $install_path -m level && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m level && - ./install.sh $verbose $color -w $install_path && + ./install.sh $verbose $color $shared $static -w $install_path && cd $original_path && cd package/level/fll-level_2-$2/ && - ./bootstrap.sh $verbose $color clean && + ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh $verbose $color build -w $install_path -m level && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m level && - ./install.sh $verbose $color -w $install_path + ./install.sh $verbose $color $shared $static -w $install_path fi if [[ $1 == "monolithic" ]] ; then @@ -94,11 +109,11 @@ if [[ $1 == "monolithic" ]] ; then cd package/monolithic/fll-$2/ && - ./bootstrap.sh $verbose $color clean && + ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh $verbose $color build -w $install_path -m monolithic && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m monolithic && - ./install.sh $verbose $color -w $install_path + ./install.sh $verbose $color $shared $static -w $install_path fi # the following in an example on building the Featureless Make project (fake) from the project bootstrapped from above. @@ -115,11 +130,11 @@ if [[ $1 == "fake-individual" || $1 == "fake-level" || $1 == "fake-monolithic" ] cd package/program/fake-$2/ && - ./bootstrap.sh $verbose $color clean && + ./bootstrap.sh clean $verbose $color && - ./bootstrap.sh $verbose $color build -w $install_path -m $build_mode && + ./bootstrap.sh build $verbose $color $shared $static -w $install_path -m $build_mode && - ./install.sh $verbose $color -w $install_path + ./install.sh $verbose $color $shared $static -w $install_path fi # regardless of what happens always return to the starting directory. diff --git a/documents/threads.txt b/documents/threads.txt index aaebabf..edbae5b 100644 --- a/documents/threads.txt +++ b/documents/threads.txt @@ -8,3 +8,20 @@ Threads Documentation: 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. + + Some projects that optionally support pthreads may support the macro _di_pthread_support_ for disabling threads. + + Thread support is a very common functionality and there may be changes to the FLL scripts and fakefile to support the options "--disable-thread" and "--enable-thread" to make utilizing threads slightly easier. + Some libraries and programs in this project require threads to work and will not compile with threads disabled. + +GLIBC Problems: + Some versions of GLIBC butcher static linking in some way or another. + One of the problems encountered is that with compiling against threads (-pthread) some programs may get messages like\: + multiple definition of `__lll_lock_wait_private' ... libpthread.a(lowlevellock.o): in function `__lll_unlock_wake_private' ... + + An immediate solution would be to fix the GLIBC and set __lll_lock_wait_private to a weak_function. + This is not practical for most users, so it may be that thread support in statically compiled libraries for GLIBC will not be possible. + An alternative could be to use a more sane libc instead of GLIBC (if you can find one, like musl-libc). + + There needs to be more investigation into the cause of this. + Maybe there is some way to fix this during compile or link time without having to fix GLIBC or use a different libc for static linking. diff --git a/level_0/f_account/data/build/settings b/level_0/f_account/data/build/settings index 53215b2..4ed2e4c 100644 --- a/level_0/f_account/data/build/settings +++ b/level_0/f_account/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_capability/data/build/settings b/level_0/f_capability/data/build/settings index 1db7437..e538f67 100644 --- a/level_0/f_capability/data/build/settings +++ b/level_0/f_capability/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_color/data/build/settings b/level_0/f_color/data/build/settings index 8bfe485..80aaaeb 100644 --- a/level_0/f_color/data/build/settings +++ b/level_0/f_color/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_console/data/build/settings b/level_0/f_console/data/build/settings index ca04354..c60e43e 100644 --- a/level_0/f_console/data/build/settings +++ b/level_0/f_console/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_control_group/data/build/settings b/level_0/f_control_group/data/build/settings index 8828ab2..6523f94 100644 --- a/level_0/f_control_group/data/build/settings +++ b/level_0/f_control_group/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_conversion/data/build/settings b/level_0/f_conversion/data/build/settings index 4c90dc1..fff2386 100644 --- a/level_0/f_conversion/data/build/settings +++ b/level_0/f_conversion/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_directory/data/build/settings b/level_0/f_directory/data/build/settings index 54a7448..9c51aff 100644 --- a/level_0/f_directory/data/build/settings +++ b/level_0/f_directory/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_environment/data/build/settings b/level_0/f_environment/data/build/settings index 9106d84..d75807e 100644 --- a/level_0/f_environment/data/build/settings +++ b/level_0/f_environment/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_execute/data/build/settings b/level_0/f_execute/data/build/settings index 500c1b1..0df1771 100644 --- a/level_0/f_execute/data/build/settings +++ b/level_0/f_execute/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_file/data/build/settings b/level_0/f_file/data/build/settings index 0560fce..153e524 100644 --- a/level_0/f_file/data/build/settings +++ b/level_0/f_file/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_fss/data/build/settings b/level_0/f_fss/data/build/settings index 65920d4..b619c5f 100644 --- a/level_0/f_fss/data/build/settings +++ b/level_0/f_fss/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_iki/data/build/settings b/level_0/f_iki/data/build/settings index c0415c1..5dde159 100644 --- a/level_0/f_iki/data/build/settings +++ b/level_0/f_iki/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_memory/data/build/settings b/level_0/f_memory/data/build/settings index 11e1330..ff3d867 100644 --- a/level_0/f_memory/data/build/settings +++ b/level_0/f_memory/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_path/data/build/settings b/level_0/f_path/data/build/settings index 46cd454..bc38323 100644 --- a/level_0/f_path/data/build/settings +++ b/level_0/f_path/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_pipe/data/build/settings b/level_0/f_pipe/data/build/settings index 112d8f2..768aee5 100644 --- a/level_0/f_pipe/data/build/settings +++ b/level_0/f_pipe/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_print/data/build/settings b/level_0/f_print/data/build/settings index 3b22c67..a5ca534 100644 --- a/level_0/f_print/data/build/settings +++ b/level_0/f_print/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_serialize/data/build/settings b/level_0/f_serialize/data/build/settings index 1296564..6cfedf4 100644 --- a/level_0/f_serialize/data/build/settings +++ b/level_0/f_serialize/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_signal/c/signal.c b/level_0/f_signal/c/signal.c index 4aa77a6..c3fea93 100644 --- a/level_0/f_signal/c/signal.c +++ b/level_0/f_signal/c/signal.c @@ -170,55 +170,38 @@ extern "C" { } #endif // _di_f_signal_set_fill_ -#ifndef _di_f_signal_set_get_ - f_return_status f_signal_set_get(sigset_t *set) { +#ifndef _di_f_signal_mask_ + f_return_status f_signal_mask(const int how, const sigset_t *next, sigset_t *current) { #ifndef _di_level_0_parameter_checking_ - if (!set) return F_status_set_error(F_parameter); + if (!next && !current) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - #ifdef _threadsafe_f_signal_handle - #define f_macro_signal_set_get_sigmask pthread_sigmask - #else - #define f_macro_signal_set_get_sigmask sigprocmask - #endif - - if (f_macro_signal_set_get_sigmask(0, NULL, set) < 0) { + if (sigprocmask(how, next, current) < 0) { if (errno == EFAULT) return F_status_set_error(F_buffer); if (errno == EINVAL) return F_status_set_error(F_parameter); return F_status_set_error(F_failure); } - #undef f_macro_signal_set_get_sigmask - return F_none; } -#endif // _di_f_signal_set_get_ +#endif // _di_f_signal_mask_ -#ifndef _di_f_signal_set_handle_ - f_return_status f_signal_set_handle(const int how, const sigset_t *set) { - #ifndef _di_level_0_parameter_checking_ - if (!set) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - #ifdef _threadsafe_f_signal_handle - #define f_macro_signal_set_get_sigmask pthread_sigmask - #else - #define f_macro_signal_set_get_sigmask sigprocmask - #endif +#ifndef _di_f_signal_queue_ + f_return_status f_signal_queue(const pid_t id, const int signal, const union sigval value) { - if (f_macro_signal_set_get_sigmask(how, set, NULL) < 0) { - if (errno == EFAULT) return F_status_set_error(F_buffer); + if (sigqueue(id, signal, value) < 0) { + if (errno == EAGAIN) return F_status_set_error(F_resource_not); + if (errno == ENOSYS) return F_status_set_error(F_supported_not); if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == ESRCH) return F_status_set_error(F_found_not); return F_status_set_error(F_failure); } - #undef f_macro_signal_set_get_sigmask - return F_none; } -#endif // _di_f_signal_set_handle_ +#endif // _di_f_signal_queue_ #ifndef _di_f_signal_set_has_ f_return_status f_signal_set_has(const int signal, const sigset_t *set) { diff --git a/level_0/f_signal/c/signal.h b/level_0/f_signal/c/signal.h index 6e35860..d3e8e61 100644 --- a/level_0/f_signal/c/signal.h +++ b/level_0/f_signal/c/signal.h @@ -176,40 +176,54 @@ extern "C" { #endif // _di_f_signal_set_fill_ /** - * Get the current signal set in use. + * Get or assign the current signal set in use. * - * @param set - * The current set of signals being handled. + * Either set or previous may be NULL but not both (at least one is required). + * + * @param how + * How to handle the signal. + * Set this to 0 when only trying to get the current signal set. + * @param next + * (optional) The new set of signals to handle. + * Set to NULL to not use. + * @param current + * (optional) The current set of signals being handled. + * Set to NULL to not use. * * @return * F_none on success but no signal found. * F_parameter (with error bit) if a parameter is invalid. * F_failure (with error bit) for any other error. * - * @see pthread_sigmask() + * @see sigprocmask() */ -#ifndef _di_f_signal_set_get_ - extern f_return_status f_signal_set_get(sigset_t *set); -#endif // _di_f_signal_set_get_ +#ifndef _di_f_signal_mask_ + extern f_return_status f_signal_mask(const int how, const sigset_t *next, sigset_t *current); +#endif // _di_f_signal_mask_ /** - * Designate how to handle or not handle a set of signals designated by the set. + * Send the signal and value to the given process. * - * @param how - * How to process the signal, such as SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK. - * @param set - * The set of signals to handle. + * @param id + * The PID to signal. + * @param signal + * The signal to send to the thread. + * @param value + * The signal value to send. * * @return * F_none on success but no signal found. + * F_found_not (with error bit) if the given PID was found. * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if the max signals is reached. + * F_supported_not (with error bit) if this action is not supported by the current OS. * F_failure (with error bit) for any other error. * - * @see pthread_sigmask() + * @see sigqueue() */ -#ifndef _di_f_signal_set_handle_ - extern f_return_status f_signal_set_handle(const int how, const sigset_t *set); -#endif // _di_f_signal_set_handle_ +#ifndef _di_f_signal_queue_ + extern f_return_status f_signal_queue(const pid_t id, const int signal, const union sigval value); +#endif // _di_f_signal_queue_ /** * Check to see if the given signal set has a given signal. diff --git a/level_0/f_signal/data/build/defines b/level_0/f_signal/data/build/defines index 3f4bf61..4f13080 100644 --- a/level_0/f_signal/data/build/defines +++ b/level_0/f_signal/data/build/defines @@ -1,3 +1 @@ # fss-0000 - -_threadsafe_f_signal_handle Enable use of pthread_sigmask() instead of sigprocmask() in appropriate f_signal_*() functions. diff --git a/level_0/f_signal/data/build/settings b/level_0/f_signal/data/build/settings index 8f7ccba..90457d7 100644 --- a/level_0/f_signal/data/build/settings +++ b/level_0/f_signal/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no @@ -45,12 +45,10 @@ search_shared yes search_static yes defines_all -#defines_all -D_threadsafe_f_signal_handle defines_static defines_shared flags_all -z now -g -fdiagnostics-color=always -#flags_all -z now -g -pthread flags_shared flags_static flags_library -fPIC diff --git a/level_0/f_socket/data/build/settings b/level_0/f_socket/data/build/settings index 5a4efdb..4883008 100644 --- a/level_0/f_socket/data/build/settings +++ b/level_0/f_socket/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_status/data/build/settings b/level_0/f_status/data/build/settings index db50080..039c5a9 100644 --- a/level_0/f_status/data/build/settings +++ b/level_0/f_status/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_string/data/build/settings b/level_0/f_string/data/build/settings index 3b99fa5..1213c19 100644 --- a/level_0/f_string/data/build/settings +++ b/level_0/f_string/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_thread/c/private-thread.c b/level_0/f_thread/c/private-thread.c index d3a6273..1b8152d 100644 --- a/level_0/f_thread/c/private-thread.c +++ b/level_0/f_thread/c/private-thread.c @@ -5,27 +5,186 @@ extern "C" { #endif +#if !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_delete_) + f_return_status private_f_thread_attributes_delete(f_thread_attributes_t *attributes) { + f_status_t status = F_none; + + f_macro_thread_attributes_t_delete(status, (*attributes)); + + return status; + } +#endif // !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_delete_) + +#if !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_increase_) || !defined(_di_f_thread_attributes_increase_by_) + f_return_status private_f_thread_attributes_resize(const f_array_length_t length, f_thread_attributes_t *attributes) { + f_status_t status = F_none; + + f_macro_thread_attributes_t_resize(status, (*attributes), length); + + return status; + } +#endif // !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_increase_) || !defined(_di_f_thread_attributes_increase_by_) + +#if !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_delete_) + f_return_status private_f_thread_conditions_delete(f_thread_conditions_t *conditions) { + f_status_t status = F_none; + + f_macro_thread_conditions_t_delete(status, (*conditions)); + + return status; + } +#endif // !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_delete_) + +#if !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_) + f_return_status private_f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions) { + f_status_t status = F_none; + + f_macro_thread_conditions_t_resize(status, (*conditions), length); + + return status; + } +#endif // !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_) + +#if !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_delete_) + f_return_status private_f_thread_ids_delete(f_thread_ids_t *ids) { + f_status_t status = F_none; + + f_macro_thread_ids_t_delete(status, (*ids)); + + return status; + } +#endif // !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_delete_) + +#if !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_increase_) || !defined(_di_f_thread_ids_increase_by_) + f_return_status private_f_thread_ids_resize(const f_array_length_t length, f_thread_ids_t *ids) { + f_status_t status = F_none; + + f_macro_thread_ids_t_resize(status, (*ids), length); + + return status; + } +#endif // !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_increase_) || !defined(_di_f_thread_ids_increase_by_) + +#if !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_delete_) + f_return_status private_f_thread_keys_delete(f_thread_keys_t *keys) { + f_status_t status = F_none; + + f_macro_thread_keys_t_delete(status, (*keys)); + + return status; + } +#endif // !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_delete_) + +#if !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_) + f_return_status private_f_thread_keys_resize(const f_array_length_t length, f_thread_keys_t *keys) { + f_status_t status = F_none; + + f_macro_thread_keys_t_resize(status, (*keys), length); + + return status; + } +#endif // !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_) + +#if !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_delete_) + f_return_status private_f_thread_locks_delete(f_thread_locks_t *locks) { + f_status_t status = F_none; + + f_macro_thread_locks_t_delete(status, (*locks)); + + return status; + } +#endif // !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_delete_) + +#if !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_) + f_return_status private_f_thread_locks_resize(const f_array_length_t length, f_thread_locks_t *locks) { + f_status_t status = F_none; + + f_macro_thread_locks_t_resize(status, (*locks), length); + + return status; + } +#endif // !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_) + +#if !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_delete_) + f_return_status private_f_thread_mutexs_delete(f_thread_mutexs_t *mutexs) { + f_status_t status = F_none; + + f_macro_thread_mutexs_t_delete(status, (*mutexs)); + + return status; + } +#endif // !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_delete_) + +#if !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_increase_) || !defined(_di_f_thread_mutexs_increase_by_) + f_return_status private_f_thread_mutexs_resize(const f_array_length_t length, f_thread_mutexs_t *mutexs) { + f_status_t status = F_none; + + f_macro_thread_mutexs_t_resize(status, (*mutexs), length); + + return status; + } +#endif // !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_increase_) || !defined(_di_f_thread_mutexs_increase_by_) + +#if !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_delete_) + f_return_status private_f_thread_mutex_attributes_delete(f_thread_mutex_attributes_t *mutex_attributes) { + f_status_t status = F_none; + + f_macro_thread_mutex_attributes_t_delete(status, (*mutex_attributes)); + + return status; + } +#endif // !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_delete_) + +#if !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_increase_) || !defined(_di_f_thread_mutex_attributes_increase_by_) + f_return_status private_f_thread_mutex_attributes_resize(const f_array_length_t length, f_thread_mutex_attributes_t *mutex_attributes) { + f_status_t status = F_none; + + f_macro_thread_mutex_attributes_t_resize(status, (*mutex_attributes), length); + + return status; + } +#endif // !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_increase_) || !defined(_di_f_thread_mutex_attributes_increase_by_) + +#if !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_delete_) + f_return_status private_f_thread_onces_delete(f_thread_onces_t *onces) { + f_status_t status = F_none; + + f_macro_thread_onces_t_delete(status, (*onces)); + + return status; + } +#endif // !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_delete_) + +#if !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_increase_) || !defined(_di_f_thread_onces_increase_by_) + f_return_status private_f_thread_onces_resize(const f_array_length_t length, f_thread_onces_t *onces) { + f_status_t status = F_none; + + f_macro_thread_onces_t_resize(status, (*onces), length); + + return status; + } +#endif // !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_increase_) || !defined(_di_f_thread_onces_increase_by_) + #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_return_status private_f_thread_sets_delete(f_thread_sets_t *sets) { f_status_t status = F_none; - f_macro_thread_sets_t_delete(status, (*thread_sets)); + f_macro_thread_sets_t_delete(status, (*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_return_status private_f_thread_sets_resize(const f_array_length_t length, f_thread_sets_t *sets) { f_status_t status = F_none; - f_macro_thread_sets_t_resize(status, (*thread_sets), length); + f_macro_thread_sets_t_resize(status, (*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 index 4163516..e555737 100644 --- a/level_0/f_thread/c/private-thread.h +++ b/level_0/f_thread/c/private-thread.h @@ -16,25 +16,401 @@ extern "C" { #endif /** + * Private implementation of f_thread_attributes_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param attributes + * The attributes to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_attributes_t_delete(). + * + * @see f_macro_thread_attributes_t_delete() + * @see f_thread_attributes_decrease() + * @see f_thread_attributes_decrease_by() + * @see f_thread_attributes_delete() + */ +#if !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_delete_) + extern f_return_status private_f_thread_attributes_delete(f_thread_attributes_t *attributes) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param attributes + * The attributes to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_attributes_t_resize(). + * + * @see f_macro_thread_attributes_t_resize() + * @see f_thread_attributes_decrease() + * @see f_thread_attributes_decrease_by() + * @see f_thread_attributes_increase() + * @see f_thread_attributes_increase_by() + */ +#if !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_increase_) || !defined(_di_f_thread_attributes_increase_by_) + extern f_return_status private_f_thread_attributes_resize(const f_array_length_t length, f_thread_attributes_t *attributes) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_increase_) || !defined(_di_f_thread_attributes_increase_by_) + +/** + * Private implementation of f_thread_conditions_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param conditions + * The conditions to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_conditions_t_delete(). + * + * @see f_macro_thread_conditions_t_delete() + * @see f_thread_conditions_decrease() + * @see f_thread_conditions_decrease_by() + * @see f_thread_conditions_delete() + */ +#if !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_delete_) + extern f_return_status private_f_thread_conditions_delete(f_thread_conditions_t *conditions) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param conditions + * The conditions to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_conditions_t_resize(). + * + * @see f_macro_thread_conditions_t_resize() + * @see f_thread_conditions_decrease() + * @see f_thread_conditions_decrease_by() + * @see f_thread_conditions_increase() + * @see f_thread_conditions_increase_by() + */ +#if !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_) + extern f_return_status private_f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_) + +/** + * Private implementation of f_thread_ids_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param ids + * The ids to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_ids_t_delete(). + * + * @see f_macro_thread_ids_t_delete() + * @see f_thread_ids_decrease() + * @see f_thread_ids_decrease_by() + * @see f_thread_ids_delete() + */ +#if !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_delete_) + extern f_return_status private_f_thread_ids_delete(f_thread_ids_t *ids) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param ids + * The ids to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_ids_t_resize(). + * + * @see f_macro_thread_ids_t_resize() + * @see f_thread_ids_decrease() + * @see f_thread_ids_decrease_by() + * @see f_thread_ids_increase() + * @see f_thread_ids_increase_by() + */ +#if !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_increase_) || !defined(_di_f_thread_ids_increase_by_) + extern f_return_status private_f_thread_ids_resize(const f_array_length_t length, f_thread_ids_t *ids) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_ids_decrease_) || !defined(_di_f_thread_ids_decrease_by_) || !defined(_di_f_thread_ids_increase_) || !defined(_di_f_thread_ids_increase_by_) + +/** + * Private implementation of f_thread_keys_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param keys + * The keys to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_keys_t_delete(). + * + * @see f_macro_thread_keys_t_delete() + * @see f_thread_keys_decrease() + * @see f_thread_keys_decrease_by() + * @see f_thread_keys_delete() + */ +#if !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_delete_) + extern f_return_status private_f_thread_keys_delete(f_thread_keys_t *keys) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param keys + * The keys to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_keys_t_resize(). + * + * @see f_macro_thread_keys_t_resize() + * @see f_thread_keys_decrease() + * @see f_thread_keys_decrease_by() + * @see f_thread_keys_increase() + * @see f_thread_keys_increase_by() + */ +#if !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_) + extern f_return_status private_f_thread_keys_resize(const f_array_length_t length, f_thread_keys_t *keys) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_keys_decrease_) || !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_) + +/** + * Private implementation of f_thread_locks_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param locks + * The locks to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_locks_t_delete(). + * + * @see f_macro_thread_locks_t_delete() + * @see f_thread_locks_decrease() + * @see f_thread_locks_decrease_by() + * @see f_thread_locks_delete() + */ +#if !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_delete_) + extern f_return_status private_f_thread_locks_delete(f_thread_locks_t *locks) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param locks + * The locks to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_locks_t_resize(). + * + * @see f_macro_thread_locks_t_resize() + * @see f_thread_locks_decrease() + * @see f_thread_locks_decrease_by() + * @see f_thread_locks_increase() + * @see f_thread_locks_increase_by() + */ +#if !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_) + extern f_return_status private_f_thread_locks_resize(const f_array_length_t length, f_thread_locks_t *locks) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_locks_decrease_) || !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_) + +/** + * Private implementation of f_thread_mutexs_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param mutexs + * The mutexs to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_mutexs_t_delete(). + * + * @see f_macro_thread_mutexs_t_delete() + * @see f_thread_mutexs_decrease() + * @see f_thread_mutexs_decrease_by() + * @see f_thread_mutexs_delete() + */ +#if !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_delete_) + extern f_return_status private_f_thread_mutexs_delete(f_thread_mutexs_t *mutexs) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param mutexs + * The mutexs to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_mutexs_t_resize(). + * + * @see f_macro_thread_mutexs_t_resize() + * @see f_thread_mutexs_decrease() + * @see f_thread_mutexs_decrease_by() + * @see f_thread_mutexs_increase() + * @see f_thread_mutexs_increase_by() + */ +#if !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_increase_) || !defined(_di_f_thread_mutexs_increase_by_) + extern f_return_status private_f_thread_mutexs_resize(const f_array_length_t length, f_thread_mutexs_t *mutexs) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_increase_) || !defined(_di_f_thread_mutexs_increase_by_) + +/** + * Private implementation of f_thread_mutex_attributes_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param mutex_attributes + * The mutex_attributes to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_mutex_attributes_t_delete(). + * + * @see f_macro_thread_mutex_attributes_t_delete() + * @see f_thread_mutex_attributes_decrease() + * @see f_thread_mutex_attributes_decrease_by() + * @see f_thread_mutex_attributes_delete() + */ +#if !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_delete_) + extern f_return_status private_f_thread_mutex_attributes_delete(f_thread_mutex_attributes_t *mutex_attributes) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param mutex_attributes + * The mutex_attributes to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_mutex_attributes_t_resize(). + * + * @see f_macro_thread_mutex_attributes_t_resize() + * @see f_thread_mutex_attributes_decrease() + * @see f_thread_mutex_attributes_decrease_by() + * @see f_thread_mutex_attributes_increase() + * @see f_thread_mutex_attributes_increase_by() + */ +#if !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_increase_) || !defined(_di_f_thread_mutex_attributes_increase_by_) + extern f_return_status private_f_thread_mutex_attributes_resize(const f_array_length_t length, f_thread_mutex_attributes_t *mutex_attributes) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_mutex_attributes_decrease_) || !defined(_di_f_thread_mutex_attributes_decrease_by_) || !defined(_di_f_thread_mutex_attributes_increase_) || !defined(_di_f_thread_mutex_attributes_increase_by_) + +/** + * Private implementation of f_thread_onces_delete(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param onces + * The onces to delete. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_onces_t_delete(). + * + * @see f_macro_thread_onces_t_delete() + * @see f_thread_onces_decrease() + * @see f_thread_onces_decrease_by() + * @see f_thread_onces_delete() + */ +#if !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_delete_) + extern f_return_status private_f_thread_onces_delete(f_thread_onces_t *onces) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_delete_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param onces + * The onces to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_macro_thread_onces_t_resize(). + * + * @see f_macro_thread_onces_t_resize() + * @see f_thread_onces_decrease() + * @see f_thread_onces_decrease_by() + * @see f_thread_onces_increase() + * @see f_thread_onces_increase_by() + */ +#if !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_increase_) || !defined(_di_f_thread_onces_increase_by_) + extern f_return_status private_f_thread_onces_resize(const f_array_length_t length, f_thread_onces_t *onces) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_thread_onces_decrease_) || !defined(_di_f_thread_onces_decrease_by_) || !defined(_di_f_thread_onces_increase_) || !defined(_di_f_thread_onces_increase_by_) + +/** * 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. + * @param sets + * The sets to delete. * * @return * F_none on success. * - * Errors (with error bit) from: f_macro_threads_t_delete(). + * Errors (with error bit) from: f_macro_thread_sets_t_delete(). * - * @see f_macro_threads_t_delete() + * @see f_macro_thread_sets_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; + extern f_return_status private_f_thread_sets_delete(f_thread_sets_t *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_) /** @@ -44,22 +420,22 @@ extern "C" { * * @param length * The new size to use. - * @param thread_sets - * The thread_sets to resize. + * @param sets + * The sets to resize. * * @return * F_none on success. * - * Errors (with error bit) from: f_macro_threads_t_resize(). + * Errors (with error bit) from: f_macro_thread_sets_t_resize(). * - * @see f_macro_threads_t_resize() + * @see f_macro_thread_sets_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; + extern f_return_status private_f_thread_sets_resize(const f_array_length_t length, f_thread_sets_t *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 diff --git a/level_0/f_thread/c/thread-common.h b/level_0/f_thread/c/thread-common.h index 3ac5b2f..aa0e126 100644 --- a/level_0/f_thread/c/thread-common.h +++ b/level_0/f_thread/c/thread-common.h @@ -17,6 +17,727 @@ extern "C" { #endif /** + * A typedef representing pthread_attr_t. + */ +#ifndef _di_f_thread_attribute_t_ + typedef pthread_attr_t f_thread_attribute_t; + + #define f_thread_attribute_t_initialize { 0 } + + // This does not clear the thread.attributes.__size array (may need to memset() against a sizeof(pthread_attr_t)). + #define f_macro_thread_attribute_t_clear(attribute) attribute.__align = 0; +#endif // _di_f_thread_attribute_t_ + +/** + * An array of f_thread_attribute_t. + * + * array: the array of f_thread_attribute_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_attributes_t_ + typedef struct { + f_thread_attribute_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_attributes_t; + + #define f_thread_attributes_t_initialize { 0, 0, 0 } + + #define f_macro_thread_attributes_t_clear(attributes) \ + attributes.array = 0; \ + attributes.size = 0; \ + attributes.used = 0; + + #define f_macro_thread_attributes_new(status, attributes, length) \ + f_macro_thread_attributes_t_clear(attributes) \ + status = f_memory_new((void **) & attributes.array, sizeof(f_thread_attribute_t), length); \ + if (status == F_none) { \ + attributes.size = length; \ + attributes.used = 0; \ + } + + #define f_macro_thread_attributes_t_delete(status, attributes) \ + status = f_memory_delete((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size); \ + if (status == F_none) { \ + attributes.used = 0; \ + attributes.size = 0; \ + } + + #define f_macro_thread_attributes_t_destroy(status, attributes) \ + status = f_memory_destroy((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size); \ + if (status == F_none) { \ + attributes.used = 0; \ + attributes.size = 0; \ + } + + #define f_macro_thread_attributes_t_delete_simple(attributes) \ + f_memory_delete((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size); \ + attributes.used = 0; \ + attributes.size = 0; + + #define f_macro_thread_attributes_t_destroy_simple(attributes) \ + f_memory_destroy((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size); \ + attributes.used = 0; \ + attributes.size = 0; + + #define f_macro_thread_attributes_t_resize(status, attributes, new_length) \ + status = f_memory_resize((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size, new_length); \ + if (status == F_none) { \ + if (new_length > attributes.size) { \ + for (f_array_length_t _macro__i = attributes.size; _macro__i < new_length; _macro__i++) { \ + memset(&attributes.array[_macro__i], 0, sizeof(f_thread_attribute_t)); \ + } \ + } \ + attributes.size = new_length; \ + if (attributes.used > attributes.size) attributes.used = new_length; \ + } + + #define f_macro_thread_attributes_t_adjust(status, attributes, new_length) \ + status = f_memory_adjust((void **) & attributes.array, sizeof(f_thread_attribute_t), attributes.size, new_length); \ + if (status == F_none) { \ + if (new_length > attributes.size) { \ + for (f_array_length_t _macro__i = attributes.size; _macro__i < new_length; _macro__i++) { \ + memset(&attributes.array[_macro__i], 0, sizeof(f_thread_attribute_t)); \ + } \ + } \ + attributes.size = new_length; \ + if (attributes.used > attributes.size) attributes.used = new_length; \ + } +#endif // _di_f_thread_attributes_t_ + +/** + * A typedef representing pthread_cond_t. + */ +#ifndef _di_f_thread_condition_t_ + typedef pthread_cond_t f_thread_condition_t; + + #define f_thread_condition_t_initialize 0 + + #define f_macro_thread_condition_t_clear(condition) condition = 0; +#endif // _di_f_thread_condition_t_ + +/** + * An array of thread conditions. + * + * array: the array of f_thread_condition_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_conditions_t_ + typedef struct { + f_thread_condition_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_conditions_t; + + #define f_thread_conditions_t_initialize { 0, 0, 0 } + + #define f_macro_thread_conditions_t_clear(conditions) \ + conditions.array = 0; \ + conditions.size = 0; \ + conditions.used = 0; + + #define f_macro_thread_conditions_new(status, conditions, length) \ + f_macro_thread_conditions_t_clear(conditions) \ + status = f_memory_new((void **) & conditions.array, sizeof(f_thread_condition_t), length); \ + if (status == F_none) { \ + conditions.size = length; \ + conditions.used = 0; \ + } + + #define f_macro_thread_conditions_t_delete(status, conditions) \ + status = f_memory_delete((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size); \ + if (status == F_none) { \ + conditions.used = 0; \ + conditions.size = 0; \ + } + + #define f_macro_thread_conditions_t_destroy(status, conditions) \ + status = f_memory_destroy((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size); \ + if (status == F_none) { \ + conditions.used = 0; \ + conditions.size = 0; \ + } + + #define f_macro_thread_conditions_t_delete_simple(conditions) \ + f_memory_delete((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size); \ + conditions.used = 0; \ + conditions.size = 0; + + #define f_macro_thread_conditions_t_destroy_simple(conditions) \ + f_memory_destroy((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size); \ + conditions.used = 0; \ + conditions.size = 0; + + #define f_macro_thread_conditions_t_resize(status, conditions, new_length) \ + status = f_memory_resize((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size, new_length); \ + if (status == F_none) { \ + if (new_length > conditions.size) { \ + for (f_array_length_t _macro__i = conditions.size; _macro__i < new_length; _macro__i++) { \ + memset(&conditions.array[_macro__i], 0, sizeof(f_thread_condition_t)); \ + } \ + } \ + conditions.size = new_length; \ + if (conditions.used > conditions.size) conditions.used = new_length; \ + } + + #define f_macro_thread_conditions_t_adjust(status, conditions, new_length) \ + status = f_memory_adjust((void **) & conditions.array, sizeof(f_thread_condition_t), conditions.size, new_length); \ + if (status == F_none) { \ + if (new_length > conditions.size) { \ + for (f_array_length_t _macro__i = conditions.size; _macro__i < new_length; _macro__i++) { \ + memset(&conditions.array[_macro__i], 0, sizeof(f_thread_condition_t)); \ + } \ + } \ + conditions.size = new_length; \ + if (conditions.used > conditions.size) conditions.used = new_length; \ + } +#endif // _di_f_thread_conditions_t_ + +/** + * A typedef representing pthread_t. + */ +#ifndef _di_f_thread_id_t_ + typedef pthread_t f_thread_id_t; + + #define f_thread_id_t_initialize 0 + + #define f_macro_thread_id_t_clear(id) id = 0; +#endif // _di_f_thread_id_t_ + +/** + * An array of thread IDs. + * + * array: the array of f_thread_id_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_ids_t_ + typedef struct { + f_thread_id_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_ids_t; + + #define f_thread_ids_t_initialize { 0, 0, 0 } + + #define f_macro_thread_ids_t_clear(ids) \ + ids.array = 0; \ + ids.size = 0; \ + ids.used = 0; + + #define f_macro_thread_ids_new(status, ids, length) \ + f_macro_thread_ids_t_clear(ids) \ + status = f_memory_new((void **) & ids.array, sizeof(f_thread_id_t), length); \ + if (status == F_none) { \ + ids.size = length; \ + ids.used = 0; \ + } + + #define f_macro_thread_ids_t_delete(status, ids) \ + status = f_memory_delete((void **) & ids.array, sizeof(f_thread_id_t), ids.size); \ + if (status == F_none) { \ + ids.used = 0; \ + ids.size = 0; \ + } + + #define f_macro_thread_ids_t_destroy(status, ids) \ + status = f_memory_destroy((void **) & ids.array, sizeof(f_thread_id_t), ids.size); \ + if (status == F_none) { \ + ids.used = 0; \ + ids.size = 0; \ + } + + #define f_macro_thread_ids_t_delete_simple(ids) \ + f_memory_delete((void **) & ids.array, sizeof(f_thread_id_t), ids.size); \ + ids.used = 0; \ + ids.size = 0; + + #define f_macro_thread_ids_t_destroy_simple(ids) \ + f_memory_destroy((void **) & ids.array, sizeof(f_thread_id_t), ids.size); \ + ids.used = 0; \ + ids.size = 0; + + #define f_macro_thread_ids_t_resize(status, ids, new_length) \ + status = f_memory_resize((void **) & ids.array, sizeof(f_thread_id_t), ids.size, new_length); \ + if (status == F_none) { \ + if (new_length > ids.size) { \ + for (f_array_length_t _macro__i = ids.size; _macro__i < new_length; _macro__i++) { \ + memset(&ids.array[_macro__i], 0, sizeof(f_thread_id_t)); \ + } \ + } \ + ids.size = new_length; \ + if (ids.used > ids.size) ids.used = new_length; \ + } + + #define f_macro_thread_ids_t_adjust(status, ids, new_length) \ + status = f_memory_adjust((void **) & ids.array, sizeof(f_thread_id_t), ids.size, new_length); \ + if (status == F_none) { \ + if (new_length > ids.size) { \ + for (f_array_length_t _macro__i = ids.size; _macro__i < new_length; _macro__i++) { \ + memset(&ids.array[_macro__i], 0, sizeof(f_thread_id_t)); \ + } \ + } \ + ids.size = new_length; \ + if (ids.used > ids.size) ids.used = new_length; \ + } +#endif // _di_f_thread_ids_t_ + +/** + * A typedef representing pthread_key_t. + */ +#ifndef _di_f_thread_key_t_ + typedef pthread_key_t f_thread_key_t; + + #define f_thread_key_t_initialize 0 + + #define f_macro_thread_key_t_clear(key) key = 0; +#endif // _di_f_thread_key_t_ + +/** + * An array of thread keys. + * + * array: the array of f_thread_key_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_keys_t_ + typedef struct { + f_thread_key_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_keys_t; + + #define f_thread_keys_t_initialize { 0, 0, 0 } + + #define f_macro_thread_keys_t_clear(keys) \ + keys.array = 0; \ + keys.size = 0; \ + keys.used = 0; + + #define f_macro_thread_keys_new(status, keys, length) \ + f_macro_thread_keys_t_clear(keys) \ + status = f_memory_new((void **) & keys.array, sizeof(f_thread_key_t), length); \ + if (status == F_none) { \ + keys.size = length; \ + keys.used = 0; \ + } + + #define f_macro_thread_keys_t_delete(status, keys) \ + status = f_memory_delete((void **) & keys.array, sizeof(f_thread_key_t), keys.size); \ + if (status == F_none) { \ + keys.used = 0; \ + keys.size = 0; \ + } + + #define f_macro_thread_keys_t_destroy(status, keys) \ + status = f_memory_destroy((void **) & keys.array, sizeof(f_thread_key_t), keys.size); \ + if (status == F_none) { \ + keys.used = 0; \ + keys.size = 0; \ + } + + #define f_macro_thread_keys_t_delete_simple(keys) \ + f_memory_delete((void **) & keys.array, sizeof(f_thread_key_t), keys.size); \ + keys.used = 0; \ + keys.size = 0; + + #define f_macro_thread_keys_t_destroy_simple(keys) \ + f_memory_destroy((void **) & keys.array, sizeof(f_thread_key_t), keys.size); \ + keys.used = 0; \ + keys.size = 0; + + #define f_macro_thread_keys_t_resize(status, keys, new_length) \ + status = f_memory_resize((void **) & keys.array, sizeof(f_thread_key_t), keys.size, new_length); \ + if (status == F_none) { \ + if (new_length > keys.size) { \ + for (f_array_length_t _macro__i = keys.size; _macro__i < new_length; _macro__i++) { \ + memset(&keys.array[_macro__i], 0, sizeof(f_thread_key_t)); \ + } \ + } \ + keys.size = new_length; \ + if (keys.used > keys.size) keys.used = new_length; \ + } + + #define f_macro_thread_keys_t_adjust(status, keys, new_length) \ + status = f_memory_adjust((void **) & keys.array, sizeof(f_thread_key_t), keys.size, new_length); \ + if (status == F_none) { \ + if (new_length > keys.size) { \ + for (f_array_length_t _macro__i = keys.size; _macro__i < new_length; _macro__i++) { \ + memset(&keys.array[_macro__i], 0, sizeof(f_thread_key_t)); \ + } \ + } \ + keys.size = new_length; \ + if (keys.used > keys.size) keys.used = new_length; \ + } +#endif // _di_f_thread_keys_t_ + +/** + * A typedef representing pthread_rwlock_t (read/write lock). + */ +#ifndef _di_f_thread_lock_t_ + typedef pthread_rwlock_t f_thread_lock_t; + + #define f_thread_lock_t_initialize 0 + + #define f_macro_thread_lock_t_clear(lock) lock = 0; +#endif // _di_f_thread_lock_t_ + +/** + * An array of thread locks. + * + * array: the array of f_thread_lock_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_locks_t_ + typedef struct { + f_thread_lock_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_locks_t; + + #define f_thread_locks_t_initialize { 0, 0, 0 } + + #define f_macro_thread_locks_t_clear(locks) \ + locks.array = 0; \ + locks.size = 0; \ + locks.used = 0; + + #define f_macro_thread_locks_new(status, locks, length) \ + f_macro_thread_locks_t_clear(locks) \ + status = f_memory_new((void **) & locks.array, sizeof(f_thread_lock_t), length); \ + if (status == F_none) { \ + locks.size = length; \ + locks.used = 0; \ + } + + #define f_macro_thread_locks_t_delete(status, locks) \ + status = f_memory_delete((void **) & locks.array, sizeof(f_thread_lock_t), locks.size); \ + if (status == F_none) { \ + locks.used = 0; \ + locks.size = 0; \ + } + + #define f_macro_thread_locks_t_destroy(status, locks) \ + status = f_memory_destroy((void **) & locks.array, sizeof(f_thread_lock_t), locks.size); \ + if (status == F_none) { \ + locks.used = 0; \ + locks.size = 0; \ + } + + #define f_macro_thread_locks_t_delete_simple(locks) \ + f_memory_delete((void **) & locks.array, sizeof(f_thread_lock_t), locks.size); \ + locks.used = 0; \ + locks.size = 0; + + #define f_macro_thread_locks_t_destroy_simple(locks) \ + f_memory_destroy((void **) & locks.array, sizeof(f_thread_lock_t), locks.size); \ + locks.used = 0; \ + locks.size = 0; + + #define f_macro_thread_locks_t_resize(status, locks, new_length) \ + status = f_memory_resize((void **) & locks.array, sizeof(f_thread_lock_t), locks.size, new_length); \ + if (status == F_none) { \ + if (new_length > locks.size) { \ + for (f_array_length_t _macro__i = locks.size; _macro__i < new_length; _macro__i++) { \ + memset(&locks.array[_macro__i], 0, sizeof(f_thread_lock_t)); \ + } \ + } \ + locks.size = new_length; \ + if (locks.used > locks.size) locks.used = new_length; \ + } + + #define f_macro_thread_locks_t_adjust(status, locks, new_length) \ + status = f_memory_adjust((void **) & locks.array, sizeof(f_thread_lock_t), locks.size, new_length); \ + if (status == F_none) { \ + if (new_length > locks.size) { \ + for (f_array_length_t _macro__i = locks.size; _macro__i < new_length; _macro__i++) { \ + memset(&locks.array[_macro__i], 0, sizeof(f_thread_lock_t)); \ + } \ + } \ + locks.size = new_length; \ + if (locks.used > locks.size) locks.used = new_length; \ + } +#endif // _di_f_thread_locks_t_ + +/** + * A typedef representing pthread_mutex_t. + */ +#ifndef _di_f_thread_mutex_t_ + typedef pthread_mutex_t f_thread_mutex_t; + + #define f_thread_mutex_t_initialize 0 + + #define f_macro_thread_mutex_t_clear(mutex) mutex = 0; +#endif // _di_f_thread_mutex_t_ + +/** + * An array of thread mutexes. + * + * array: the array of f_thread_mutex_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_mutexs_t_ + typedef struct { + f_thread_mutex_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_mutexs_t; + + #define f_thread_mutexs_t_initialize { 0, 0, 0 } + + #define f_macro_thread_mutexs_t_clear(mutexs) \ + mutexs.array = 0; \ + mutexs.size = 0; \ + mutexs.used = 0; + + #define f_macro_thread_mutexs_new(status, mutexs, length) \ + f_macro_thread_mutexs_t_clear(mutexs) \ + status = f_memory_new((void **) & mutexs.array, sizeof(f_thread_mutex_t), length); \ + if (status == F_none) { \ + mutexs.size = length; \ + mutexs.used = 0; \ + } + + #define f_macro_thread_mutexs_t_delete(status, mutexs) \ + status = f_memory_delete((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size); \ + if (status == F_none) { \ + mutexs.used = 0; \ + mutexs.size = 0; \ + } + + #define f_macro_thread_mutexs_t_destroy(status, mutexs) \ + status = f_memory_destroy((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size); \ + if (status == F_none) { \ + mutexs.used = 0; \ + mutexs.size = 0; \ + } + + #define f_macro_thread_mutexs_t_delete_simple(mutexs) \ + f_memory_delete((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size); \ + mutexs.used = 0; \ + mutexs.size = 0; + + #define f_macro_thread_mutexs_t_destroy_simple(mutexs) \ + f_memory_destroy((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size); \ + mutexs.used = 0; \ + mutexs.size = 0; + + #define f_macro_thread_mutexs_t_resize(status, mutexs, new_length) \ + status = f_memory_resize((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size, new_length); \ + if (status == F_none) { \ + if (new_length > mutexs.size) { \ + for (f_array_length_t _macro__i = mutexs.size; _macro__i < new_length; _macro__i++) { \ + memset(&mutexs.array[_macro__i], 0, sizeof(f_thread_mutex_t)); \ + } \ + } \ + mutexs.size = new_length; \ + if (mutexs.used > mutexs.size) mutexs.used = new_length; \ + } + + #define f_macro_thread_mutexs_t_adjust(status, mutexs, new_length) \ + status = f_memory_adjust((void **) & mutexs.array, sizeof(f_thread_mutex_t), mutexs.size, new_length); \ + if (status == F_none) { \ + if (new_length > mutexs.size) { \ + for (f_array_length_t _macro__i = mutexs.size; _macro__i < new_length; _macro__i++) { \ + memset(&mutexs.array[_macro__i], 0, sizeof(f_thread_mutex_t)); \ + } \ + } \ + mutexs.size = new_length; \ + if (mutexs.used > mutexs.size) mutexs.used = new_length; \ + } +#endif // _di_f_thread_mutexs_t_ + +/** + * A typedef representing pthread_mutex_attribute_t. + */ +#ifndef _di_f_thread_mutex_attribute_t_ + typedef pthread_mutexattr_t f_thread_mutex_attribute_t; + + #define f_thread_mutex_attribute_t_initialize 0 + + #define f_macro_thread_mutex_attribute_t_clear(mutex_attribute) mutex_attribute = 0; +#endif // _di_f_thread_mutex_attribute_t_ + +/** + * An array of thread mutex_attributees. + * + * array: the array of f_thread_mutex_attribute_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_mutex_attributes_t_ + typedef struct { + f_thread_mutex_attribute_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_mutex_attributes_t; + + #define f_thread_mutex_attributes_t_initialize { 0, 0, 0 } + + #define f_macro_thread_mutex_attributes_t_clear(mutex_attributes) \ + mutex_attributes.array = 0; \ + mutex_attributes.size = 0; \ + mutex_attributes.used = 0; + + #define f_macro_thread_mutex_attributes_new(status, mutex_attributes, length) \ + f_macro_thread_mutex_attributes_t_clear(mutex_attributes) \ + status = f_memory_new((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), length); \ + if (status == F_none) { \ + mutex_attributes.size = length; \ + mutex_attributes.used = 0; \ + } + + #define f_macro_thread_mutex_attributes_t_delete(status, mutex_attributes) \ + status = f_memory_delete((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size); \ + if (status == F_none) { \ + mutex_attributes.used = 0; \ + mutex_attributes.size = 0; \ + } + + #define f_macro_thread_mutex_attributes_t_destroy(status, mutex_attributes) \ + status = f_memory_destroy((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size); \ + if (status == F_none) { \ + mutex_attributes.used = 0; \ + mutex_attributes.size = 0; \ + } + + #define f_macro_thread_mutex_attributes_t_delete_simple(mutex_attributes) \ + f_memory_delete((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size); \ + mutex_attributes.used = 0; \ + mutex_attributes.size = 0; + + #define f_macro_thread_mutex_attributes_t_destroy_simple(mutex_attributes) \ + f_memory_destroy((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size); \ + mutex_attributes.used = 0; \ + mutex_attributes.size = 0; + + #define f_macro_thread_mutex_attributes_t_resize(status, mutex_attributes, new_length) \ + status = f_memory_resize((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size, new_length); \ + if (status == F_none) { \ + if (new_length > mutex_attributes.size) { \ + for (f_array_length_t _macro__i = mutex_attributes.size; _macro__i < new_length; _macro__i++) { \ + memset(&mutex_attributes.array[_macro__i], 0, sizeof(f_thread_mutex_attribute_t)); \ + } \ + } \ + mutex_attributes.size = new_length; \ + if (mutex_attributes.used > mutex_attributes.size) mutex_attributes.used = new_length; \ + } + + #define f_macro_thread_mutex_attributes_t_adjust(status, mutex_attributes, new_length) \ + status = f_memory_adjust((void **) & mutex_attributes.array, sizeof(f_thread_mutex_attribute_t), mutex_attributes.size, new_length); \ + if (status == F_none) { \ + if (new_length > mutex_attributes.size) { \ + for (f_array_length_t _macro__i = mutex_attributes.size; _macro__i < new_length; _macro__i++) { \ + memset(&mutex_attributes.array[_macro__i], 0, sizeof(f_thread_mutex_attribute_t)); \ + } \ + } \ + mutex_attributes.size = new_length; \ + if (mutex_attributes.used > mutex_attributes.size) mutex_attributes.used = new_length; \ + } +#endif // _di_f_thread_mutex_attributes_t_ + +/** + * A typedef representing pthread_once_t. + */ +#ifndef _di_f_thread_once_t_ + typedef pthread_once_t f_thread_once_t; + + #define f_thread_once_t_initialize 0 + + #define f_macro_thread_once_t_clear(once) once = 0; +#endif // _di_f_thread_once_t_ + +/** + * An array of thread onces. + * + * array: the array of f_thread_once_t. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_thread_onces_t_ + typedef struct { + f_thread_once_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_thread_onces_t; + + #define f_thread_onces_t_initialize { 0, 0, 0 } + + #define f_macro_thread_onces_t_clear(onces) \ + onces.array = 0; \ + onces.size = 0; \ + onces.used = 0; + + #define f_macro_thread_onces_new(status, onces, length) \ + f_macro_thread_onces_t_clear(onces) \ + status = f_memory_new((void **) & onces.array, sizeof(f_thread_once_t), length); \ + if (status == F_none) { \ + onces.size = length; \ + onces.used = 0; \ + } + + #define f_macro_thread_onces_t_delete(status, onces) \ + status = f_memory_delete((void **) & onces.array, sizeof(f_thread_once_t), onces.size); \ + if (status == F_none) { \ + onces.used = 0; \ + onces.size = 0; \ + } + + #define f_macro_thread_onces_t_destroy(status, onces) \ + status = f_memory_destroy((void **) & onces.array, sizeof(f_thread_once_t), onces.size); \ + if (status == F_none) { \ + onces.used = 0; \ + onces.size = 0; \ + } + + #define f_macro_thread_onces_t_delete_simple(onces) \ + f_memory_delete((void **) & onces.array, sizeof(f_thread_once_t), onces.size); \ + onces.used = 0; \ + onces.size = 0; + + #define f_macro_thread_onces_t_destroy_simple(onces) \ + f_memory_destroy((void **) & onces.array, sizeof(f_thread_once_t), onces.size); \ + onces.used = 0; \ + onces.size = 0; + + #define f_macro_thread_onces_t_resize(status, onces, new_length) \ + status = f_memory_resize((void **) & onces.array, sizeof(f_thread_once_t), onces.size, new_length); \ + if (status == F_none) { \ + if (new_length > onces.size) { \ + for (f_array_length_t _macro__i = onces.size; _macro__i < new_length; _macro__i++) { \ + memset(&onces.array[_macro__i], 0, sizeof(f_thread_once_t)); \ + } \ + } \ + onces.size = new_length; \ + if (onces.used > onces.size) onces.used = new_length; \ + } + + #define f_macro_thread_onces_t_adjust(status, onces, new_length) \ + status = f_memory_adjust((void **) & onces.array, sizeof(f_thread_once_t), onces.size, new_length); \ + if (status == F_none) { \ + if (new_length > onces.size) { \ + for (f_array_length_t _macro__i = onces.size; _macro__i < new_length; _macro__i++) { \ + memset(&onces.array[_macro__i], 0, sizeof(f_thread_once_t)); \ + } \ + } \ + onces.size = new_length; \ + if (onces.used > onces.size) onces.used = new_length; \ + } +#endif // _di_f_thread_onces_t_ + +/** * A structure containing basic thread information. * * attributes: The thread attributes (which is a union). @@ -25,17 +746,17 @@ extern "C" { */ #ifndef _di_f_thread_set_t_ typedef struct { - pthread_attr_t attributes; - pthread_t id; + f_thread_attribute_t attributes; + f_thread_id_t id; int result; } f_thread_set_t; - #define f_thread_set_t_initialize { { 0 }, 0, 0 } + #define f_thread_set_t_initialize { f_thread_attribute_t_initialize, f_thread_id_t_initialize, 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; + f_macro_thread_attribute_t_clear(thread.attributes) \ + f_macro_thread_id_t_clear(thread.id) #endif // _di_f_thread_set_t_ /** @@ -60,7 +781,7 @@ extern "C" { threads.size = 0; \ threads.used = 0; - #define f_macro_threads_new(status, threads, length) \ + #define f_macro_thread_sets_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) { \ diff --git a/level_0/f_thread/c/thread.c b/level_0/f_thread/c/thread.c index 4a1e20a..5488bae 100644 --- a/level_0/f_thread/c/thread.c +++ b/level_0/f_thread/c/thread.c @@ -5,20 +5,1155 @@ extern "C" { #endif +#ifndef _di_f_thread_at_fork_ + f_return_status f_thread_at_fork(void (*before) (void), void (*after_parent) (void), void (*after_child) (void)) { + #ifndef _di_level_0_parameter_checking_ + if (!before) return F_status_set_error(F_parameter); + if (!after_parent) return F_status_set_error(F_parameter); + if (!after_child) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_atfork(before, after_parent, after_child); + + if (error) { + if (error == ENOMEM) return F_status_set_error(F_memory_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_key_create_ + +#ifndef _di_f_thread_attribute_affinity_get_ + f_return_status f_thread_attribute_affinity_get(const f_thread_attribute_t attribute, const size_t affinity_size, cpu_set_t *affinity_set) { + #ifndef _di_level_0_parameter_checking_ + if (!affinity_set) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getaffinity_np(&attribute, affinity_size, affinity_set); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_affinity_get_ + +#ifndef _di_f_thread_attribute_affinity_set_ + f_return_status f_thread_attribute_affinity_set(const size_t affinity_size, const cpu_set_t *affinity_set, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setaffinity_np(attribute, affinity_size, affinity_set); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ENOMEM) return F_status_set_error(F_memory_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_affinity_set_ + +#ifndef _di_f_thread_attribute_create_ + f_return_status f_thread_attribute_create(f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_init(attribute); + + if (error) { + if (error == ENOMEM) return F_status_set_error(F_memory_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_create_ + +#ifndef _di_f_thread_attribute_default_get_ + f_return_status f_thread_attribute_default_get(f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_getattr_default_np(attribute); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_default_get_ + +#ifndef _di_f_thread_attribute_default_set_ + f_return_status f_thread_attribute_default_set(f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_setattr_default_np(attribute); + + if (error) { + if (error == ENOMEM) return F_status_set_error(F_memory_not); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_default_set_ + +#ifndef _di_f_thread_attribute_delete_ + f_return_status f_thread_attribute_delete(f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_destroy(attribute); + + if (error) { + return F_status_set_error(F_failure); + } + + attribute = 0; + + return F_none; + } +#endif // _di_f_thread_attribute_delete_ + +#ifndef _di_f_thread_attribute_detach_get_ + f_return_status f_thread_attribute_detach_get(const f_thread_attribute_t attribute, int *state) { + #ifndef _di_level_0_parameter_checking_ + if (!state) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getdetachstate(&attribute, state); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_detach_get_ + +#ifndef _di_f_thread_attribute_detach_set_ + f_return_status f_thread_attribute_detach_set(const int state, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setdetachstate(attribute, state); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_detach_set_ + +#ifndef _di_f_thread_attribute_guard_get_ + f_return_status f_thread_attribute_guard_get(const f_thread_attribute_t attribute, size_t *guard) { + #ifndef _di_level_0_parameter_checking_ + if (!guard) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getguardsize(&attribute, guard); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_guard_get_ + +#ifndef _di_f_thread_attribute_guard_set_ + f_return_status f_thread_attribute_guard_set(const size_t guard, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setguardsize(attribute, guard); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_guard_set_ + +#ifndef _di_f_thread_attribute_scheduler_inherit_get_ + f_return_status f_thread_attribute_scheduler_inherit_get(const f_thread_attribute_t attribute, int *inherit) { + #ifndef _di_level_0_parameter_checking_ + if (!inherit) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getinheritsched(&attribute, inherit); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_inherit_get_ + +#ifndef _di_f_thread_attribute_scheduler_inherit_set_ + f_return_status f_thread_attribute_scheduler_inherit_set(const int inherit, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setinheritsched(attribute, inherit); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_inherit_set_ + +#ifndef _di_f_thread_attribute_scheduler_parameter_get_ + f_return_status f_thread_attribute_scheduler_parameter_get(const f_thread_attribute_t attribute, struct sched_param *parameter) { + #ifndef _di_level_0_parameter_checking_ + if (!parameter) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getschedparam(&attribute, parameter); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_parameter_get_ + +#ifndef _di_f_thread_attribute_scheduler_parameter_set_ + f_return_status f_thread_attribute_scheduler_parameter_set(const struct sched_param parameter, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setschedparam(attribute, ¶meter); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_parameter_set_ + +#ifndef _di_f_thread_attribute_scheduler_policy_get_ + f_return_status f_thread_attribute_scheduler_policy_get(const f_thread_attribute_t attribute, int *policy) { + #ifndef _di_level_0_parameter_checking_ + if (!policy) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getschedpolicy(&attribute, policy); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_policy_get_ + +#ifndef _di_f_thread_attribute_scheduler_policy_set_ + f_return_status f_thread_attribute_scheduler_policy_set(const int policy, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setschedpolicy(attribute, policy); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scheduler_policy_set_ + +#ifndef _di_f_thread_attribute_scope_get_ + f_return_status f_thread_attribute_scope_get(const f_thread_attribute_t attribute, int *scope) { + #ifndef _di_level_0_parameter_checking_ + if (!scope) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getscope(&attribute, scope); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scope_get_ + +#ifndef _di_f_thread_attribute_scope_set_ + f_return_status f_thread_attribute_scope_set(const int scope, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setscope(attribute, scope); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ENOTSUP) return F_status_set_error(F_supported_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_scope_set_ + +#ifndef _di_f_thread_attribute_stack_get_ + f_return_status f_thread_attribute_stack_get(const f_thread_attribute_t attribute, size_t *stack_size, void **stack) { + #ifndef _di_level_0_parameter_checking_ + if (!stack) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_getstack(&attribute, stack, stack_size); + + if (error) { + if (error == EACCES) return F_status_set_error(F_access_denied); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_stack_get_ + +#ifndef _di_f_thread_attribute_stack_set_ + f_return_status f_thread_attribute_stack_set(const size_t stack_size, void * const stack, f_thread_attribute_t *attribute) { + #ifndef _di_level_0_parameter_checking_ + if (!attribute) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_attr_setstack(attribute, stack, stack_size); + + if (error) { + if (error == EACCES) return F_status_set_error(F_access_denied); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_attribute_stack_set_ + +#ifndef _di_f_thread_attributes_decrease_ + f_return_status f_thread_attributes_decrease(f_thread_attributes_t *attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (attributes->size > 1) { + return private_f_thread_attributes_resize(attributes->size - 1, attributes); + } + + return private_f_thread_attributes_delete(attributes); + } +#endif // _di_f_thread_attributes_decrease_ + +#ifndef _di_f_thread_attributes_decrease_by_ + f_return_status f_thread_attributes_decrease_by(const f_array_length_t amount, f_thread_attributes_t *attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (attributes->size - amount > 0) { + return private_f_thread_attributes_resize(attributes->size - amount, attributes); + } + + return private_f_thread_attributes_delete(attributes); + } +#endif // _di_f_thread_attributes_decrease_by_ + +#ifndef _di_f_thread_attributes_delete_ + f_return_status f_thread_attributes_delete(f_thread_attributes_t *attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_attributes_delete(attributes); + } +#endif // _di_f_thread_attributes_delete_ + +#ifndef _di_f_thread_attributes_increase_ + f_return_status f_thread_attributes_increase(f_thread_attributes_t *attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (attributes->used + 1 > attributes->size) { + f_array_length_t size = attributes->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (attributes->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_attributes_resize(size, attributes); + } + + return F_none; + } +#endif // _di_f_thread_attributes_increase_ + +#ifndef _di_f_thread_attributes_increase_by_ + f_return_status f_thread_attributes_increase_by(const f_array_length_t amount, f_thread_attributes_t *attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (attributes->used + amount > attributes->size) { + if (attributes->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_attributes_resize(attributes->used + amount, attributes); + } + + return F_none; + } +#endif // _di_f_thread_attributes_increase_by_ + +#ifndef _di_f_thread_caller_ + f_thread_id_t f_thread_caller() { + return pthread_self(); + } +#endif // _di_f_thread_caller_ + +#ifndef _di_f_thread_cancel_ + f_return_status f_thread_cancel(const f_thread_id_t id) { + + const int error = pthread_cancel(id); + + if (error) { + if (error == ESRCH) return F_status_set_error(F_found_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_cancel_ + +#ifndef _di_f_thread_cancel_state_set_ + f_return_status f_thread_cancel_state_set(const int state, int *previous) { + + const int error = pthread_setcancelstate(state, previous); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_cancel_state_set_ + +#ifndef _di_f_thread_cancel_test_ + f_return_status f_thread_cancel_test() { + + pthread_testcancel(); + + return F_none; + } +#endif // _di_f_thread_cancel_test_ + +#ifndef _di_f_thread_cancel_type_set_ + f_return_status f_thread_cancel_type_set(const int type, int *previous) { + + const int error = pthread_setcanceltype(type, previous); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_cancel_type_set_ + +#ifndef _di_f_thread_clock_get_id_ + f_return_status f_thread_clock_get_id(const f_thread_id_t id_thread, clockid_t *id_clock) { + + const int error = pthread_getcpuclockid(id_thread, id_clock); + + if (error) { + if (error == ENOENT) return F_status_set_error(F_supported_not); + if (error == ESRCH) return F_status_set_error(F_found_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_clock_get_id_ + +#ifndef _di_f_thread_compare_ + f_return_status f_thread_compare(const f_thread_id_t id1, const f_thread_id_t id2) { + + if (pthread_equal(id1, id2)) { + return F_equal_to; + } + + return F_equal_to_not; + } +#endif // _di_f_thread_compare_ + +#ifndef _di_f_thread_condition_unblock_all_ + f_return_status f_thread_condition_unblock_all(f_thread_condition_t *condition) { + #ifndef _di_level_0_parameter_checking_ + if (!condition) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_cond_broadcast(condition); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_condition_unblock_all_ + +#ifndef _di_f_thread_condition_unblock_any_ + f_return_status f_thread_condition_unblock_any(f_thread_condition_t *condition) { + #ifndef _di_level_0_parameter_checking_ + if (!condition) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_cond_signal(condition); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_condition_unblock_any_ + +#ifndef _di_f_thread_condition_wait_ + f_return_status f_thread_condition_wait(f_thread_condition_t *condition, f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!condition) return F_status_set_error(F_parameter); + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_cond_wait(condition, mutex); + + if (error) { + 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_condition_wait_ + +#ifndef _di_f_thread_condition_wait_timed_ + f_return_status f_thread_condition_wait_timed(const struct timespec *wait, f_thread_condition_t *condition, f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!condition) return F_status_set_error(F_parameter); + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_cond_timedwait(condition, mutex, wait); + + if (error) { + 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_condition_wait_timed_ + +#ifndef _di_f_thread_conditions_decrease_ + f_return_status f_thread_conditions_decrease(f_thread_conditions_t *conditions) { + #ifndef _di_level_0_parameter_checking_ + if (!conditions) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (conditions->size > 1) { + return private_f_thread_conditions_resize(conditions->size - 1, conditions); + } + + return private_f_thread_conditions_delete(conditions); + } +#endif // _di_f_thread_conditions_decrease_ + +#ifndef _di_f_thread_conditions_decrease_by_ + f_return_status f_thread_conditions_decrease_by(const f_array_length_t amount, f_thread_conditions_t *conditions) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!conditions) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (conditions->size - amount > 0) { + return private_f_thread_conditions_resize(conditions->size - amount, conditions); + } + + return private_f_thread_conditions_delete(conditions); + } +#endif // _di_f_thread_conditions_decrease_by_ + +#ifndef _di_f_thread_conditions_delete_ + f_return_status f_thread_conditions_delete(f_thread_conditions_t *conditions) { + #ifndef _di_level_0_parameter_checking_ + if (!conditions) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_conditions_delete(conditions); + } +#endif // _di_f_thread_conditions_delete_ + +#ifndef _di_f_thread_conditions_increase_ + f_return_status f_thread_conditions_increase(f_thread_conditions_t *conditions) { + #ifndef _di_level_0_parameter_checking_ + if (!conditions) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (conditions->used + 1 > conditions->size) { + f_array_length_t size = conditions->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (conditions->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_conditions_resize(size, conditions); + } + + return F_none; + } +#endif // _di_f_thread_conditions_increase_ + +#ifndef _di_f_thread_conditions_increase_by_ + f_return_status f_thread_conditions_increase_by(const f_array_length_t amount, f_thread_conditions_t *conditions) { + #ifndef _di_level_0_parameter_checking_ + if (!conditions) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (conditions->used + amount > conditions->size) { + if (conditions->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_conditions_resize(conditions->used + amount, conditions); + } + + return F_none; + } +#endif // _di_f_thread_conditions_increase_by_ + #ifndef _di_f_thread_create_ - f_return_status f_thread_create(const pthread_attr_t *attribute, pthread_t *id, void *(*routine) (void *), void *argument) { + f_return_status f_thread_create(const f_thread_attribute_t *attribute, f_thread_id_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); + if (error == ETIMEDOUT) return F_time; + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_create_ + +#ifndef _di_f_thread_exit_ + f_return_status f_thread_exit(int *result) { + #ifndef _di_level_0_parameter_checking_ + if (!result) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + pthread_exit(result); + + return F_none; + } +#endif // _di_f_thread_exit_ + +#ifndef _di_f_thread_ids_decrease_ + f_return_status f_thread_ids_decrease(f_thread_ids_t *ids) { + #ifndef _di_level_0_parameter_checking_ + if (!ids) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (ids->size > 1) { + return private_f_thread_ids_resize(ids->size - 1, ids); + } + + return private_f_thread_ids_delete(ids); + } +#endif // _di_f_thread_ids_decrease_ + +#ifndef _di_f_thread_ids_decrease_by_ + f_return_status f_thread_ids_decrease_by(const f_array_length_t amount, f_thread_ids_t *ids) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!ids) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (ids->size - amount > 0) { + return private_f_thread_ids_resize(ids->size - amount, ids); + } + + return private_f_thread_ids_delete(ids); + } +#endif // _di_f_thread_ids_decrease_by_ + +#ifndef _di_f_thread_ids_delete_ + f_return_status f_thread_ids_delete(f_thread_ids_t *ids) { + #ifndef _di_level_0_parameter_checking_ + if (!ids) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_ids_delete(ids); + } +#endif // _di_f_thread_ids_delete_ + +#ifndef _di_f_thread_ids_increase_ + f_return_status f_thread_ids_increase(f_thread_ids_t *ids) { + #ifndef _di_level_0_parameter_checking_ + if (!ids) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (ids->used + 1 > ids->size) { + f_array_length_t size = ids->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (ids->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_ids_resize(size, ids); + } + + return F_none; + } +#endif // _di_f_thread_ids_increase_ + +#ifndef _di_f_thread_ids_increase_by_ + f_return_status f_thread_ids_increase_by(const f_array_length_t amount, f_thread_ids_t *ids) { + #ifndef _di_level_0_parameter_checking_ + if (!ids) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (ids->used + amount > ids->size) { + if (ids->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_ids_resize(ids->used + amount, ids); + } + + return F_none; + } +#endif // _di_f_thread_ids_increase_by_ + +#ifndef _di_f_thread_join_ + f_return_status f_thread_join(const f_thread_id_t id, void **result) { + + const int error = pthread_join(id, result); + + if (error) { + if (error == EDEADLK) return F_status_set_error(F_deadlock); + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == EPERM) return F_status_set_error(F_supported_not); + if (error == ESRCH) return F_status_set_error(F_found_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_join_ + +#ifndef _di_f_thread_join_try_ + f_return_status f_thread_try(const f_thread_id_t id, void **result) { + + const int error = pthread_tryjoin_np(id, result); + + if (error) { + if (error == EBUSY) return F_busy; + if (error == EDEADLK) return F_status_set_error(F_deadlock); + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == EPERM) return F_status_set_error(F_supported_not); + if (error == ESRCH) return F_status_set_error(F_found_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_join_try_ + +#ifndef _di_f_thread_join_timed_ + f_return_status f_thread_timed(const f_thread_id_t id, const struct timespec wait, void **result) { + + const int error = pthread_timedjoin_np(id, result, &wait); + + if (error) { + if (error == EBUSY) return F_busy; + if (error == EDEADLK) return F_status_set_error(F_deadlock); + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == EPERM) return F_status_set_error(F_supported_not); + if (error == ESRCH) return F_status_set_error(F_found_not); + if (error == ETIMEDOUT) return F_time; + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_join_timed_ + +#ifndef _di_f_thread_key_create_ + f_return_status f_thread_key_create(void (*routine) (void *), f_thread_key_t *key) { + #ifndef _di_level_0_parameter_checking_ + if (!routine) return F_status_set_error(F_parameter); + if (!key) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_key_create(key, routine); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == ENOMEM) return F_status_set_error(F_memory_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_key_create_ + +#ifndef _di_f_thread_key_get_ + f_return_status f_thread_key_get(const f_thread_key_t key, void **value) { + #ifndef _di_level_0_parameter_checking_ + if (!value) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + *value = pthread_getspecific(key); + + return F_none; + } +#endif // _di_f_thread_key_get_ + +#ifndef _di_f_thread_key_set_ + f_return_status f_thread_key_set(const f_thread_key_t key, const void *value) { + #ifndef _di_level_0_parameter_checking_ + if (!value) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_setspecific(key, value); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_key_set_ + +#ifndef _di_f_thread_keys_decrease_ + f_return_status f_thread_keys_decrease(f_thread_keys_t *keys) { + #ifndef _di_level_0_parameter_checking_ + if (!keys) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (keys->size > 1) { + return private_f_thread_keys_resize(keys->size - 1, keys); + } + + return private_f_thread_keys_delete(keys); + } +#endif // _di_f_thread_keys_decrease_ + +#ifndef _di_f_thread_keys_decrease_by_ + f_return_status f_thread_keys_decrease_by(const f_array_length_t amount, f_thread_keys_t *keys) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!keys) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (keys->size - amount > 0) { + return private_f_thread_keys_resize(keys->size - amount, keys); + } + + return private_f_thread_keys_delete(keys); + } +#endif // _di_f_thread_keys_decrease_by_ + +#ifndef _di_f_thread_keys_delete_ + f_return_status f_thread_keys_delete(f_thread_keys_t *keys) { + #ifndef _di_level_0_parameter_checking_ + if (!keys) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_keys_delete(keys); + } +#endif // _di_f_thread_keys_delete_ + +#ifndef _di_f_thread_keys_increase_ + f_return_status f_thread_keys_increase(f_thread_keys_t *keys) { + #ifndef _di_level_0_parameter_checking_ + if (!keys) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (keys->used + 1 > keys->size) { + f_array_length_t size = keys->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (keys->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_keys_resize(size, keys); + } + + return F_none; + } +#endif // _di_f_thread_keys_increase_ + +#ifndef _di_f_thread_keys_increase_by_ + f_return_status f_thread_keys_increase_by(const f_array_length_t amount, f_thread_keys_t *keys) { + #ifndef _di_level_0_parameter_checking_ + if (!keys) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (keys->used + amount > keys->size) { + if (keys->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_keys_resize(keys->used + amount, keys); + } + + return F_none; + } +#endif // _di_f_thread_keys_increase_by_ + +#ifndef _di_f_thread_lock_ + f_return_status f_thread_lock(f_thread_lock_t *lock) { + #ifndef _di_level_0_parameter_checking_ + if (!lock) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_rwlock_rdlock(lock); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EDEADLK) return F_status_set_error(F_deadlock); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_lock_ + +#ifndef _di_f_thread_lock_try_ + f_return_status f_thread_lock_try(f_thread_lock_t *lock) { + #ifndef _di_level_0_parameter_checking_ + if (!lock) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_rwlock_tryrdlock(lock); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EBUSY) return F_busy; + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_lock_try_ + +#ifndef _di_f_thread_locks_decrease_ + f_return_status f_thread_locks_decrease(f_thread_locks_t *locks) { + #ifndef _di_level_0_parameter_checking_ + if (!locks) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (locks->size > 1) { + return private_f_thread_locks_resize(locks->size - 1, locks); + } + + return private_f_thread_locks_delete(locks); + } +#endif // _di_f_thread_locks_decrease_ + +#ifndef _di_f_thread_locks_decrease_by_ + f_return_status f_thread_locks_decrease_by(const f_array_length_t amount, f_thread_locks_t *locks) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!locks) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (locks->size - amount > 0) { + return private_f_thread_locks_resize(locks->size - amount, locks); + } + + return private_f_thread_locks_delete(locks); + } +#endif // _di_f_thread_locks_decrease_by_ + +#ifndef _di_f_thread_locks_delete_ + f_return_status f_thread_locks_delete(f_thread_locks_t *locks) { + #ifndef _di_level_0_parameter_checking_ + if (!locks) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_locks_delete(locks); + } +#endif // _di_f_thread_locks_delete_ + +#ifndef _di_f_thread_locks_increase_ + f_return_status f_thread_locks_increase(f_thread_locks_t *locks) { + #ifndef _di_level_0_parameter_checking_ + if (!locks) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (locks->used + 1 > locks->size) { + f_array_length_t size = locks->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (locks->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_locks_resize(size, locks); + } + + return F_none; + } +#endif // _di_f_thread_locks_increase_ + +#ifndef _di_f_thread_locks_increase_by_ + f_return_status f_thread_locks_increase_by(const f_array_length_t amount, f_thread_locks_t *locks) { + #ifndef _di_level_0_parameter_checking_ + if (!locks) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (locks->used + amount > locks->size) { + if (locks->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_locks_resize(locks->used + amount, locks); + } + + return F_none; + } +#endif // _di_f_thread_locks_increase_by_ + +#ifndef _di_f_thread_mutex_create_ + f_return_status f_thread_mutex_create(f_thread_mutex_attribute_t * const attribute, f_thread_mutex_t *mutex) { #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); + if (!mutex) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const int error = pthread_create(id, attribute, routine, argument); + const int error = pthread_mutex_init(mutex, attribute); if (error) { if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EBUSY) return F_status_set_error(F_busy); if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ENOMEM) return F_status_set_error(F_memory_not); if (error == EPERM) return F_status_set_error(F_prohibited); return F_status_set_error(F_failure); @@ -26,65 +1161,407 @@ extern "C" { return F_none; } -#endif // _di_f_thread_create_ +#endif // _di_f_thread_mutex_create_ + +#ifndef _di_f_thread_mutex_delete_ + f_return_status f_thread_mutex_delete(f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_mutex_destroy(mutex); + + if (error) { + if (error == EBUSY) return F_status_set_error(F_busy); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_mutex_delete_ + +#ifndef _di_f_thread_mutex_lock_ + f_return_status f_thread_mutex_lock(f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_mutex_lock(mutex); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EDEADLK) return F_status_set_error(F_deadlock); + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_mutex_lock_ + +#ifndef _di_f_thread_mutex_lock_try_ + f_return_status f_thread_mutex_lock_try(f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_mutex_trylock(mutex); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EBUSY) return F_busy; + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_mutex_lock_try_ + +#ifndef _di_f_thread_mutex_unlock_ + f_return_status f_thread_mutex_unlock(f_thread_mutex_t *mutex) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_mutex_unlock(mutex); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == EBUSY) return F_status_set_error(F_busy); + 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_mutex_unlock_ + +#ifndef _di_f_thread_mutexs_decrease_ + f_return_status f_thread_mutexs_decrease(f_thread_mutexs_t *mutexs) { + #ifndef _di_level_0_parameter_checking_ + if (!mutexs) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutexs->size > 1) { + return private_f_thread_mutexs_resize(mutexs->size - 1, mutexs); + } + + return private_f_thread_mutexs_delete(mutexs); + } +#endif // _di_f_thread_mutexs_decrease_ + +#ifndef _di_f_thread_mutexs_decrease_by_ + f_return_status f_thread_mutexs_decrease_by(const f_array_length_t amount, f_thread_mutexs_t *mutexs) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!mutexs) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutexs->size - amount > 0) { + return private_f_thread_mutexs_resize(mutexs->size - amount, mutexs); + } + + return private_f_thread_mutexs_delete(mutexs); + } +#endif // _di_f_thread_mutexs_decrease_by_ + +#ifndef _di_f_thread_mutexs_delete_ + f_return_status f_thread_mutexs_delete(f_thread_mutexs_t *mutexs) { + #ifndef _di_level_0_parameter_checking_ + if (!mutexs) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_mutexs_delete(mutexs); + } +#endif // _di_f_thread_mutexs_delete_ + +#ifndef _di_f_thread_mutexs_increase_ + f_return_status f_thread_mutexs_increase(f_thread_mutexs_t *mutexs) { + #ifndef _di_level_0_parameter_checking_ + if (!mutexs) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutexs->used + 1 > mutexs->size) { + f_array_length_t size = mutexs->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (mutexs->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_mutexs_resize(size, mutexs); + } + + return F_none; + } +#endif // _di_f_thread_mutexs_increase_ + +#ifndef _di_f_thread_mutexs_increase_by_ + f_return_status f_thread_mutexs_increase_by(const f_array_length_t amount, f_thread_mutexs_t *mutexs) { + #ifndef _di_level_0_parameter_checking_ + if (!mutexs) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutexs->used + amount > mutexs->size) { + if (mutexs->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_mutexs_resize(mutexs->used + amount, mutexs); + } + + return F_none; + } +#endif // _di_f_thread_mutexs_increase_by_ + +#ifndef _di_f_thread_mutex_attributes_decrease_ + f_return_status f_thread_mutex_attributes_decrease(f_thread_mutex_attributes_t *mutex_attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex_attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutex_attributes->size > 1) { + return private_f_thread_mutex_attributes_resize(mutex_attributes->size - 1, mutex_attributes); + } + + return private_f_thread_mutex_attributes_delete(mutex_attributes); + } +#endif // _di_f_thread_mutex_attributes_decrease_ + +#ifndef _di_f_thread_mutex_attributes_decrease_by_ + f_return_status f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_attributes_t *mutex_attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!mutex_attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutex_attributes->size - amount > 0) { + return private_f_thread_mutex_attributes_resize(mutex_attributes->size - amount, mutex_attributes); + } + + return private_f_thread_mutex_attributes_delete(mutex_attributes); + } +#endif // _di_f_thread_mutex_attributes_decrease_by_ + +#ifndef _di_f_thread_mutex_attributes_delete_ + f_return_status f_thread_mutex_attributes_delete(f_thread_mutex_attributes_t *mutex_attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex_attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_mutex_attributes_delete(mutex_attributes); + } +#endif // _di_f_thread_mutex_attributes_delete_ + +#ifndef _di_f_thread_mutex_attributes_increase_ + f_return_status f_thread_mutex_attributes_increase(f_thread_mutex_attributes_t *mutex_attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex_attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutex_attributes->used + 1 > mutex_attributes->size) { + f_array_length_t size = mutex_attributes->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (mutex_attributes->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_mutex_attributes_resize(size, mutex_attributes); + } + + return F_none; + } +#endif // _di_f_thread_mutex_attributes_increase_ + +#ifndef _di_f_thread_mutex_attributes_increase_by_ + f_return_status f_thread_mutex_attributes_increase_by(const f_array_length_t amount, f_thread_mutex_attributes_t *mutex_attributes) { + #ifndef _di_level_0_parameter_checking_ + if (!mutex_attributes) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (mutex_attributes->used + amount > mutex_attributes->size) { + if (mutex_attributes->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_mutex_attributes_resize(mutex_attributes->used + amount, mutex_attributes); + } + + return F_none; + } +#endif // _di_f_thread_mutex_attributes_increase_by_ + +#ifndef _di_f_thread_once_ + f_return_status f_thread_once(void (*routine) (void), f_thread_once_t *once) { + #ifndef _di_level_0_parameter_checking_ + if (!routine) return F_status_set_error(F_parameter); + if (!once) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int error = pthread_once(once, routine); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_once_ + +#ifndef _di_f_thread_onces_decrease_ + f_return_status f_thread_onces_decrease(f_thread_onces_t *onces) { + #ifndef _di_level_0_parameter_checking_ + if (!onces) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (onces->size > 1) { + return private_f_thread_onces_resize(onces->size - 1, onces); + } + + return private_f_thread_onces_delete(onces); + } +#endif // _di_f_thread_onces_decrease_ + +#ifndef _di_f_thread_onces_decrease_by_ + f_return_status f_thread_onces_decrease_by(const f_array_length_t amount, f_thread_onces_t *onces) { + #ifndef _di_level_0_parameter_checking_ + if (!amount) return F_status_set_error(F_parameter); + if (!onces) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (onces->size - amount > 0) { + return private_f_thread_onces_resize(onces->size - amount, onces); + } + + return private_f_thread_onces_delete(onces); + } +#endif // _di_f_thread_onces_decrease_by_ + +#ifndef _di_f_thread_onces_delete_ + f_return_status f_thread_onces_delete(f_thread_onces_t *onces) { + #ifndef _di_level_0_parameter_checking_ + if (!onces) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_thread_onces_delete(onces); + } +#endif // _di_f_thread_onces_delete_ + +#ifndef _di_f_thread_onces_increase_ + f_return_status f_thread_onces_increase(f_thread_onces_t *onces) { + #ifndef _di_level_0_parameter_checking_ + if (!onces) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (onces->used + 1 > onces->size) { + f_array_length_t size = onces->used + f_memory_default_allocation_step; + + if (size > f_array_length_t_size) { + if (onces->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_onces_resize(size, onces); + } + + return F_none; + } +#endif // _di_f_thread_onces_increase_ + +#ifndef _di_f_thread_onces_increase_by_ + f_return_status f_thread_onces_increase_by(const f_array_length_t amount, f_thread_onces_t *onces) { + #ifndef _di_level_0_parameter_checking_ + if (!onces) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (onces->used + amount > onces->size) { + if (onces->used + amount > f_array_length_t_size) { + return F_status_set_error(F_array_too_large); + } + + return private_f_thread_onces_resize(onces->used + amount, onces); + } + + return F_none; + } +#endif // _di_f_thread_onces_increase_by_ #ifndef _di_f_thread_sets_decrease_ - f_return_status f_thread_sets_decrease(f_thread_sets_t *thread_sets) { + f_return_status f_thread_sets_decrease(f_thread_sets_t *sets) { #ifndef _di_level_0_parameter_checking_ - if (!thread_sets) return F_status_set_error(F_parameter); + if (!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); + if (sets->size > 1) { + return private_f_thread_sets_resize(sets->size - 1, sets); } - return private_f_thread_sets_delete(thread_sets); + return private_f_thread_sets_delete(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) { + f_return_status f_thread_sets_decrease_by(const f_array_length_t amount, f_thread_sets_t *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); + if (!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); + if (sets->size - amount > 0) { + return private_f_thread_sets_resize(sets->size - amount, sets); } - return private_f_thread_sets_delete(thread_sets); + return private_f_thread_sets_delete(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) { + f_return_status f_thread_sets_delete(f_thread_sets_t *sets) { #ifndef _di_level_0_parameter_checking_ - if (!thread_sets) return F_status_set_error(F_parameter); + if (!sets) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - return private_f_thread_sets_delete(thread_sets); + return private_f_thread_sets_delete(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) { + f_return_status f_thread_sets_increase(f_thread_sets_t *sets) { #ifndef _di_level_0_parameter_checking_ - if (!thread_sets) return F_status_set_error(F_parameter); + if (!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 (sets->used + 1 > sets->size) { + f_array_length_t size = sets->used + f_memory_default_allocation_step; if (size > f_array_length_t_size) { - if (thread_sets->used + 1 > f_array_length_t_size) { + if (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 private_f_thread_sets_resize(size, sets); } return F_none; @@ -92,23 +1569,83 @@ extern "C" { #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) { + f_return_status f_thread_sets_increase_by(const f_array_length_t amount, f_thread_sets_t *sets) { #ifndef _di_level_0_parameter_checking_ - if (!thread_sets) return F_status_set_error(F_parameter); + if (!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) { + if (sets->used + amount > sets->size) { + if (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 private_f_thread_sets_resize(sets->used + amount, sets); } return F_none; } #endif // _di_f_thread_sets_increase_by_ +#ifndef _di_f_thread_signal_ + f_return_status f_thread_signal(const f_thread_id_t id, const int signal) { + + const int error = pthread_kill(id, signal); + + if (error) { + if (error == EINVAL) return F_status_set_error(F_parameter); + + if (error == ESRCH) { + if (signal) return F_status_set_error(F_found_not); + + return F_found_not; + } + + return F_status_set_error(F_failure); + } + + if (signal) { + return F_none; + } + + return F_found; + } +#endif // _di_f_thread_signal_ + +#ifndef _di_f_thread_signal_mask_ + f_return_status f_thread_signal_mask(const int how, const sigset_t *next, sigset_t *current) { + #ifndef _di_level_0_parameter_checking_ + if (!next && !current) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (pthread_sigmask(how, next, current) < 0) { + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINVAL) return F_status_set_error(F_parameter); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_signal_mask_ + +#ifndef _di_f_thread_signal_queue_ + f_return_status f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value) { + + const int error = pthread_sigqueue(id, signal, value); + + if (error) { + if (error == EAGAIN) return F_status_set_error(F_resource_not); + if (error == ENOSYS) return F_status_set_error(F_supported_not); + if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ESRCH) return F_status_set_error(F_found_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_thread_signal_queue_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_thread/c/thread.h b/level_0/f_thread/c/thread.h index 93271c1..7178748 100644 --- a/level_0/f_thread/c/thread.h +++ b/level_0/f_thread/c/thread.h @@ -5,53 +5,1796 @@ * API Version: 0.5 * Licenses: lgplv2.1 * - * Provides POSIX thread_sets related functionality. + * Provides POSIX sets related functionality. */ #ifndef _F_thread_h #define _F_thread_h +// include pre-requirements +#define _GNU_SOURCE + // libc includes +#include #include +#include #include #include -// fll-0 includes -#include -#include -#include +// fll-0 includes +#include +#include +#include + +// fll-0 thread includes +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform a fork operation. + * + * @param before + * The function to call before forking. + * @param after_parent + * The function called after forking, for the parent process. + * @param child_parent + * The function called after forking, for the child process. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_memory_not (with error bit) if out of memory. + * F_failure (with error bit) on any other error. + * + * @see pthread_atfork() + */ +#ifndef _di_f_thread_at_fork_ + extern f_return_status f_thread_at_fork(void (*before) (void), void (*after_parent) (void), void (*after_child) (void)); +#endif // _di_f_thread_at_fork_ + +/** + * Get the affinity state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param affinity_size + * The size of the affinity_set. + * @param affinity_set + * The assigned affinity information. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getaffinity_np() + */ +#ifndef _di_f_thread_attribute_affinity_get_ + extern f_return_status f_thread_attribute_affinity_get(const f_thread_attribute_t attribute, const size_t affinity_size, cpu_set_t *affinity_set); +#endif // _di_f_thread_attribute_affinity_get_ + +/** + * Set the affinity state of the thread attribute. + * + * @param affinity_size + * The size of the affinity_set. + * @param affinity_set + * The affinity information to assign. + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setaffinity_np() + */ +#ifndef _di_f_thread_attribute_affinity_set_ + extern f_return_status f_thread_attribute_affinity_set(const size_t affinity_size, const cpu_set_t *affinity_set, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_affinity_set_ + +/** + * Create (initialize) a thread attribute structure. + * + * @param attribute + * The thread attributes to create. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_memory_not (with error bit) if out of memory. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_init() + */ +#ifndef _di_f_thread_attribute_create_ + extern f_return_status f_thread_attribute_create(f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_create_ + +/** + * Get the default thread attribute. + * + * @param attribute + * The thread attributes to process. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_getattr_default_np() + */ +#ifndef _di_f_thread_attribute_default_get_ + extern f_return_status f_thread_attribute_default_get(f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_default_get_ + +/** + * Set the default thread attribute. + * + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_setattr_default_np() + */ +#ifndef _di_f_thread_attribute_default_set_ + extern f_return_status f_thread_attribute_default_set(f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_default_set_ + +/** + * Delete a thread attribute structure. + * + * On successfully delete, the pointer address is set to 0. + * + * @param attribute + * The thread attributes to delete. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_destroy() + */ +#ifndef _di_f_thread_attribute_delete_ + extern f_return_status f_thread_attribute_delete(f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_delete_ + +/** + * Get the detached state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param state + * The currently assigned state. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getdetachstate() + */ +#ifndef _di_f_thread_attribute_detach_get_ + extern f_return_status f_thread_attribute_detach_get(const f_thread_attribute_t attribute, int *state); +#endif // _di_f_thread_attribute_detach_get_ + +/** + * Set the detached state of the thread attribute. + * + * @param state + * The state to assign (such as PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE). + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setdetachstate() + */ +#ifndef _di_f_thread_attribute_detach_set_ + extern f_return_status f_thread_attribute_detach_set(const int state, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_detach_set_ + +/** + * Get the guard size of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param guard + * The currently assigned guard size. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getguardsize() + */ +#ifndef _di_f_thread_attribute_guard_get_ + extern f_return_status f_thread_attribute_guard_get(const f_thread_attribute_t attribute, size_t *guard); +#endif // _di_f_thread_attribute_guard_get_ + +/** + * Set the guard size of the thread attribute. + * + * @param guard + * The guard size to assign. + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setguardsize() + */ +#ifndef _di_f_thread_attribute_guard_set_ + extern f_return_status f_thread_attribute_guard_set(const size_t guard, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_guard_set_ + +/** + * Get the scheduler inherit state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param inherit + * The currently assigned scheduler inherit state. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getinheritsched() + */ +#ifndef _di_f_thread_attribute_scheduler_inherit_get_ + extern f_return_status f_thread_attribute_scheduler_inherit_get(const f_thread_attribute_t attribute, int *inherit); +#endif // _di_f_thread_attribute_scheduler_inherit_get_ + +/** + * Set the scheduler inherit state of the thread attribute. + * + * @param inherit + * The inherit state of the scheduler (such as PTHREAD_INHERIT_SCHED or PTHREAD_EXPLICIT_SCHED). + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setinheritsched() + */ +#ifndef _di_f_thread_attribute_scheduler_inherit_set_ + extern f_return_status f_thread_attribute_scheduler_inherit_set(const int inherit, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_scheduler_inherit_set_ + +/** + * Get the scheduler parameter state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param parameter + * The currently assigned scheduler parameters. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getschedparam() + */ +#ifndef _di_f_thread_attribute_scheduler_parameter_get_ + extern f_return_status f_thread_attribute_scheduler_parameter_get(const f_thread_attribute_t attribute, struct sched_param *parameter); +#endif // _di_f_thread_attribute_scheduler_parameter_get_ + +/** + * Set the scheduler parameter state of the thread attribute. + * + * @param parameter + * The parameters of the scheduler. + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setschedparam() + */ +#ifndef _di_f_thread_attribute_scheduler_parameter_set_ + extern f_return_status f_thread_attribute_scheduler_parameter_set(const struct sched_param parameter, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_scheduler_parameter_set_ + +/** + * Get the scheduler policy state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param policy + * The currently assigned scheduler policy state. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getschedpolicy() + */ +#ifndef _di_f_thread_attribute_scheduler_policy_get_ + extern f_return_status f_thread_attribute_scheduler_policy_get(const f_thread_attribute_t attribute, int *policy); +#endif // _di_f_thread_attribute_scheduler_policy_get_ + +/** + * Set the scheduler policy state of the thread attribute. + * + * @param policy + * The policy state of the scheduler (such as SCHED_FIFO, SCHED_RR, or SCHED_OTHER). + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setschedpolicy() + */ +#ifndef _di_f_thread_attribute_scheduler_policy_set_ + extern f_return_status f_thread_attribute_scheduler_policy_set(const int policy, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_scheduler_policy_set_ + +/** + * Get the scheduler scope state of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param scope + * The currently assigned scheduler scope state. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getscope() + */ +#ifndef _di_f_thread_attribute_scope_get_ + extern f_return_status f_thread_attribute_scope_get(const f_thread_attribute_t attribute, int *scope); +#endif // _di_f_thread_attribute_scope_get_ + +/** + * Set the scheduler scope state of the thread attribute. + * + * @param scope + * The scope state of the scheduler (such as PTHREAD_SCOPE_SYSTEM or PTHREAD_SCOPE_PROCESS). + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_supported_not (with error bit) if the scope is not supported by the current OS (such as Linux not supporting PTHREAD_SCOPE_PROCESS). + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setscope() + */ +#ifndef _di_f_thread_attribute_scope_set_ + extern f_return_status f_thread_attribute_scope_set(const int scope, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_scope_set_ + +/** + * Get the stack of the thread attribute. + * + * @param attribute + * The thread attributes to process. + * @param stack_size + * The size of the stack. + * @param stack + * The assigned stack. + * + * @return + * F_none on success. + * F_access_denied (with error bit) if the caller cannot both read and write to the stack address. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_getstack() + */ +#ifndef _di_f_thread_attribute_stack_get_ + extern f_return_status f_thread_attribute_stack_get(const f_thread_attribute_t attribute, size_t *stack_size, void **stack); +#endif // _di_f_thread_attribute_stack_get_ + +/** + * Set the stack of the thread attribute. + * + * @param stack_size + * The size of the stack_set. + * @param stack + * The stack to assign. + * @param attribute + * The thread attributes to update. + * + * @return + * F_none on success. + * F_access_denied (with error bit) if the caller cannot both read and write to the stack address. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_attr_setstack() + */ +#ifndef _di_f_thread_attribute_stack_set_ + extern f_return_status f_thread_attribute_stack_set(const size_t stack_size, void * const stack, f_thread_attribute_t *attribute); +#endif // _di_f_thread_attribute_stack_set_ + +/** + * Resize the attributes 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 attributes + * 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_attributes_decrease_ + extern f_return_status f_thread_attributes_decrease(f_thread_attributes_t *attributes); +#endif // _di_f_thread_attributes_decrease_ + +/** + * Resize the attributes 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 attributes + * 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_attributes_decrease_by_ + extern f_return_status f_thread_attributes_decrease_by(const f_array_length_t amount, f_thread_attributes_t *attributes); +#endif // _di_f_thread_attributes_decrease_by_ + +/** + * Delete the attributes 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_attributes_delete_ + extern f_return_status f_thread_attributes_delete(f_thread_attributes_t *attributes); +#endif // _di_f_thread_attributes_delete_ + +/** + * Increase the size of the attributes 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 attributes + * 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_attributes_increase_ + extern f_return_status f_thread_attributes_increase(f_thread_attributes_t *attributes); +#endif // _di_f_thread_attributes_increase_ + +/** + * Resize the attributes 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 attributes + * 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_attributes_increase_by_ + extern f_return_status f_thread_attributes_increase_by(const f_array_length_t amount, f_thread_attributes_t *attributes); +#endif // _di_f_thread_attributes_increase_by_ + +/** + * Get the ID of the calling thread. + * + * @return + * ID of the calling thread + * + * @see pthread_self() + */ +#ifndef _di_f_thread_caller_ + extern f_thread_id_t f_thread_caller(); +#endif // _di_f_thread_caller_ + +/** + * Cancel a thread. + * + * @param id + * The thread to cancel. + * + * @return + * F_none on success. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_failure (with error bit) on any other error. + * + * @see pthread_cancel() + */ +#ifndef _di_f_thread_cancel_ + extern f_return_status f_thread_cancel(const f_thread_id_t id); +#endif // _di_f_thread_cancel_ + +/** + * Assign a cancellation state. + * + * @param state + * The cancellation state to assign. + * @param previous + * (optional) The previously assigned cancellation state. + * Set to NULL to not use. + * (Note: Linux allows this to be optional/NULL but POSIX does not explicitly defined this and there may be portability issues.) + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_setcancelstate() + */ +#ifndef _di_f_thread_cancel_state_set_ + extern f_return_status f_thread_cancel_state_set(const int state, int *previous); +#endif // _di_f_thread_cancel_state_set_ + +/** + * Force any pending thread cancellation to be processed. + * + * If there is no pending thread cancel, nothing happens. + * If there is a pending thread cancel, the thread cancels and this function never returns. + * + * @return + * F_none on success. + * + * @see pthread_testcancel() + */ +#ifndef _di_f_thread_cancel_test_ + extern f_return_status f_thread_cancel_test(); +#endif // _di_f_thread_cancel_test_ + +/** + * Assign a cancellation type. + * + * @param type + * The cancellation type to assign. + * @param previous + * (optional) The previously assigned cancellation type. + * Set to NULL to not use. + * (Note: Linux allows this to be optional/NULL but POSIX does not explicitly defined this and there may be portability issues.) + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_setcanceltype() + */ +#ifndef _di_f_thread_cancel_type_set_ + extern f_return_status f_thread_cancel_type_set(const int type, int *previous); +#endif // _di_f_thread_cancel_type_set_ + +/** + * Get the clock ID for the given thread. + * + * @param id_thread + * The ID of the thread to use. + * @param id_clock + * The retrieved clock ID. + * + * @return + * F_none on success. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_supported_not (with error bit) if per-CPU clocks are not supported by the OS. + * F_failure (with error bit) on any other error. + * + * @see pthread_equal() + */ +#ifndef _di_f_thread_clock_get_id_ + extern f_return_status f_thread_clock_get_id(const f_thread_id_t id_thread, clockid_t *id_clock); +#endif // _di_f_thread_clock_get_id_ + +/** + * Compare two different thread IDs. + * + * POSIX designates that the thread id (pthread_t) to be loosely defined and can be anything from an integer to a structure. + * For portability purposes, calling pthread_equal() is the only safe way to compare two thread ids. + * + * @return + * F_equal_to if the two thread IDs are the same. + * F_equal_to_not if the two thread IDs are different. + * + * @see pthread_equal() + */ +#ifndef _di_f_thread_compare_ + extern f_return_status f_thread_compare(const f_thread_id_t id1, const f_thread_id_t id2); +#endif // _di_f_thread_compare_ + +/** + * Unblock all threads waiting on a condition. + * + * @param condition + * The condition to broadcast the unblock signal to. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_cond_broadcast() + */ +#ifndef _di_f_thread_condition_unblock_all_ + extern f_return_status f_thread_condition_unblock_all(f_thread_condition_t *condition); +#endif // _di_f_thread_condition_unblock_all_ + +/** + * Unblock all threads waiting on a condition. + * + * @param condition + * The condition to broadcast the unblock signal to. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_cond_signal() + */ +#ifndef _di_f_thread_condition_unblock_any_ + extern f_return_status f_thread_condition_unblock_any(f_thread_condition_t *condition); +#endif // _di_f_thread_condition_unblock_any_ + +/** + * Wait until condition is triggered. + * + * This is a blocking operation. + * + * @param condition + * The condition to wait on. + * @param mutex + * The mutex to use for waiting on condition. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_cond_wait() + */ +#ifndef _di_f_thread_condition_wait_ + extern f_return_status f_thread_condition_wait(f_thread_condition_t *condition, f_thread_mutex_t *mutex); +#endif // _di_f_thread_condition_wait_ + +/** + * Wait until condition is triggered, blocking until the timeout expires. + * + * This is a semi-blocking operation. + * This will block until timeout and then no longer block. + * + * @param wait + * The amount of time to wait for. + * The wait time is relative to the clock, so consider calling clock_gettime() and then adding the amount of wait time. + * @param condition + * The condition to wait on. + * @param mutex + * The mutex to use for waiting on condition. + * + * @return + * F_none on success. + * F_time on success, and wait timeout was reached before condition was triggered. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if not allowed to perform the operation (possibly because mutex is not owned by current thread). + * F_failure (with error bit) on any other error. + * + * @see pthread_cond_timedwait() + */ +#ifndef _di_f_thread_condition_wait_timed_ + extern f_return_status f_thread_condition_wait_timed(const struct timespec *wait, f_thread_condition_t *condition, f_thread_mutex_t *mutex); +#endif // _di_f_thread_condition_wait_timed_ + +/** + * Resize the conditions 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 conditions + * 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_conditions_decrease_ + extern f_return_status f_thread_conditions_decrease(f_thread_conditions_t *conditions); +#endif // _di_f_thread_conditions_decrease_ + +/** + * Resize the conditions 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 conditions + * 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_conditions_decrease_by_ + extern f_return_status f_thread_conditions_decrease_by(const f_array_length_t amount, f_thread_conditions_t *conditions); +#endif // _di_f_thread_conditions_decrease_by_ + +/** + * Delete the conditions 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_conditions_delete_ + extern f_return_status f_thread_conditions_delete(f_thread_conditions_t *conditions); +#endif // _di_f_thread_conditions_delete_ + +/** + * Increase the size of the conditions 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 conditions + * 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_conditions_increase_ + extern f_return_status f_thread_conditions_increase(f_thread_conditions_t *conditions); +#endif // _di_f_thread_conditions_increase_ + +/** + * Resize the conditions 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 conditions + * 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_conditions_increase_by_ + extern f_return_status f_thread_conditions_increase_by(const f_array_length_t amount, f_thread_conditions_t *conditions); +#endif // _di_f_thread_conditions_increase_by_ + +/** + * 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 f_thread_attribute_t *attribute, f_thread_id_t *id, void *(*routine) (void *), void *argument); +#endif // _di_f_thread_create_ + +/** + * Detatch the given thread. + * + * When a detached thread exits, the resources will automatically be returned to the system without needing another thread to join with it. + * + * Only joinable, undetached, threads are detachable. + * + * Once a thread is detached, it can no longer be joined. + * + * @param id + * The ID of the thread to detach. + * + * @return + * F_none on success. + * F_deadlock (with error bit) if operation would cause a deadlock.ead. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_parameter (with error bit) if a parameter is invalid. + * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thr + * + * + * @see pthread_detach() + */ +#ifndef _di_f_thread_detach_ + extern f_return_status f_thread_detach(const f_thread_id_t id); +#endif // _di_f_thread_detach_ + +/** + * Have the current thread exit. + * + * @param result + * The code returned by the exited thread. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see pthread_exit() + */ +#ifndef _di_f_thread_exit_ + extern f_return_status f_thread_exit(int *result); +#endif // _di_f_thread_exit_ + +/** + * Resize the ids 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 ids + * 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_ids_decrease_ + extern f_return_status f_thread_ids_decrease(f_thread_ids_t *ids); +#endif // _di_f_thread_ids_decrease_ + +/** + * Resize the ids 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 ids + * 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_ids_decrease_by_ + extern f_return_status f_thread_ids_decrease_by(const f_array_length_t amount, f_thread_ids_t *ids); +#endif // _di_f_thread_ids_decrease_by_ + +/** + * Delete the ids 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_ids_delete_ + extern f_return_status f_thread_ids_delete(f_thread_ids_t *ids); +#endif // _di_f_thread_ids_delete_ + +/** + * Increase the size of the ids 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 ids + * 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_ids_increase_ + extern f_return_status f_thread_ids_increase(f_thread_ids_t *ids); +#endif // _di_f_thread_ids_increase_ + +/** + * Resize the ids 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 ids + * 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_ids_increase_by_ + extern f_return_status f_thread_ids_increase_by(const f_array_length_t amount, f_thread_ids_t *ids); +#endif // _di_f_thread_ids_increase_by_ + +/** + * Wait until the given thread exits and then join it to the current thread. + * + * This is a blocking operation. + * + * @param id + * The ID of the thread to wait for. + * @param result + * (optional) The data returned by the terminated thread (usually the exist status). + * If the terminated thread is cancelled, then this holds PTHREAD_CANCELED. + * Set to NULL to not use. + * + * @return + * F_none on success. + * F_deadlock (with error bit) if operation would cause a deadlock.ead. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_parameter (with error bit) if a parameter is invalid. + * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thr + * + * + * @see pthread_join() + */ +#ifndef _di_f_thread_join_ + extern f_return_status f_thread_join(const f_thread_id_t id, void **result); +#endif // _di_f_thread_join_ + +/** + * Try to join the given thread to the current thread. + * + * This is a non-blocking operation. + * + * @param id + * The ID of the thread to wait for. + * @param result + * (optional) The data returned by the terminated thread (usually the exist status). + * If the terminated thread is cancelled, then this holds PTHREAD_CANCELED. + * Set to NULL to not use. + * + * @return + * F_none on success. + * F_busy on success, but thread could not be joined because it has not yet exited. + * F_deadlock (with error bit) if operation would cause a deadlock.ead. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_parameter (with error bit) if a parameter is invalid. + * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thr + * + * + * @see pthread_tryjoin_np() + */ +#ifndef _di_f_thread_join_try_ + extern f_return_status f_thread_try(const f_thread_id_t id, void **result); +#endif // _di_f_thread_join_try_ + +/** + * Try to join the given thread to the current thread, blocking until the timeout expires. + * + * This is a semi-blocking operation. + * This will block until timeout and then no longer block. + * + * @param id + * The ID of the thread to wait for. + * @param wait + * The amount of time to wait for. + * The wait time is relative to the clock, so consider calling clock_gettime() and then adding the amount of wait time. + * @param result + * (optional) The data returned by the terminated thread (usually the exist status). + * If the terminated thread is cancelled, then this holds PTHREAD_CANCELED. + * Set to NULL to not use. + * + * @return + * F_none on success. + * F_busy on success, but thread could not be joined because it has not yet exited. + * F_time on success, but thread could not be joined because it has not yet exited and the wait timeout was reached. + * F_deadlock (with error bit) if operation would cause a deadlock. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_parameter (with error bit) if a parameter is invalid. + * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thread. + * + * + * @see pthread_timedjoin_np() + */ +#ifndef _di_f_thread_join_timed_ + extern f_return_status f_thread_timed(const f_thread_id_t id, const struct timespec wait, void **result); +#endif // _di_f_thread_join_timed_ + +/** + * Create a thread key. + * + * @param routine + * The function to execute for deallocation/deleting. + * @param key + * The thread key. + * + * @return + * F_none on success. + * F_memory_not (with error bit) if out of memory. + * 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_failure (with error bit) on any other error. + * + * @see pthread_key_create() + */ +#ifndef _di_f_thread_key_create_ + extern f_return_status f_thread_key_create(void (*routine) (void *), f_thread_key_t *key); +#endif // _di_f_thread_key_create_ + +/** + * Get the value of a thread key. + * + * @param key + * The thread key. + * @param value + * The assigned thread key value. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see pthread_getspecific() + */ +#ifndef _di_f_thread_key_get_ + extern f_return_status f_thread_key_get(const f_thread_key_t key, void **value); +#endif // _di_f_thread_key_get_ + +/** + * Get the value of a thread key. + * + * @param key + * The thread key. + * @param value + * The thread key value to assign. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see pthread_setspecific() + */ +#ifndef _di_f_thread_key_set_ + extern f_return_status f_thread_key_set(const f_thread_key_t key, const void *value); +#endif // _di_f_thread_key_set_ + +/** + * Resize the keys 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 keys + * 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_keys_decrease_ + extern f_return_status f_thread_keys_decrease(f_thread_keys_t *keys); +#endif // _di_f_thread_keys_decrease_ + +/** + * Resize the keys 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 keys + * 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_keys_decrease_by_ + extern f_return_status f_thread_keys_decrease_by(const f_array_length_t amount, f_thread_keys_t *keys); +#endif // _di_f_thread_keys_decrease_by_ + +/** + * Delete the keys 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_keys_delete_ + extern f_return_status f_thread_keys_delete(f_thread_keys_t *keys); +#endif // _di_f_thread_keys_delete_ + +/** + * Increase the size of the keys 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 keys + * 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_keys_increase_ + extern f_return_status f_thread_keys_increase(f_thread_keys_t *keys); +#endif // _di_f_thread_keys_increase_ + +/** + * Resize the keys 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 keys + * 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_keys_increase_by_ + extern f_return_status f_thread_keys_increase_by(const f_array_length_t amount, f_thread_keys_t *keys); +#endif // _di_f_thread_keys_increase_by_ + +/** + * Make a read lock on the read/write lock. + * + * @param lock + * The read/write lock. + * + * @return + * F_none on success. + * F_deadlock (with error bit) if operation would cause a deadlock. + * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if max read/write locks is reached. + * + * @see pthread_rwlock_rdlock() + */ +#ifndef _di_f_thread_lock_ + extern f_return_status f_thread_lock(f_thread_lock_t *lock); +#endif // _di_f_thread_lock_ + +/** + * Try to make a read lock on the read/write lock. + * + * @param lock + * The read/write lock. + * + * @return + * F_none on success. + * F_busy on success, but the read/write lock is already locked. + * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if max read/write locks is reached. + * + * @see pthread_rwlock_tryrdlock() + */ +#ifndef _di_f_thread_lock_try_ + extern f_return_status f_thread_lock_try(f_thread_lock_t *lock); +#endif // _di_f_thread_lock_try_ + +/** + * Resize the locks 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 locks + * 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_locks_decrease_ + extern f_return_status f_thread_locks_decrease(f_thread_locks_t *locks); +#endif // _di_f_thread_locks_decrease_ + +/** + * Resize the locks 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 locks + * 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_locks_decrease_by_ + extern f_return_status f_thread_locks_decrease_by(const f_array_length_t amount, f_thread_locks_t *locks); +#endif // _di_f_thread_locks_decrease_by_ + +/** + * Delete the locks 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_locks_delete_ + extern f_return_status f_thread_locks_delete(f_thread_locks_t *locks); +#endif // _di_f_thread_locks_delete_ + +/** + * Increase the size of the locks 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 locks + * 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_locks_increase_ + extern f_return_status f_thread_locks_increase(f_thread_locks_t *locks); +#endif // _di_f_thread_locks_increase_ + +/** + * Resize the locks 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 locks + * 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_locks_increase_by_ + extern f_return_status f_thread_locks_increase_by(const f_array_length_t amount, f_thread_locks_t *locks); +#endif // _di_f_thread_locks_increase_by_ + +/** + * Create a thread mutex. + * + * @param attribute + * (optional) The mutex attributes to set. + * Set to NULL to not use (in which case the default attributes are used). + * @param mutex + * The mutex to create. + * + * @return + * F_none on success. + * F_busy (with error bit) if the mutex is busy. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if not allowed to perform the operation. + * F_resource_not (with error bit) if max mutexes is reached. + * F_failure (with error bit) on any other error. + * + * @see pthread_mutex_init() + */ +#ifndef _di_f_thread_mutex_create_ + extern f_return_status f_thread_mutex_create(f_thread_mutex_attribute_t * const attribute, f_thread_mutex_t *mutex); +#endif // _di_f_thread_mutex_create_ + +/** + * Create a thread mutex. + * + * @param mutex + * The mutex to delete. + * + * @return + * F_none on success. + * F_busy (with error bit) if the mutex is busy. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see pthread_mutex_destroy() + */ +#ifndef _di_f_thread_mutex_delete_ + extern f_return_status f_thread_mutex_delete(f_thread_mutex_t *mutex); +#endif // _di_f_thread_mutex_delete_ + +/** + * Lock the mutex. + * + * This is a blocking function. + * + * @param mutex + * The thread mutex. + * + * @return + * F_none on success. + * F_deadlock (with error bit) if operation would cause a deadlock. + * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if max mutex locks is reached. + * + * @see pthread_mutex_lock() + */ +#ifndef _di_f_thread_mutex_lock_ + extern f_return_status f_thread_mutex_lock(f_thread_mutex_t *mutex); +#endif // _di_f_thread_mutex_lock_ + +/** + * Try to lock the mutex. + * + * If mutex is already locked, return immediately. + * + * This is a non-blocking function. + * + * @param mutex + * The thread mutex. + * + * @return + * F_none on success. + * F_busy on success, but the mutex is already locked. + * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if max mutex locks is reached. + * + * @see pthread_mutex_trylock() + */ +#ifndef _di_f_thread_mutex_lock_try_ + extern f_return_status f_thread_mutex_lock_try(f_thread_mutex_t *mutex); +#endif // _di_f_thread_mutex_lock_try_ + +/** + * Unlock the mutex. + * + * @param mutex + * The thread mutex. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if not allowed to perform the operation (possibly because mutex is not owned by current thread). + * F_resource_not (with error bit) if max mutex locks is reached. + * + * @see pthread_mutex_unlock() + */ +#ifndef _di_f_thread_mutex_unlock_ + extern f_return_status f_thread_mutex_unlock(f_thread_mutex_t *mutex); +#endif // _di_f_thread_mutex_unlock_ + +/** + * Resize the mutexs 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 mutexs + * 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_mutexs_decrease_ + extern f_return_status f_thread_mutexs_decrease(f_thread_mutexs_t *mutexs); +#endif // _di_f_thread_mutexs_decrease_ + +/** + * Resize the mutexs 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 mutexs + * 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_mutexs_decrease_by_ + extern f_return_status f_thread_mutexs_decrease_by(const f_array_length_t amount, f_thread_mutexs_t *mutexs); +#endif // _di_f_thread_mutexs_decrease_by_ + +/** + * Delete the mutexs 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_mutexs_delete_ + extern f_return_status f_thread_mutexs_delete(f_thread_mutexs_t *mutexs); +#endif // _di_f_thread_mutexs_delete_ -// fll-0 thread includes -#include +/** + * Increase the size of the mutexs 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 mutexs + * 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_mutexs_increase_ + extern f_return_status f_thread_mutexs_increase(f_thread_mutexs_t *mutexs); +#endif // _di_f_thread_mutexs_increase_ -#ifdef __cplusplus -extern "C" { -#endif +/** + * Resize the mutexs 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 mutexs + * 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_mutexs_increase_by_ + extern f_return_status f_thread_mutexs_increase_by(const f_array_length_t amount, f_thread_mutexs_t *mutexs); +#endif // _di_f_thread_mutexs_increase_by_ /** - * Get the user account by the user id. + * Resize the mutex_attributes array to a smaller size, by 1. * - * @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. + * This will shrink the size by size - 1. + * This will not shrink the size to less than 0. + * + * @param mutex_attributes + * 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_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. + */ +#ifndef _di_f_thread_mutex_attributes_decrease_ + extern f_return_status f_thread_mutex_attributes_decrease(f_thread_mutex_attributes_t *mutex_attributes); +#endif // _di_f_thread_mutex_attributes_decrease_ + +/** + * Resize the mutex_attributes array to a smaller size. * - * @see pthread_create() + * 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 mutex_attributes + * 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_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_ +#ifndef _di_f_thread_mutex_attributes_decrease_by_ + extern f_return_status f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_attributes_t *mutex_attributes); +#endif // _di_f_thread_mutex_attributes_decrease_by_ + +/** + * Delete the mutex_attributes 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_mutex_attributes_delete_ + extern f_return_status f_thread_mutex_attributes_delete(f_thread_mutex_attributes_t *mutex_attributes); +#endif // _di_f_thread_mutex_attributes_delete_ + +/** + * Increase the size of the mutex_attributes 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 mutex_attributes + * 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_mutex_attributes_increase_ + extern f_return_status f_thread_mutex_attributes_increase(f_thread_mutex_attributes_t *mutex_attributes); +#endif // _di_f_thread_mutex_attributes_increase_ + +/** + * Resize the mutex_attributes 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 mutex_attributes + * 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_mutex_attributes_increase_by_ + extern f_return_status f_thread_mutex_attributes_increase_by(const f_array_length_t amount, f_thread_mutex_attributes_t *mutex_attributes); +#endif // _di_f_thread_mutex_attributes_increase_by_ + +/** + * Call the given routine only one time and never again. + * + * Subsequent calls will not call the given routine. + * + * @param once + * The once variable designating that the given routine will be called only once. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see pthread_once() + */ +#ifndef _di_f_thread_once_ + extern f_return_status f_thread_once(void (*routine) (void), f_thread_once_t *once); +#endif // _di_f_thread_once_ + +/** + * Resize the onces 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 onces + * 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_onces_decrease_ + extern f_return_status f_thread_onces_decrease(f_thread_onces_t *onces); +#endif // _di_f_thread_onces_decrease_ + +/** + * Resize the onces 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 onces + * 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_onces_decrease_by_ + extern f_return_status f_thread_onces_decrease_by(const f_array_length_t amount, f_thread_onces_t *onces); +#endif // _di_f_thread_onces_decrease_by_ + +/** + * Delete the onces 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_onces_delete_ + extern f_return_status f_thread_onces_delete(f_thread_onces_t *onces); +#endif // _di_f_thread_onces_delete_ + +/** + * Increase the size of the onces 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 onces + * 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_onces_increase_ + extern f_return_status f_thread_onces_increase(f_thread_onces_t *onces); +#endif // _di_f_thread_onces_increase_ + +/** + * Resize the onces 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 onces + * 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_onces_increase_by_ + extern f_return_status f_thread_onces_increase_by(const f_array_length_t amount, f_thread_onces_t *onces); +#endif // _di_f_thread_onces_increase_by_ /** * Resize the thread set array to a smaller size, by 1. @@ -59,7 +1802,7 @@ extern "C" { * This will shrink the size by size - 1. * This will not shrink the size to less than 0. * - * @param thread_sets + * @param sets * The string array to resize. * * @return @@ -69,7 +1812,7 @@ extern "C" { * 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); + extern f_return_status f_thread_sets_decrease(f_thread_sets_t *sets); #endif // _di_f_thread_sets_decrease_ /** @@ -81,7 +1824,7 @@ extern "C" { * * @param amount * A positive number representing how much to decrease the size by. - * @param thread_sets + * @param sets * The string array to resize. * * @return @@ -91,7 +1834,7 @@ extern "C" { * 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); + extern f_return_status f_thread_sets_decrease_by(const f_array_length_t amount, f_thread_sets_t *sets); #endif // _di_f_thread_sets_decrease_by_ /** @@ -105,7 +1848,7 @@ extern "C" { * 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); + extern f_return_status f_thread_sets_delete(f_thread_sets_t *sets); #endif // _di_f_thread_sets_delete_ /** @@ -114,7 +1857,7 @@ extern "C" { * 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 + * @param sets * The string array to resize. * * @return @@ -125,7 +1868,7 @@ extern "C" { * 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); + extern f_return_status f_thread_sets_increase(f_thread_sets_t *sets); #endif // _di_f_thread_sets_increase_ /** @@ -137,7 +1880,7 @@ extern "C" { * * @param amount * A positive number representing how much to increase the size by. - * @param thread_sets + * @param sets * The string array to resize. * * @return @@ -148,9 +1891,81 @@ extern "C" { * 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); + extern f_return_status f_thread_sets_increase_by(const f_array_length_t amount, f_thread_sets_t *sets); #endif // _di_f_thread_sets_increase_by_ +/** + * Send a signal to the given thread. + * + * @param id + * The ID of the thread to signal. + * @param signal + * The signal to send to the thread. + * If 0 is used instead of a valid signal, then instead check to see if the thread exists. + * + * @return + * F_none on success and signal is not 0. + * F_found on success, signal is 0, and the thread by the given ID does exist. + * F_found_not on success, signal is 0, and the thread by the given ID does not exist. + * F_found_not (with error bit) if no thread by the given ID was found (and signal is not 0). + * F_parameter (with error bit) if a parameter is invalid. + * + * @see pthread_kill() + */ +#ifndef _di_f_thread_signal_ + extern f_return_status f_thread_signal(const f_thread_id_t id, const int signal); +#endif // _di_f_thread_signal_ + +/** + * Get or assign the current signal set in use. + * + * Either set or previous may be NULL but not both (at least one is required). + * + * @param how + * How to handle the signal. + * Set this to 0 when only trying to get the current signal set. + * @param next + * (optional) The new set of signals to handle. + * Set to NULL to not use. + * @param current + * (optional) The current set of signals being handled. + * Set to NULL to not use. + * + * @return + * F_none on success but no signal found. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) for any other error. + * + * @see pthread_sigmask() + */ +#ifndef _di_f_thread_signal_mask_ + extern f_return_status f_thread_signal_mask(const int how, const sigset_t *next, sigset_t *current); +#endif // _di_f_thread_signal_mask_ + +/** + * Send the signal and value to the given thread. + * + * @param id + * The ID of the thread to signal. + * @param signal + * The signal to send to the thread. + * @param value + * The signal value to send. + * + * @return + * F_none on success but no signal found. + * F_found_not (with error bit) if no thread by the given ID was found. + * F_parameter (with error bit) if a parameter is invalid. + * F_resource_not (with error bit) if the max signals is reached. + * F_supported_not (with error bit) if this action is not supported by the current OS. + * F_failure (with error bit) for any other error. + * + * @see pthread_sigqueue() + */ +#ifndef _di_f_thread_signal_queue_ + extern f_return_status f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value); +#endif // _di_f_thread_signal_queue_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_thread/data/build/settings b/level_0/f_thread/data/build/settings index 6952eb7..204bc1a 100644 --- a/level_0/f_thread/data/build/settings +++ b/level_0/f_thread/data/build/settings @@ -18,7 +18,7 @@ modes_default individual build_compiler gcc build_indexer ar build_language c -build_libraries -lc +build_libraries -pthread -lc build_libraries-individual -lf_memory build_sources_library thread.c private-thread.c build_sources_program @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no @@ -48,7 +48,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -pthread +flags_all -z now -g -fdiagnostics-color=always flags_shared flags_static flags_library -fPIC diff --git a/level_0/f_type/data/build/settings b/level_0/f_type/data/build/settings index ec06bd3..84dc3e5 100644 --- a/level_0/f_type/data/build/settings +++ b/level_0/f_type/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_0/f_utf/data/build/settings b/level_0/f_utf/data/build/settings index adc954b..3e9be8c 100644 --- a/level_0/f_utf/data/build/settings +++ b/level_0/f_utf/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_0 path_headers_preserve no diff --git a/level_1/fl_color/data/build/settings b/level_1/fl_color/data/build/settings index 9cb8805..f5048dd 100644 --- a/level_1/fl_color/data/build/settings +++ b/level_1/fl_color/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_console/data/build/settings b/level_1/fl_console/data/build/settings index b865b86..a6ad93e 100644 --- a/level_1/fl_console/data/build/settings +++ b/level_1/fl_console/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_control_group/data/build/settings b/level_1/fl_control_group/data/build/settings index 9773b79..5f7cde4 100644 --- a/level_1/fl_control_group/data/build/settings +++ b/level_1/fl_control_group/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_conversion/data/build/settings b/level_1/fl_conversion/data/build/settings index 8cdfc1b..f5bb19b 100644 --- a/level_1/fl_conversion/data/build/settings +++ b/level_1/fl_conversion/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_directory/data/build/settings b/level_1/fl_directory/data/build/settings index 550e45d..1d4b2fe 100644 --- a/level_1/fl_directory/data/build/settings +++ b/level_1/fl_directory/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_environment/data/build/settings b/level_1/fl_environment/data/build/settings index 8269804..de57391 100644 --- a/level_1/fl_environment/data/build/settings +++ b/level_1/fl_environment/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_execute/c/execute-common.h b/level_1/fl_execute/c/execute-common.h index a3f919f..c876d11 100644 --- a/level_1/fl_execute/c/execute-common.h +++ b/level_1/fl_execute/c/execute-common.h @@ -20,8 +20,11 @@ extern "C" { * A structure for containing additional parameters for the execute functions that call the execv() family of functions. * * bitwise options: - * fl_execute_parameter_option_exit: used to desginate to exit after calling child otherwise child process will return. - * fl_execute_parameter_option_path: used to designate that this is a path to a program (such as '/bin/bash'). + * fl_execute_parameter_option_exit: used to desginate to exit after calling child otherwise child process will return. + * fl_execute_parameter_option_path: used to designate that this is a path to a program (such as '/bin/bash'). + * fl_execute_parameter_option_threadsafe: used to designate that threadsafe functions are to be used (such as: f_thread_signal_mask instead of f_signal_mask). + * + * If thread support is disabled in the library, then fl_execute_parameter_option_threadsafe will fallback to non-threadsafe. * * option: accepts the bitwise options * environment: the environment variable name and value pairs, set to 0 to not use. @@ -29,8 +32,9 @@ extern "C" { * data: the data to pipe to the child process, set to 0 to not use. */ #ifndef _di_fl_execute_parameter_t_ - #define fl_execute_parameter_option_exit 0x1 - #define fl_execute_parameter_option_path 0x2 + #define fl_execute_parameter_option_exit 0x1 + #define fl_execute_parameter_option_path 0x2 + #define fl_execute_parameter_option_threadsafe 0x4 typedef struct { uint8_t option; diff --git a/level_1/fl_execute/data/build/settings b/level_1/fl_execute/data/build/settings index 13f1dbd..3e48aed 100644 --- a/level_1/fl_execute/data/build/settings +++ b/level_1/fl_execute/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no @@ -44,7 +44,7 @@ search_exclusive yes search_shared yes search_static yes -#defines_all -D_en_libcap_ +#defines_all -D_di_libcap_ defines_all defines_static defines_shared diff --git a/level_1/fl_fss/data/build/settings b/level_1/fl_fss/data/build/settings index 92460c6..c3c91bc 100644 --- a/level_1/fl_fss/data/build/settings +++ b/level_1/fl_fss/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_iki/data/build/settings b/level_1/fl_iki/data/build/settings index 910b5b9..9bf500b 100644 --- a/level_1/fl_iki/data/build/settings +++ b/level_1/fl_iki/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_print/data/build/settings b/level_1/fl_print/data/build/settings index f6d744d..cdf5f44 100644 --- a/level_1/fl_print/data/build/settings +++ b/level_1/fl_print/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_status/data/build/settings b/level_1/fl_status/data/build/settings index 63a03b1..4ce15c4 100644 --- a/level_1/fl_status/data/build/settings +++ b/level_1/fl_status/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_string/data/build/settings b/level_1/fl_string/data/build/settings index 5b83d3f..6e00230 100644 --- a/level_1/fl_string/data/build/settings +++ b/level_1/fl_string/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_type/data/build/settings b/level_1/fl_type/data/build/settings index 2dd48de..dd0c87d 100644 --- a/level_1/fl_type/data/build/settings +++ b/level_1/fl_type/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_utf/data/build/settings b/level_1/fl_utf/data/build/settings index e66d76b..be9c9c6 100644 --- a/level_1/fl_utf/data/build/settings +++ b/level_1/fl_utf/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_1/fl_utf_file/data/build/settings b/level_1/fl_utf_file/data/build/settings index da619b1..cc62e2a 100644 --- a/level_1/fl_utf_file/data/build/settings +++ b/level_1/fl_utf_file/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_1 path_headers_preserve no diff --git a/level_2/fll_control_group/data/build/settings b/level_2/fll_control_group/data/build/settings index 68d9488..0a6be9f 100644 --- a/level_2/fll_control_group/data/build/settings +++ b/level_2/fll_control_group/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_environment/data/build/settings b/level_2/fll_environment/data/build/settings index 16a6970..5d31bdb 100644 --- a/level_2/fll_environment/data/build/settings +++ b/level_2/fll_environment/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_error/data/build/settings b/level_2/fll_error/data/build/settings index 5de5e80..eedc8c7 100644 --- a/level_2/fll_error/data/build/settings +++ b/level_2/fll_error/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_execute/c/execute.h b/level_2/fll_execute/c/execute.h index fc2a082..d6ae81f 100644 --- a/level_2/fll_execute/c/execute.h +++ b/level_2/fll_execute/c/execute.h @@ -40,6 +40,10 @@ #include #include +#ifndef _di_pthread_support_ + #include +#endif // _di_pthread_support_ + // fll-1 includes #include #include @@ -443,7 +447,8 @@ extern "C" { * Errors (with error bit) from: f_environment_get(). * Errors (with error bit) from: f_file_exists(). * Errors (with error bit) from: f_macro_string_dynamics_t_delete(). - * Errors (with error bit) from: f_signal_set_handle(). + * Errors (with error bit) from: f_signal_mask(). + * Errors (with error bit) from: f_thread_signal_mask(). * Errors (with error bit) from: fl_environment_path_explode_dynamic(). * Errors (with error bit) from: fl_string_append(). * Errors (with error bit) from: fl_string_dynamic_delete(). @@ -470,7 +475,8 @@ extern "C" { * @see f_capability_process_set() * @see f_environment_get() * @see f_file_exists() - * @see f_signal_set_handle() + * @see f_signal_mask() + * @see f_thread_signal_mask() * @see fl_control_group_apply() * @see fl_environment_path_explode_dynamic() * @see fl_string_append() diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c index 3f5b0d2..9f88548 100644 --- a/level_2/fll_execute/c/private-execute.c +++ b/level_2/fll_execute/c/private-execute.c @@ -320,8 +320,23 @@ extern "C" { } if (parameter && parameter->signals) { - f_signal_set_handle(SIG_BLOCK, ¶meter->signals->block); - f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not); + #ifdef _di_pthread_support_ + + f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + + #else // _di_pthread_support_ + + if (parameter->option & fl_execute_parameter_option_threadsafe) { + f_thread_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_thread_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + } + else { + f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + } + + #endif // _di_pthread_support_ } if (parameter && parameter->environment) { @@ -465,8 +480,23 @@ extern "C" { } if (parameter && parameter->signals) { - f_signal_set_handle(SIG_BLOCK, ¶meter->signals->block); - f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not); + #ifdef _di_pthread_support_ + + f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + + #else // _di_pthread_support_ + + if (parameter->option & fl_execute_parameter_option_threadsafe) { + f_thread_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_thread_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + } + else { + f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); + f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); + } + + #endif // _di_pthread_support_ } if (parameter && parameter->environment) { diff --git a/level_2/fll_execute/c/private-execute.h b/level_2/fll_execute/c/private-execute.h index e946412..3fc9b21 100644 --- a/level_2/fll_execute/c/private-execute.h +++ b/level_2/fll_execute/c/private-execute.h @@ -11,21 +11,6 @@ #ifndef _PRIVATE_FLL_execute_h #define _PRIVATE_FLL_execute_h -// libc includes -#include -#include -#include -#include -#include - -// fll-0 includes -#include -#include -#include -#include - -// fll-1 includes - #ifdef __cplusplus extern "C" { #endif @@ -238,7 +223,8 @@ extern "C" { * @see waitpid() * * @see f_environment_set_dynamic() - * @see f_signal_set_handle() + * @see f_signal_mask() + * @see f_thread_signal_mask() * @see fl_control_group_apply() * @see fll_execute_program() */ @@ -302,7 +288,8 @@ extern "C" { * @see waitpid() * * @see f_environment_set_dynamic() - * @see f_signal_set_handle() + * @see f_signal_mask() + * @see f_thread_signal_mask() * @see fll_execute_program() */ #if !defined(_di_fll_execute_program_) diff --git a/level_2/fll_execute/data/build/defines b/level_2/fll_execute/data/build/defines index 903c38c..8a7625a 100644 --- a/level_2/fll_execute/data/build/defines +++ b/level_2/fll_execute/data/build/defines @@ -1,2 +1,3 @@ # fss-0000 _di_libcap_ Disable libcap support, allow for compiling and linking without libcap (-lcap). +_di_pthread_support_ Disable support for compiling and depending on pthreads (and projects like f_thread). diff --git a/level_2/fll_execute/data/build/dependencies b/level_2/fll_execute/data/build/dependencies index 0b7c46f..4e06e33 100644 --- a/level_2/fll_execute/data/build/dependencies +++ b/level_2/fll_execute/data/build/dependencies @@ -11,6 +11,7 @@ f_execute f_file f_path f_signal +f_thread fl_control_group fl_environment fl_execute diff --git a/level_2/fll_execute/data/build/settings b/level_2/fll_execute/data/build/settings index ff0b80f..c95b57d 100644 --- a/level_2/fll_execute/data/build/settings +++ b/level_2/fll_execute/data/build/settings @@ -12,14 +12,15 @@ environment process_pre process_post -modes individual +modes individual individual_threadless modes_default individual build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfl_control_group -lfl_environment -lfl_string -lf_account -lf_capability -lf_environment -lf_file -lf_memory -lf_path -lf_signal -lf_utf +build_libraries-individual -lfl_control_group -lfl_environment -lfl_string -lf_account -lf_capability -lf_environment -lf_file -lf_memory -lf_path -lf_signal -lf_thread -lf_utf +build_libraries-individual_threadless -lfl_control_group -lfl_environment -lfl_string -lf_account -lf_capability -lf_environment -lf_file -lf_memory -lf_path -lf_signal -lf_utf build_sources_library execute.c private-execute.c build_sources_program build_sources_headers execute.h @@ -27,7 +28,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no @@ -44,11 +45,14 @@ search_exclusive yes search_shared yes search_static yes +#defines_all -D_di_libcap_ defines_all +defines_all-individual_threadless -D_di_pthread_support_ defines_static defines_shared flags_all -z now -g -fdiagnostics-color=always +flags_all-individual -pthread flags_shared flags_static flags_library -fPIC diff --git a/level_2/fll_file/data/build/settings b/level_2/fll_file/data/build/settings index 2b0a816..ea40752 100644 --- a/level_2/fll_file/data/build/settings +++ b/level_2/fll_file/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index efda731..9bf7362 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -183,7 +183,7 @@ extern "C" { if (F_status_is_error(status)) return status; } - destination->string[destination->used++] = f_string_eol[0]; + destination->string[destination->used++] = f_string_eol_s[0]; } } diff --git a/level_2/fll_fss/data/build/settings b/level_2/fll_fss/data/build/settings index 366bb4f..56c2ffa 100644 --- a/level_2/fll_fss/data/build/settings +++ b/level_2/fll_fss/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_iki/data/build/settings b/level_2/fll_iki/data/build/settings index 1996555..e80491d 100644 --- a/level_2/fll_iki/data/build/settings +++ b/level_2/fll_iki/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_path/data/build/settings b/level_2/fll_path/data/build/settings index 7e8e42d..ed9362c 100644 --- a/level_2/fll_path/data/build/settings +++ b/level_2/fll_path/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_program/data/build/settings b/level_2/fll_program/data/build/settings index 86e3496..cdbb4e5 100644 --- a/level_2/fll_program/data/build/settings +++ b/level_2/fll_program/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_2/fll_status/data/build/settings b/level_2/fll_status/data/build/settings index adfa05e..f84b695 100644 --- a/level_2/fll_status/data/build/settings +++ b/level_2/fll_status/data/build/settings @@ -27,7 +27,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_2 path_headers_preserve no diff --git a/level_3/byte_dump/data/build/settings b/level_3/byte_dump/data/build/settings index 7b40f23..51d5165 100644 --- a/level_3/byte_dump/data/build/settings +++ b/level_3/byte_dump/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/control/data/build/settings b/level_3/control/data/build/settings index e836a9a..afb1852 100644 --- a/level_3/control/data/build/settings +++ b/level_3/control/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/controller/c/main.c b/level_3/controller/c/main.c index ec2c9d5..0d9ce1a 100644 --- a/level_3/controller/c/main.c +++ b/level_3/controller/c/main.c @@ -17,13 +17,13 @@ int main(const unsigned long argc, const f_string_t *argv) { f_signal_set_add(F_signal_interrupt, &data.signal.set); f_signal_set_add(F_signal_quit, &data.signal.set); f_signal_set_add(F_signal_termination, &data.signal.set); - f_signal_set_handle(SIG_BLOCK, &data.signal.set); + f_signal_mask(SIG_BLOCK, &data.signal.set, 0); status = f_signal_open(&data.signal); // if there is an error opening a signal descriptor, then do not handle signals. if (F_status_is_error(status)) { - f_signal_set_handle(SIG_UNBLOCK, &data.signal.set); + f_signal_mask(SIG_UNBLOCK, &data.signal.set, 0); f_signal_close(&data.signal); } diff --git a/level_3/controller/data/build/settings b/level_3/controller/data/build/settings index ab184c6..230d232 100644 --- a/level_3/controller/data/build/settings +++ b/level_3/controller/data/build/settings @@ -18,7 +18,7 @@ modes_default monolithic build_compiler gcc build_indexer ar build_language c -build_libraries -lc -lcap +build_libraries -pthread -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_thread -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll @@ -29,7 +29,7 @@ build_sources_script build_sources_setting entries rules build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no @@ -46,7 +46,7 @@ search_exclusive yes search_shared yes search_static yes -#defines_all -D_di_libcap_ +#defines_all -D_di_libcap_ -D_di_thread_support_ defines_all defines_static defines_shared diff --git a/level_3/fake/c/main.c b/level_3/fake/c/main.c index 847f076..3436e4c 100644 --- a/level_3/fake/c/main.c +++ b/level_3/fake/c/main.c @@ -25,13 +25,13 @@ int main(const unsigned long argc, const f_string_t *argv) { f_signal_set_add(F_signal_interrupt, &data.signal.set); f_signal_set_add(F_signal_quit, &data.signal.set); f_signal_set_add(F_signal_termination, &data.signal.set); - f_signal_set_handle(SIG_BLOCK, &data.signal.set); + f_signal_mask(SIG_BLOCK, &data.signal.set, 0); status = f_signal_open(&data.signal); // if there is an error opening a signal descriptor, then do not handle signals. if (F_status_is_error(status)) { - f_signal_set_handle(SIG_UNBLOCK, &data.signal.set); + f_signal_mask(SIG_UNBLOCK, &data.signal.set, 0); f_signal_close(&data.signal); } diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index 88fa66d..314af23 100644 --- a/level_3/fake/data/build/settings +++ b/level_3/fake/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no @@ -46,12 +46,12 @@ search_exclusive yes search_shared yes search_static yes -#defines_all -D_di_libcap_ +#defines_all -D_di_libcap_ -D_di_thread_support_ 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/firewall/data/build/settings b/level_3/firewall/data/build/settings index efa351b..ba3ae4e 100644 --- a/level_3/firewall/data/build/settings +++ b/level_3/firewall/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting default-blacklist default-whitelist example-device-firewall firewall-first firewall-last firewall-other build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no @@ -46,11 +46,12 @@ search_exclusive yes search_shared yes search_static yes +#defines_all -D_di_libcap_ -D_di_thread_support_ 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_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings index 8bb772d..4b81e30 100644 --- a/level_3/fss_basic_list_read/data/build/settings +++ b/level_3/fss_basic_list_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_basic_list_write/data/build/settings b/level_3/fss_basic_list_write/data/build/settings index 8b99e8b..7a9917c 100644 --- a/level_3/fss_basic_list_write/data/build/settings +++ b/level_3/fss_basic_list_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings index 4dfd977..9432734 100644 --- a/level_3/fss_basic_read/data/build/settings +++ b/level_3/fss_basic_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_basic_write/data/build/settings b/level_3/fss_basic_write/data/build/settings index d6372e0..970578c 100644 --- a/level_3/fss_basic_write/data/build/settings +++ b/level_3/fss_basic_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_embedded_list_read/data/build/settings b/level_3/fss_embedded_list_read/data/build/settings index ecba103..5d2cd7a 100644 --- a/level_3/fss_embedded_list_read/data/build/settings +++ b/level_3/fss_embedded_list_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_embedded_list_write/data/build/settings b/level_3/fss_embedded_list_write/data/build/settings index c67cef0..6f7f22b 100644 --- a/level_3/fss_embedded_list_write/data/build/settings +++ b/level_3/fss_embedded_list_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_extended_list_read/data/build/settings b/level_3/fss_extended_list_read/data/build/settings index 13d42bf..7b38df5 100644 --- a/level_3/fss_extended_list_read/data/build/settings +++ b/level_3/fss_extended_list_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_extended_list_write/data/build/settings b/level_3/fss_extended_list_write/data/build/settings index 3abb786..736ae0f 100644 --- a/level_3/fss_extended_list_write/data/build/settings +++ b/level_3/fss_extended_list_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings index 1b66b5d..d412af1 100644 --- a/level_3/fss_extended_read/data/build/settings +++ b/level_3/fss_extended_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_extended_write/data/build/settings b/level_3/fss_extended_write/data/build/settings index 6e4edde..3ad3aa1 100644 --- a/level_3/fss_extended_write/data/build/settings +++ b/level_3/fss_extended_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/fss_status_code/data/build/settings b/level_3/fss_status_code/data/build/settings index 1b1f6af..e0ce636 100644 --- a/level_3/fss_status_code/data/build/settings +++ b/level_3/fss_status_code/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/iki_read/data/build/settings b/level_3/iki_read/data/build/settings index 5719414..e5a1ae4 100644 --- a/level_3/iki_read/data/build/settings +++ b/level_3/iki_read/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/iki_write/data/build/settings b/level_3/iki_write/data/build/settings index 3708887..0d8deff 100644 --- a/level_3/iki_write/data/build/settings +++ b/level_3/iki_write/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/init/c/main.c b/level_3/init/c/main.c index d10b1a0..45878cf 100644 --- a/level_3/init/c/main.c +++ b/level_3/init/c/main.c @@ -10,11 +10,11 @@ int main(const unsigned long argc, const f_string_t *argv) { f_signal_set_add(F_signal_interrupt, &data.signal.set); f_signal_set_add(F_signal_quit, &data.signal.set); f_signal_set_add(F_signal_termination, &data.signal.set); - f_signal_set_handle(SIG_BLOCK, &data.signal.set); + f_signal_mask(SIG_BLOCK, &data.signal.set, 0); // if there is an error opening a signal descriptor, then do not handle signals. if (F_status_is_error(f_signal_open(&data.signal))) { - f_signal_set_handle(SIG_UNBLOCK, &data.signal.set); + f_signal_mask(SIG_UNBLOCK, &data.signal.set, 0); f_signal_close(&data.signal); } diff --git a/level_3/init/data/build/settings b/level_3/init/data/build/settings index 25604e9..d795056 100644 --- a/level_3/init/data/build/settings +++ b/level_3/init/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no diff --git a/level_3/status_code/data/build/settings b/level_3/status_code/data/build/settings index b6333bc..539c2dd 100644 --- a/level_3/status_code/data/build/settings +++ b/level_3/status_code/data/build/settings @@ -29,7 +29,7 @@ build_sources_script build_sources_setting build_script yes build_shared yes -build_static yes +build_static no path_headers level_3 path_headers_preserve no