]> Kevux Git Server - fll/commitdiff
Update: thread support.
authorKevin Day <thekevinday@gmail.com>
Sun, 3 Jan 2021 03:11:02 +0000 (21:11 -0600)
committerKevin Day <thekevinday@gmail.com>
Sun, 3 Jan 2021 03:11:02 +0000 (21:11 -0600)
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.

93 files changed:
build/level_0/settings
build/level_1/settings
build/level_2/settings
build/monolithic/settings
build/scripts/bootstrap-example.sh
documents/threads.txt
level_0/f_account/data/build/settings
level_0/f_capability/data/build/settings
level_0/f_color/data/build/settings
level_0/f_console/data/build/settings
level_0/f_control_group/data/build/settings
level_0/f_conversion/data/build/settings
level_0/f_directory/data/build/settings
level_0/f_environment/data/build/settings
level_0/f_execute/data/build/settings
level_0/f_file/data/build/settings
level_0/f_fss/data/build/settings
level_0/f_iki/data/build/settings
level_0/f_memory/data/build/settings
level_0/f_path/data/build/settings
level_0/f_pipe/data/build/settings
level_0/f_print/data/build/settings
level_0/f_serialize/data/build/settings
level_0/f_signal/c/signal.c
level_0/f_signal/c/signal.h
level_0/f_signal/data/build/defines
level_0/f_signal/data/build/settings
level_0/f_socket/data/build/settings
level_0/f_status/data/build/settings
level_0/f_string/data/build/settings
level_0/f_thread/c/private-thread.c
level_0/f_thread/c/private-thread.h
level_0/f_thread/c/thread-common.h
level_0/f_thread/c/thread.c
level_0/f_thread/c/thread.h
level_0/f_thread/data/build/settings
level_0/f_type/data/build/settings
level_0/f_utf/data/build/settings
level_1/fl_color/data/build/settings
level_1/fl_console/data/build/settings
level_1/fl_control_group/data/build/settings
level_1/fl_conversion/data/build/settings
level_1/fl_directory/data/build/settings
level_1/fl_environment/data/build/settings
level_1/fl_execute/c/execute-common.h
level_1/fl_execute/data/build/settings
level_1/fl_fss/data/build/settings
level_1/fl_iki/data/build/settings
level_1/fl_print/data/build/settings
level_1/fl_status/data/build/settings
level_1/fl_string/data/build/settings
level_1/fl_type/data/build/settings
level_1/fl_utf/data/build/settings
level_1/fl_utf_file/data/build/settings
level_2/fll_control_group/data/build/settings
level_2/fll_environment/data/build/settings
level_2/fll_error/data/build/settings
level_2/fll_execute/c/execute.h
level_2/fll_execute/c/private-execute.c
level_2/fll_execute/c/private-execute.h
level_2/fll_execute/data/build/defines
level_2/fll_execute/data/build/dependencies
level_2/fll_execute/data/build/settings
level_2/fll_file/data/build/settings
level_2/fll_fss/c/fss_basic.c
level_2/fll_fss/data/build/settings
level_2/fll_iki/data/build/settings
level_2/fll_path/data/build/settings
level_2/fll_program/data/build/settings
level_2/fll_status/data/build/settings
level_3/byte_dump/data/build/settings
level_3/control/data/build/settings
level_3/controller/c/main.c
level_3/controller/data/build/settings
level_3/fake/c/main.c
level_3/fake/data/build/settings
level_3/firewall/data/build/settings
level_3/fss_basic_list_read/data/build/settings
level_3/fss_basic_list_write/data/build/settings
level_3/fss_basic_read/data/build/settings
level_3/fss_basic_write/data/build/settings
level_3/fss_embedded_list_read/data/build/settings
level_3/fss_embedded_list_write/data/build/settings
level_3/fss_extended_list_read/data/build/settings
level_3/fss_extended_list_write/data/build/settings
level_3/fss_extended_read/data/build/settings
level_3/fss_extended_write/data/build/settings
level_3/fss_status_code/data/build/settings
level_3/iki_read/data/build/settings
level_3/iki_write/data/build/settings
level_3/init/c/main.c
level_3/init/data/build/settings
level_3/status_code/data/build/settings

index a679e21c694cf3bfb1f64369ddbe2488b5f825ea..68b9c743739302b346faa7053fd20121d4507c20 100644 (file)
@@ -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
index d251db662fcd70fa9c22ab7542c56f3f4752730e..be2ce79cf185f708bea25780a8c9114c4ccdc3ba 100644 (file)
@@ -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
index 1c0b0334383b34946132fd936c1762a4a6f6527a..59a660c33032dfce076468526cb5713e56bb5c2e 100644 (file)
@@ -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
index e1ebd75fa4d4280fd4f9be6ac7e8fb6f194e80df..5be10cfd412cbe940a6ee1dea48339260ae84474 100644 (file)
@@ -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
index 7f34fc5162a2c0ed6c861e9c3877d328b2917645..275b122699ff39c209d491aa0b7a8eb531712249 100644 (file)
@@ -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.
index aaebabf36e129e8913c857fb0020c9045ec37479..edbae5bbb8f6a97bd4977dc2f54596ef30f6a328 100644 (file)
@@ -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.
index 53215b2557d7f93fd922091108bef994640963d3..4ed2e4c0f0154ff9c4013e08c76ebf4b1365881d 100644 (file)
@@ -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
index 1db7437937ca01cc019d2377accb00af70bf4df4..e538f674580eb10b02eeabd2f3d611068759c74c 100644 (file)
@@ -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
index 8bfe48587d3379f75aa52349d6dd785511a40e4c..80aaaebfb457c9e6526fa9cdf6c4e00f101112eb 100644 (file)
@@ -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
index ca04354c7806bb0d1c1a8a6a9776f8037e4c2e61..c60e43ede712fff00dadf73813bc422ae07caffe 100644 (file)
@@ -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
index 8828ab2a603a79f75045dcef294d22542f344de5..6523f94347ed80e653951d7512a2ad228fd9db43 100644 (file)
@@ -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
index 4c90dc1f32378949962b221f170ff82b479936ad..fff2386a09130b9821699a701bec24441e2020e9 100644 (file)
@@ -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
index 54a74484a58de5c8556b9de9847342b6b5dc1a8c..9c51affb6c9363ebdf1ef2538e1c09b6b06ffe19 100644 (file)
@@ -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
index 9106d84ff5a89b04d7aae3535879e253be05f8ee..d75807e4026fd2242fa1a1d93260423b2ef1c823 100644 (file)
@@ -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
index 500c1b19e290f3f5d13420c6f4f4638412be520a..0df1771b4a6184c68ef4ac42a1ab5dea9f77f259 100644 (file)
@@ -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
index 0560fcefa0f450f9849e94d409c087d6dd613e45..153e5242497f2ddaf82b3775d01bf68a0ff1d6e5 100644 (file)
@@ -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
index 65920d46e3809a12c1854412277e785d68d199f3..b619c5f4147f31f8c6028b061595df1379f59bdd 100644 (file)
@@ -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
index c0415c14b1521c91d01842ab264a95e86d57ea67..5dde159a87323f2b8581d2f1e106d666d08b27de 100644 (file)
@@ -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
index 11e13303f2afb0997718d2517935d52c2e74bc3a..ff3d8670d9b22996e06031841035707127c84439 100644 (file)
@@ -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
index 46cd4549f04ffc3b22facb82912ee7f122643682..bc383234855070d87366367a2e1f67d75c87e765 100644 (file)
@@ -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
index 112d8f26e478edaf16ee3d8874d3a0df114042e2..768aee50d34493473f7be9098a63df874f6f458c 100644 (file)
@@ -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
index 3b22c6778d5aafffff53db074310e63986fee078..a5ca534e4808860c538d1162370d4c6f3b52ad0e 100644 (file)
@@ -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
index 12965641c69ebe5befc2029428e8c87aa8e32705..6cfedf40a154438ee6d1b13c07da89c080309f9c 100644 (file)
@@ -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
index 4aa77a6c41ff2a36abb06a22650c7a2935573900..c3fea930ef96afdf4d12389d38c0ae8749bdf32a 100644 (file)
@@ -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) {
index 6e358606c0c2783988b7dfdceac363394a641d87..d3e8e611ea00c1f48214169a5947e97358e86099 100644 (file)
@@ -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.
index 3f4bf6120e8dc6977a210aef84226951d0e372c7..4f130804d83cb5bf412c3e349a4ac790b2b825ca 100644 (file)
@@ -1,3 +1 @@
 # fss-0000
-
-_threadsafe_f_signal_handle Enable use of pthread_sigmask() instead of sigprocmask() in appropriate f_signal_*() functions.
index 8f7ccba1fac167b70af31242e98465a200a60eff..90457d7fbbf6ebeb976ec5b39f958f57393c9f46 100644 (file)
@@ -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
index 5a4efdb8ca8c87f4871252698051b8c1578ca2b2..4883008f4f846e19b4d73068deff9a86189ee558 100644 (file)
@@ -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
index db50080cc82e7fa67b3b8b93c56499ab51fb0ef7..039c5a969b1a1e72daa0f6969d080c9d8d1e8e62 100644 (file)
@@ -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
index 3b99fa580adfee8623e37aa1e1d66bcbb22e76b3..1213c19f4df90fb6b1ee3757f7455c2a44fff173 100644 (file)
@@ -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
index d3a6273c147f831744872fca2b4ce0e6334e5634..1b8152df4e2cf707d004cee1e588930efacad0a7 100644 (file)
 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
index 41635169f60e110af88614d82ec231bb8458391e..e5557374021428ea3fe2d0e0faab25cbfd960d19 100644 (file)
@@ -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
index 3ac5b2fc9e7e98c1428272bc42f070062fbf9f9e..aa0e126f49a1796dc24e1a750a6e6cb706bc4fb8 100644 (file)
@@ -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) { \
index 4a1e20ab47c426eac25570ef9aca331fe87483cb..5488bae3491d2b102a2fa97ae2db12a15df627b5 100644 (file)
 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, &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_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
index 93271c1478fe0bbd892123e19cd9ab2c01c823a0..717874899417783d8b8bd6a67c7123855a3a47e9 100644 (file)
  * 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 <signal.h>
 #include <sys/types.h>
+#include <time.h>
 #include <pthread.h>
 #include <unistd.h>
 
-// fll-0 includes
-#include <level_0/type.h>
-#include <level_0/status.h>
-#include <level_0/memory.h>
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/status.h>
+#include <level_0/memory.h>
+
+// fll-0 thread includes
+#include <level_0/thread-common.h>
+
+#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 <level_0/thread-common.h>
+/**
+ * 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
index 6952eb79950203e49a495b280c75be18d0374ffd..204bc1a9a7a9c1b8254955dfd6a8b94d6d9f7dbc 100644 (file)
@@ -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
index ec06bd34709d57fd8e6adc503dcb4611ccec139e..84dc3e595438e905955bc66d6629ec0e97459b2b 100644 (file)
@@ -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
index adc954b97a3adab1b2d79794032815c74604608a..3e9be8cf314db745dedf59c54c0ff971bd9f7a3d 100644 (file)
@@ -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
index 9cb880518246cd36b987e92a2733345df192e76d..f5048dd8fbd15963b2d19dadc4a07c5015ff86b9 100644 (file)
@@ -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
index b865b86eddf8cbb70156c0faacea9e4b7ab0ebf0..a6ad93e28f908b88214224208573ae2e6c024089 100644 (file)
@@ -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
index 9773b794c073f1726497b09c04a4e2ef4d3f46c4..5f7cde4b5030435b6ecd04b92fd1c4650ea2f733 100644 (file)
@@ -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
index 8cdfc1b015100d3cd9c67f8fca8f63adbcc158e4..f5bb19b4b73523859c3377142a4bf4dc0716de34 100644 (file)
@@ -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
index 550e45db53b874dcea3870727fb078f6c162738b..1d4b2fe2affc537e3b2bf3bf9ebd7743e046f34c 100644 (file)
@@ -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
index 8269804dd5ceea6cb8ee0e547288561487c13ab0..de57391405c5334254539284b41cf82af96654cb 100644 (file)
@@ -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
index a3f919f0e25c71f567c145d8e31a90b7543c0c56..c876d1172927bc7e8578915ca5da3c17dda11b01 100644 (file)
@@ -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;
index 13f1dbd99ae4ed2787134dcd4f220096de022c13..3e48aed2834a40e6d774a5bacfbe4f9e44959021 100644 (file)
@@ -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
index 92460c6ee806cccc0bfff7141c31279f2ba5e475..c3c91bc4e71718721dbcfbfd81d01cebf4d28392 100644 (file)
@@ -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
index 910b5b99909746dfcd5b52948fe414540eecf2f1..9bf500b3756cc6c02ea2c27e5dd31d1908a8b4dc 100644 (file)
@@ -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
index f6d744d41959572332f9b810be8e398fe68795c0..cdf5f441fd6f5d148ee2b4913cdfec504de631ff 100644 (file)
@@ -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
index 63a03b1c2a9d1cdcea8847c0c42f96cc5fc08f34..4ce15c4cdc369940f5da89a8ebc7839c3a1ff52c 100644 (file)
@@ -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
index 5b83d3fb2bf83dc0cdd26d40c98f6e522053304c..6e002303e3060a74276fabcfb67e1862a1cc8296 100644 (file)
@@ -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
index 2dd48de05b963e91fca07838ac201c12b31bc950..dd0c87dc28d15857c60b8c798b41baadfaa67bc3 100644 (file)
@@ -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
index e66d76bb253549182477a0676cb02b478811a1e8..be9c9c674112748f893c7ea37a4086affcc98501 100644 (file)
@@ -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
index da619b1feaa87d4cca3239a12fcec4cb6b268d47..cc62e2aea8fb222a9611fc7be9f1e99494293ba7 100644 (file)
@@ -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
index 68d94881e2836c79c6bc6aaf5c2e7ca756d8b6fc..0a6be9f8a0468ac741d686f7382f649d351e7826 100644 (file)
@@ -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
index 16a6970504f6ce01e9b3de588ab09abf9fbed54a..5d31bdb7f596e43a89547764732ce8d930fa37c7 100644 (file)
@@ -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
index 5de5e8068c825f49a1f6e6bbe8202c6692db9012..eedc8c794d120a94d1d8030fa0594a1a359aec1d 100644 (file)
@@ -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
index fc2a08233be79eef33be9f321f42e91c09e42e61..d6ae81f0bd1aab7f19716e9d253d2219461f6d95 100644 (file)
 #include <level_0/path.h>
 #include <level_0/signal.h>
 
+#ifndef _di_pthread_support_
+  #include <level_0/thread.h>
+#endif // _di_pthread_support_
+
 // fll-1 includes
 #include <level_1/control_group.h>
 #include <level_1/environment.h>
@@ -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()
index 3f5b0d29b1743039a61a0d2c4c180dcabe1aca3b..9f885484eeda165cb235152df8a40c3850c662de 100644 (file)
@@ -320,8 +320,23 @@ extern "C" {
     }
 
     if (parameter && parameter->signals) {
-      f_signal_set_handle(SIG_BLOCK, &parameter->signals->block);
-      f_signal_set_handle(SIG_UNBLOCK, &parameter->signals->block_not);
+      #ifdef _di_pthread_support_
+
+        f_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+        f_signal_mask(SIG_UNBLOCK, &parameter->signals->block_not, 0);
+
+      #else // _di_pthread_support_
+
+        if (parameter->option & fl_execute_parameter_option_threadsafe) {
+          f_thread_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+          f_thread_signal_mask(SIG_UNBLOCK, &parameter->signals->block_not, 0);
+        }
+        else {
+          f_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+          f_signal_mask(SIG_UNBLOCK, &parameter->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, &parameter->signals->block);
-      f_signal_set_handle(SIG_UNBLOCK, &parameter->signals->block_not);
+      #ifdef _di_pthread_support_
+
+        f_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+        f_signal_mask(SIG_UNBLOCK, &parameter->signals->block_not, 0);
+
+      #else // _di_pthread_support_
+
+        if (parameter->option & fl_execute_parameter_option_threadsafe) {
+          f_thread_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+          f_thread_signal_mask(SIG_UNBLOCK, &parameter->signals->block_not, 0);
+        }
+        else {
+          f_signal_mask(SIG_BLOCK, &parameter->signals->block, 0);
+          f_signal_mask(SIG_UNBLOCK, &parameter->signals->block_not, 0);
+        }
+
+      #endif // _di_pthread_support_
     }
 
     if (parameter && parameter->environment) {
index e946412c6af524a153c7fe9956e2db61bd3d83fb..3fc9b2181d23b941013a2a01a32a545ae8836543 100644 (file)
 #ifndef _PRIVATE_FLL_execute_h
 #define _PRIVATE_FLL_execute_h
 
-// libc includes
-#include <memory.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-// fll-0 includes
-#include <level_0/status.h>
-#include <level_0/memory.h>
-#include <level_0/string.h>
-#include <level_0/type.h>
-
-// 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_)
index 903c38c833c065f69dcff069c87eb4b052c103ab..8a7625aaf6728926bd20b1eca180ab81bdda5039 100644 (file)
@@ -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).
index 0b7c46f2b7a3cb9c95ff717ecfd26a422b2e4160..4e06e339aa4b28f48150cbfd57c69252d51bbdee 100644 (file)
@@ -11,6 +11,7 @@ f_execute
 f_file
 f_path
 f_signal
+f_thread
 fl_control_group
 fl_environment
 fl_execute
index ff0b80f4ff8e2ef416b60829583685c29f8cf6ed..c95b57d67079b18774bc475ef4bdfa1e58679d09 100644 (file)
@@ -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
index 2b0a8166ffe86e24ed6b654a6b3c48f4bc3d9c5f..ea40752417197d25b858e584d0e8b1d69a276d3a 100644 (file)
@@ -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
index efda731fda45214575124472d72964dfebf8380c..9bf7362e7879f8cba21f9c1f5a0f3a03aba72b64 100644 (file)
@@ -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];
       }
     }
 
index 366bb4f1dfda148303b7206606e98466dec67d01..56c2ffa0a9e2ffea6791eda53eb9425ca587cd8f 100644 (file)
@@ -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
index 19965555d8f6ad3b4a5eecd20a41d8d3f978d60e..e80491d880390683783a3acd15ab1830dcd5de6e 100644 (file)
@@ -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
index 7e8e42d5c6478748b36f6ec06311e7d0493f2fa5..ed9362c65f47959805fa39a191bf893fa7a7268d 100644 (file)
@@ -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
index 86e3496cbb5ede0a13786fbb835ad3f181cfe5af..cdbb4e516d0a9248409b270fcaeecc65beb470a2 100644 (file)
@@ -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
index adfa05e3fd6101e0fe002edf0455652223209785..f84b6959bc2d29207860d139db962ae5ea37014f 100644 (file)
@@ -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
index 7b40f23dd60eb7282bc8130e03f7bf0da96358e1..51d5165378d262c55b8af0c21ffb861480b13678 100644 (file)
@@ -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
index e836a9a76db358ee87aa05d3410620ef5ed227e1..afb18525fff9b77f0da914b85c3f937ed7ab3643 100644 (file)
@@ -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
index ec2c9d569d17d519be217cac46cb1fb059de044e..0d9ce1add27e18f99166da7426c6124f1e4f5495 100644 (file)
@@ -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);
   }
 
index ab184c629bc6b07487ad4c680d73d59e2827514c..230d232ffa768f0965a749cefb15ae571bd514c0 100644 (file)
@@ -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
index 847f076a6b69823287f431a14a75277e9f47b264..3436e4c23b584612d9512dc977b232785d9e3297 100644 (file)
@@ -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);
   }
 
index 88fa66d4468180e905b7efd8dffdd77257430aa8..314af23f71dea34b4d7fa30400693e37d9597172 100644 (file)
@@ -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
index efa351b5c85b83b424064e5d263914ae8857aeb1..ba3ae4e00ab0ad9b7fc3fafbdf406683e70bdc9b 100644 (file)
@@ -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
index 8bb772de5c2cc71ad051bb5802540775accaba56..4b81e302fb7f5567b77df805521e3a8e13ecdaf2 100644 (file)
@@ -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
index 8b99e8bf66628ccfb6702a17587e6b1601956e4c..7a9917c7df7e6916b55ef60b2504c70f762b3997 100644 (file)
@@ -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
index 4dfd977279c85cd99f47f94ec9d6c0d24edcadeb..9432734252c02149ac6b528f6652715cb25bbbf3 100644 (file)
@@ -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
index d6372e01d92d5ae3f38388cfc5a70464f6606b84..970578c9f792b7a94033cc899eb28793b4c81b8a 100644 (file)
@@ -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
index ecba10342a9593e925dcf75632cc255e706ea127..5d2cd7a0956074589a8187c7a49dad1e44f18709 100644 (file)
@@ -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
index c67cef01067669707ca9cb8fbcfb6ccf03b39063..6f7f22bab273e6d99e263360571863da253eaf85 100644 (file)
@@ -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
index 13d42bf508a747fbfde5d6b63236142b97248f49..7b38df527a48dc48543aa44ff33d45b051d492b1 100644 (file)
@@ -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
index 3abb7860b731cd62039d1c7116f7a3a3ea85666b..736ae0fafa2ee2eb5d7350b2d02a587075f5dd10 100644 (file)
@@ -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
index 1b66b5dcd1c3606446af2e9d2e003ad990f0ecaf..d412af1a4f73f99ee46ee6491a2ce500daa8a412 100644 (file)
@@ -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
index 6e4edde413c3336c358692d8343dff5de8745f5d..3ad3aa14f13c9d003bfdc7820dc8e2d6a2c48ed1 100644 (file)
@@ -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
index 1b1f6af2b13c5db22a576c417055dcaf89227a55..e0ce636743335a9db960266322cc016edeccbdd1 100644 (file)
@@ -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
index 5719414a02be02eb3d2513f5386ae0d567e97cae..e5a1ae42d24e543e8b75dc23a3a14e38cab60259 100644 (file)
@@ -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
index 37088875101a7076cfd050d086c77c8f0d636a2c..0d8deff9cb02892454fe82d6285affdfa2cfddda 100644 (file)
@@ -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
index d10b1a00b6a182bf400aab594cb082100f5b2d6e..45878cfeaab6a5cb440c76a2712fee1b765226d9 100644 (file)
@@ -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);
   }
 
index 25604e903b852c2a8919b4c405fc78bd04899966..d79505695301fd78fb3560bb150cce479bc0bc9a 100644 (file)
@@ -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
index b6333bc79d21abd2e76c933a6e63e5b2ea1c35f5..539c2dd1c7275ecd0b80f3079517865d8bd996d3 100644 (file)
@@ -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