]> Kevux Git Server - fll/commitdiff
Update: remaining thread functions and add f_recover (and f_recover_not) status codes.
authorKevin Day <thekevinday@gmail.com>
Tue, 9 Feb 2021 03:57:05 +0000 (21:57 -0600)
committerKevin Day <thekevinday@gmail.com>
Tue, 9 Feb 2021 03:57:05 +0000 (21:57 -0600)
Implement the remaining POSIX thread functions that I am aware of.
I took a break in the middle of writing some of this so I expect there may be some mistakes resulting from such an interrupt.
I do not feel like focusing on this now and will address any problems as I discover them.

level_0/f_status/c/status.h
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_1/fl_status/c/status.c
level_1/fl_status/c/status.h
level_2/fll_status/c/status.c

index f54aa8c05654061545ce6682b8b1c28a3e023022..279a3c62c0cf0ef3c465530bb4865b82408fafcf 100644 (file)
@@ -249,6 +249,8 @@ extern "C" {
       F_read_only,
       F_ready,
       F_ready_not,
+      F_recover,
+      F_recover_not,
       F_recurse,
       F_recurse_not,
       F_relative,
index e80866238e32daa91b3ce0da514b89f52d64c6ee..7eb0ec932b399a2a405f39ae376d3f3a130a061a 100644 (file)
@@ -66,6 +66,128 @@ extern "C" {
   }
 #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_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_) || !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_) || !defined(_di_f_thread_barriers_resize_)
+  f_status_t private_f_thread_barrier_delete(f_thread_barrier_t *barrier) {
+
+    if (pthread_barrier_destroy(barrier)) {
+      return F_status_set_error(F_failure);
+    }
+
+    barrier = 0;
+
+    return F_none;
+  }
+#endif // !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_) || !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_) || !defined(_di_f_thread_barriers_resize_)
+
+#if !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_)
+  f_status_t private_f_thread_barriers_adjust(const f_array_length_t length, f_thread_barriers_t *barriers) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < barriers->size; ++i) {
+
+      status = private_f_thread_barrier_delete(&barriers->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(barriers->size, length, sizeof(f_thread_barrier_t), (void **) & barriers->array);
+
+    if (F_status_is_error_not(status)) {
+      barriers->size = length;
+
+      if (barriers->used > barriers->size) {
+        barriers->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_)
+
+#if !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_)
+  f_status_t private_f_thread_barriers_resize(const f_array_length_t length, f_thread_barriers_t *barriers) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < barriers->size; ++i) {
+
+      status = private_f_thread_barrier_delete(&barriers->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(barriers->size, length, sizeof(f_thread_barrier_t), (void **) & barriers->array);
+
+    if (F_status_is_error_not(status)) {
+      barriers->size = length;
+
+      if (barriers->used > barriers->size) {
+        barriers->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_)
+
+#if !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_) || !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_) || !defined(_di_f_thread_barrier_attributes_resize_)
+  f_status_t private_f_thread_barrier_attribute_delete(f_thread_barrier_attribute_t *attribute) {
+
+    if (pthread_barrierattr_destroy(attribute)) {
+      return F_status_set_error(F_failure);
+    }
+
+    attribute = 0;
+
+    return F_none;
+  }
+#endif // !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_) || !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_) || !defined(_di_f_thread_barrier_attributes_resize_)
+
+#if !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_)
+  f_status_t private_f_thread_barrier_attributes_adjust(const f_array_length_t length, f_thread_barrier_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_barrier_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(attributes->size, length, sizeof(f_thread_barrier_attribute_t), (void **) & attributes->array);
+
+    if (F_status_is_error_not(status)) {
+      attributes->size = length;
+
+      if (attributes->used > attributes->size) {
+        attributes->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_)
+
+#if !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_)
+  f_status_t private_f_thread_barrier_attributes_resize(const f_array_length_t length, f_thread_barrier_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_barrier_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(attributes->size, length, sizeof(f_thread_barrier_attribute_t), (void **) & attributes->array);
+
+    if (F_status_is_error_not(status)) {
+      attributes->size = length;
+
+      if (attributes->used > attributes->size) {
+        attributes->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_)
+
 #if !defined(_di_f_thread_condition_attributes_adjust_) || !defined(_di_f_thread_condition_attributes_decimate_by_) || !defined(_di_f_thread_condition_attributes_decrease_) || !defined(_di_f_thread_condition_attributes_decrease_by_) || !defined(_di_f_thread_condition_attributes_increase_) || !defined(_di_f_thread_condition_attributes_increase_by_) || !defined(_di_f_thread_condition_attributes_resize_)
   f_status_t private_f_thread_condition_attribute_delete(f_thread_condition_attribute_t *attribute) {
 
@@ -194,6 +316,195 @@ extern "C" {
   }
 #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_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_) || !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_) || !defined(_di_f_thread_keys_resize_)
+  f_status_t private_f_thread_key_delete(f_thread_key_t *key) {
+
+    if (pthread_key_delete(*key)) {
+      return F_status_set_error(F_failure);
+    }
+
+    key = 0;
+
+    return F_none;
+  }
+#endif // !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_) || !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_) || !defined(_di_f_thread_keys_resize_)
+
+#if !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_)
+  f_status_t private_f_thread_keys_adjust(const f_array_length_t length, f_thread_keys_t *keys) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < keys->size; ++i) {
+
+      status = private_f_thread_key_delete(&keys->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(keys->size, length, sizeof(f_thread_key_t), (void **) & keys->array);
+
+    if (F_status_is_error_not(status)) {
+      keys->size = length;
+
+      if (keys->used > keys->size) {
+        keys->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_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_)
+  f_status_t private_f_thread_keys_resize(const f_array_length_t length, f_thread_keys_t *keys) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < keys->size; ++i) {
+
+      status = private_f_thread_key_delete(&keys->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(keys->size, length, sizeof(f_thread_key_t), (void **) & keys->array);
+
+    if (F_status_is_error_not(status)) {
+      keys->size = length;
+
+      if (keys->used > keys->size) {
+        keys->used = 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_adjust_) || !defined(_di_f_thread_locks_decimate_by_) || !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_) || !defined(_di_f_thread_locks_resize_)
+  f_status_t private_f_thread_lock_delete(f_thread_lock_t *lock) {
+
+    const int error = pthread_rwlock_destroy(lock);
+
+    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 // !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_) || !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_) || !defined(_di_f_thread_locks_resize_)
+
+#if !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_)
+  f_status_t private_f_thread_locks_adjust(const f_array_length_t length, f_thread_locks_t *locks) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < locks->size; ++i) {
+
+      status = private_f_thread_lock_delete(&locks->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(locks->size, length, sizeof(f_thread_lock_t), (void **) & locks->array);
+
+    if (F_status_is_error_not(status)) {
+      locks->size = length;
+
+      if (locks->used > locks->size) {
+        locks->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_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_)
+  f_status_t private_f_thread_locks_resize(const f_array_length_t length, f_thread_locks_t *locks) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < locks->size; ++i) {
+
+      status = private_f_thread_lock_delete(&locks->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(locks->size, length, sizeof(f_thread_lock_t), (void **) & locks->array);
+
+    if (F_status_is_error_not(status)) {
+      locks->size = length;
+
+      if (locks->used > locks->size) {
+        locks->used = 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_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_) || !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_) || !defined(_di_f_thread_lock_attributes_resize_)
+  f_status_t private_f_thread_lock_attribute_delete(f_thread_lock_attribute_t *attribute) {
+
+    const int error = pthread_rwlockattr_destroy(attribute);
+
+    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 // !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_) || !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_) || !defined(_di_f_thread_lock_attributes_resize_)
+
+#if !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_)
+  f_status_t private_f_thread_lock_attributes_adjust(const f_array_length_t length, f_thread_lock_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_lock_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(attributes->size, length, sizeof(f_thread_lock_t), (void **) & attributes->array);
+
+    if (F_status_is_error_not(status)) {
+      attributes->size = length;
+
+      if (attributes->used > attributes->size) {
+        attributes->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_)
+
+#if !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_)
+  f_status_t private_f_thread_lock_attributes_resize(const f_array_length_t length, f_thread_lock_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_lock_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(attributes->size, length, sizeof(f_thread_lock_t), (void **) & attributes->array);
+
+    if (F_status_is_error_not(status)) {
+      attributes->size = length;
+
+      if (attributes->used > attributes->size) {
+        attributes->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_)
+
 #if !defined(_di_f_thread_mutex_attributes_adjust_) || !defined(_di_f_thread_mutex_attributes_decimate_by_) || !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_) || !defined(_di_f_thread_mutex_attributes_resize_)
   f_status_t private_f_thread_mutex_attribute_delete(f_thread_mutex_attribute_t *attribute) {
 
@@ -370,6 +681,70 @@ extern "C" {
   }
 #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_)
 
+#if !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_) || !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_) || !defined(_di_f_thread_spins_resize_)
+  f_status_t private_f_thread_spin_delete(f_thread_spin_t *spin) {
+
+    const int error = pthread_spin_destroy(spin);
+
+    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 // !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_) || !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_) || !defined(_di_f_thread_spins_resize_)
+
+#if !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_)
+  f_status_t private_f_thread_spins_adjust(const f_array_length_t length, f_thread_spins_t *spins) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < spins->size; ++i) {
+
+      status = private_f_thread_spin_delete(&spins->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(spins->size, length, sizeof(f_thread_spin_t), (void **) & spins->array);
+
+    if (F_status_is_error_not(status)) {
+      spins->size = length;
+
+      if (spins->used > spins->size) {
+        spins->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_)
+
+#if !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_)
+  f_status_t private_f_thread_spins_resize(const f_array_length_t length, f_thread_spins_t *spins) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < spins->size; ++i) {
+
+      status = private_f_thread_spin_delete(&spins->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(spins->size, length, sizeof(f_thread_spin_t), (void **) & spins->array);
+
+    if (F_status_is_error_not(status)) {
+      spins->size = length;
+
+      if (spins->used > spins->size) {
+        spins->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_)
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index a7340ee2a50691ee494bfd1b12b3db3741924143..e917e9b3bafafd7fdab3d9cd60d98e2174eefb56 100644 (file)
@@ -105,6 +105,158 @@ extern "C" {
  *
  * @param length
  *   The new size to use.
+ * @param barriers
+ *   The barriers to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_attr_destroy()
+ *
+ * @see f_thread_barriers_adjust()
+ * @see f_thread_barriers_decimate_by()
+ * @see f_thread_barriers_decrease()
+ * @see f_thread_barriers_decrease_by()
+ * @see f_thread_barriers_increase()
+ * @see f_thread_barriers_increase_by()
+ * @see f_thread_barriers_resize()
+ */
+#if !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_) || !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_) || !defined(_di_f_thread_barriers_resize_)
+  extern f_status_t private_f_thread_barrier_delete(f_thread_barrier_t *barrier) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_) || !defined(_di_f_thread_barriers_decrease_) || !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_) || !defined(_di_f_thread_barriers_resize_)
+
+/**
+ * Private implementation for resizing.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param barriers
+ *   The barriers to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_barriers_adjust()
+ * @see f_thread_barriers_decimate_by()
+ */
+#if !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_)
+  extern f_status_t private_f_thread_barriers_adjust(const f_array_length_t length, f_thread_barriers_t *barriers) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barriers_adjust_) || !defined(_di_f_thread_barriers_decimate_by_)
+
+/**
+ * Private implementation for resizing.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param barriers
+ *   The barriers to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_barriers_decrease_by()
+ * @see f_thread_barriers_increase()
+ * @see f_thread_barriers_increase_by()
+ */
+#if !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_)
+  extern f_status_t private_f_thread_barriers_resize(const f_array_length_t length, f_thread_barriers_t *barriers) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barriers_decrease_by_) || !defined(_di_f_thread_barriers_increase_) || !defined(_di_f_thread_barriers_increase_by_)
+
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param attributes
+ *   The attributes to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_attr_destroy()
+ *
+ * @see f_thread_barrier_attributes_adjust()
+ * @see f_thread_barrier_attributes_decimate_by()
+ * @see f_thread_barrier_attributes_decrease()
+ * @see f_thread_barrier_attributes_decrease_by()
+ * @see f_thread_barrier_attributes_increase()
+ * @see f_thread_barrier_attributes_increase_by()
+ * @see f_thread_barrier_attributes_resize()
+ */
+#if !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_) || !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_) || !defined(_di_f_thread_barrier_attributes_resize_)
+  extern f_status_t private_f_thread_barrier_attribute_delete(f_thread_barrier_attribute_t *attribute) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_) || !defined(_di_f_thread_barrier_attributes_decrease_) || !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_) || !defined(_di_f_thread_barrier_attributes_resize_)
+
+/**
+ * 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 adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_barrier_attributes_adjust()
+ * @see f_thread_barrier_attributes_decimate_by()
+ */
+#if !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_)
+  extern f_status_t private_f_thread_barrier_attributes_adjust(const f_array_length_t length, f_thread_barrier_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barrier_attributes_adjust_) || !defined(_di_f_thread_barrier_attributes_decimate_by_)
+
+/**
+ * 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_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_barrier_attributes_decrease_by()
+ * @see f_thread_barrier_attributes_increase()
+ * @see f_thread_barrier_attributes_increase_by()
+ */
+#if !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_)
+  extern f_status_t private_f_thread_barrier_attributes_resize(const f_array_length_t length, f_thread_barrier_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_barrier_attributes_decrease_by_) || !defined(_di_f_thread_barrier_attributes_increase_) || !defined(_di_f_thread_barrier_attributes_increase_by_)
+
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
  * @param attribute
  *   The attribute to adjust.
  *
@@ -255,6 +407,228 @@ extern "C" {
  *
  * Intended to be shared to each of the different implementation variations.
  *
+ * @param key
+ *   The keys to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_key_destroy()
+ *
+ * @see f_thread_keys_adjust()
+ * @see f_thread_keys_decimate_by()
+ * @see f_thread_keys_decrease()
+ * @see f_thread_keys_decrease_by()
+ * @see f_thread_keys_increase()
+ * @see f_thread_keys_increase_by()
+ * @see f_thread_keys_resize()
+ */
+#if !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_) || !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_) || !defined(_di_f_thread_keys_resize_)
+  extern f_status_t private_f_thread_key_delete(f_thread_key_t *key) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_) || !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_) || !defined(_di_f_thread_keys_resize_)
+
+/**
+ * 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 adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_keys_adjust()
+ * @see f_thread_keys_decimate_by()
+ */
+#if !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_)
+  extern f_status_t private_f_thread_keys_adjust(const f_array_length_t length, f_thread_keys_t *keys) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_keys_adjust_) || !defined(_di_f_thread_keys_decimate_by_)
+
+/**
+ * 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_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_keys_decrease_by()
+ * @see f_thread_keys_increase()
+ * @see f_thread_keys_increase_by()
+ */
+#if !defined(_di_f_thread_keys_decrease_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_)
+  extern f_status_t 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_by_) || !defined(_di_f_thread_keys_increase_) || !defined(_di_f_thread_keys_increase_by_)
+
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param lock
+ *   The locks to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_rwlock_destroy()
+ *
+ * @see f_thread_locks_adjust()
+ * @see f_thread_locks_decimate_by()
+ * @see f_thread_locks_decrease()
+ * @see f_thread_locks_decrease_by()
+ * @see f_thread_locks_increase()
+ * @see f_thread_locks_increase_by()
+ * @see f_thread_locks_resize()
+ */
+#if !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_) || !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_) || !defined(_di_f_thread_locks_resize_)
+  extern f_status_t private_f_thread_lock_delete(f_thread_lock_t *lock) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_) || !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_) || !defined(_di_f_thread_locks_resize_)
+
+/**
+ * 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 adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_locks_adjust()
+ * @see f_thread_locks_decimate_by()
+ */
+#if !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_)
+  extern f_status_t private_f_thread_locks_adjust(const f_array_length_t length, f_thread_locks_t *locks) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_locks_adjust_) || !defined(_di_f_thread_locks_decimate_by_)
+
+/**
+ * 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_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_locks_decrease_by()
+ * @see f_thread_locks_increase()
+ * @see f_thread_locks_increase_by()
+ */
+#if !defined(_di_f_thread_locks_decrease_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_)
+  extern f_status_t 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_by_) || !defined(_di_f_thread_locks_increase_) || !defined(_di_f_thread_locks_increase_by_)
+
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param attribute
+ *   The attribute to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_rwlockattr_destroy()
+ *
+ * @see f_thread_lock_attributes_adjust()
+ * @see f_thread_lock_attributes_decimate_by()
+ * @see f_thread_lock_attributes_decrease()
+ * @see f_thread_lock_attributes_decrease_by()
+ * @see f_thread_lock_attributes_increase()
+ * @see f_thread_lock_attributes_increase_by()
+ * @see f_thread_lock_attributes_resize()
+ */
+#if !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_) || !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_) || !defined(_di_f_thread_lock_attributes_resize_)
+  extern f_status_t private_f_thread_lock_attribute_delete(f_thread_lock_attribute_t *attribute) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_) || !defined(_di_f_thread_lock_attributes_decrease_) || !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_) || !defined(_di_f_thread_lock_attributes_resize_)
+
+/**
+ * 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 adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_lock_attributes_adjust()
+ * @see f_thread_lock_attributes_decimate_by()
+ */
+#if !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_)
+  extern f_status_t private_f_thread_lock_attributes_adjust(const f_array_length_t length, f_thread_lock_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_lock_attributes_adjust_) || !defined(_di_f_thread_lock_attributes_decimate_by_)
+
+/**
+ * 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_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_lock_attributes_decrease_by()
+ * @see f_thread_lock_attributes_increase()
+ * @see f_thread_lock_attributes_increase_by()
+ */
+#if !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_)
+  extern f_status_t private_f_thread_lock_attributes_resize(const f_array_length_t length, f_thread_lock_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_lock_attributes_decrease_by_) || !defined(_di_f_thread_lock_attributes_increase_) || !defined(_di_f_thread_lock_attributes_increase_by_)
+
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
  * @param attribute
  *   The attribute to delete.
  *
@@ -445,6 +819,80 @@ extern "C" {
   extern f_status_t 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_by_) || !defined(_di_f_thread_sets_increase_) || !defined(_di_f_thread_sets_increase_by_)
 
+/**
+ * Private implementation for deleting (and destroying).
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param spin
+ *   The spins to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_spin_destroy()
+ *
+ * @see f_thread_spins_adjust()
+ * @see f_thread_spins_decimate_by()
+ * @see f_thread_spins_decrease()
+ * @see f_thread_spins_decrease_by()
+ * @see f_thread_spins_increase()
+ * @see f_thread_spins_increase_by()
+ * @see f_thread_spins_resize()
+ */
+#if !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_) || !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_) || !defined(_di_f_thread_spins_resize_)
+  extern f_status_t private_f_thread_spin_delete(f_thread_spin_t *spin) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_) || !defined(_di_f_thread_spins_decrease_) || !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_) || !defined(_di_f_thread_spins_resize_)
+
+/**
+ * Private implementation for resizing.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param spins
+ *   The spins to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_spins_adjust()
+ * @see f_thread_spins_decimate_by()
+ */
+#if !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_)
+  extern f_status_t private_f_thread_spins_adjust(const f_array_length_t length, f_thread_spins_t *spins) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_spins_adjust_) || !defined(_di_f_thread_spins_decimate_by_)
+
+/**
+ * Private implementation for resizing.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param spins
+ *   The spins to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_spins_decrease_by()
+ * @see f_thread_spins_increase()
+ * @see f_thread_spins_increase_by()
+ */
+#if !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_)
+  extern f_status_t private_f_thread_spins_resize(const f_array_length_t length, f_thread_spins_t *spins) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_spins_decrease_by_) || !defined(_di_f_thread_spins_increase_) || !defined(_di_f_thread_spins_increase_by_)
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 7f445d7e29c23842625694b8cfedc0f8756d2338..68d5160029c77fa743aced74e336893252656e6b 100644 (file)
@@ -62,6 +62,94 @@ extern "C" {
 #endif // _di_f_thread_attributes_t_
 
 /**
+ * A typedef representing pthread_barrier_t.
+ */
+#ifndef _di_f_thread_barrier_t_
+  typedef pthread_barrier_t f_thread_barrier_t;
+
+  #define f_thread_barrier_t_initialize { 0 }
+
+  #define f_macro_thread_barrier_t_clear(barrier) barrier = 0
+
+  #define f_macro_thread_barrier_t_delete_simple(barrier) f_thread_barrier_delete(&barrier);
+#endif // _di_f_thread_barrier_t_
+
+/**
+ * An array of f_thread_barrier_t.
+ *
+ * array: the array of f_thread_barrier_t.
+ * size: total amount of allocated space.
+ * used: total number of allocated spaces used.
+ */
+#ifndef _di_f_thread_barriers_t_
+  typedef struct {
+    f_thread_barrier_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } f_thread_barriers_t;
+
+  #define f_thread_barriers_t_initialize { 0, 0, 0 }
+
+  #define f_macro_thread_barriers_t_clear(barriers) f_macro_memory_structure_clear(barriers)
+
+  #define f_macro_thread_barriers_t_resize(status, barriers, length) status = f_thread_barriers_resize(length, &barriers);
+  #define f_macro_thread_barriers_t_adjust(status, barriers, length) status = f_thread_barriers_adjust(length, &barriers);
+
+  #define f_macro_thread_barriers_t_delete_simple(barriers)  f_thread_barriers_resize(0, &barriers);
+  #define f_macro_thread_barriers_t_destroy_simple(barriers) f_thread_barriers_adjust(0, &barriers);
+
+  #define f_macro_thread_barriers_t_increase(status, barriers)            status = f_thread_barriers_increase(barriers);
+  #define f_macro_thread_barriers_t_increase_by(status, barriers, amount) status = f_thread_barriers_increase_by(amount, barriers);
+  #define f_macro_thread_barriers_t_decrease_by(status, barriers, amount) status = f_thread_barriers_decrease_by(amount, barriers);
+  #define f_macro_thread_barriers_t_decimate_by(status, barriers, amount) status = f_thread_barriers_decimate_by(amount, barriers);
+#endif // _di_f_thread_barriers_t_
+
+/**
+ * A typedef representing pthread_barrierattr_t.
+ */
+#ifndef _di_f_thread_barrier_attribute_t_
+  typedef pthread_barrierattr_t f_thread_barrier_attribute_t;
+
+  #define f_thread_barrier_attribute_t_initialize { 0 }
+
+  #define f_macro_thread_barrier_attribute_t_clear(barrier_attribute) barrier_attribute = 0
+
+  #define f_macro_thread_barrier_attribute_t_delete_simple(barrier_attribute) f_thread_barrier_attribute_delete(&barrier_attribute);
+#endif // _di_f_thread_barrier_attribute_t_
+
+/**
+ * An array of f_thread_barrier_attribute_t.
+ *
+ * array: the array of f_thread_barrier_attribute_t.
+ * size: total amount of allocated space.
+ * used: total number of allocated spaces used.
+ */
+#ifndef _di_f_thread_barrier_attributes_t_
+  typedef struct {
+    f_thread_barrier_attribute_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } f_thread_barrier_attributes_t;
+
+  #define f_thread_barrier_attributes_t_initialize { 0, 0, 0 }
+
+  #define f_macro_thread_barrier_attributes_t_clear(barrier_attributes) f_macro_memory_structure_clear(barrier_attributes)
+
+  #define f_macro_thread_barrier_attributes_t_resize(status, barrier_attributes, length) status = f_thread_barrier_attributes_resize(length, &barrier_attributes);
+  #define f_macro_thread_barrier_attributes_t_adjust(status, barrier_attributes, length) status = f_thread_barrier_attributes_adjust(length, &barrier_attributes);
+
+  #define f_macro_thread_barrier_attributes_t_delete_simple(barrier_attributes)  f_thread_barrier_attributes_resize(0, &barrier_attributes);
+  #define f_macro_thread_barrier_attributes_t_destroy_simple(barrier_attributes) f_thread_barrier_attributes_adjust(0, &barrier_attributes);
+
+  #define f_macro_thread_barrier_attributes_t_increase(status, barrier_attributes)            status = f_thread_barrier_attributes_increase(barrier_attributes);
+  #define f_macro_thread_barrier_attributes_t_increase_by(status, barrier_attributes, amount) status = f_thread_barrier_attributes_increase_by(amount, barrier_attributes);
+  #define f_macro_thread_barrier_attributes_t_decrease_by(status, barrier_attributes, amount) status = f_thread_barrier_attributes_decrease_by(amount, barrier_attributes);
+  #define f_macro_thread_barrier_attributes_t_decimate_by(status, barrier_attributes, amount) status = f_thread_barrier_attributes_decimate_by(amount, barrier_attributes);
+#endif // _di_f_thread_barrier_attributes_t_
+
+/**
  * A typedef representing pthread_cond_t.
  */
 #ifndef _di_f_thread_condition_t_
@@ -198,6 +286,8 @@ extern "C" {
   #define f_thread_key_t_initialize 0
 
   #define f_macro_thread_key_t_clear(key) key = 0
+
+  #define f_macro_thread_key_t_delete_simple(key) f_thread_key_delete(&key);
 #endif // _di_f_thread_key_t_
 
 /**
@@ -217,16 +307,18 @@ extern "C" {
 
   #define f_thread_keys_t_initialize { 0, 0, 0 }
 
-  #define f_macro_thread_keys_t_resize(status, keys, length) f_macro_memory_structure_resize(status, keys, f_thread_key_t, length)
-  #define f_macro_thread_keys_t_adjust(status, keys, length) f_macro_memory_structure_adjust(status, keys, f_thread_key_t, length)
+  #define f_macro_thread_keys_t_clear(keys) f_macro_memory_structure_clear(keys)
 
-  #define f_macro_thread_keys_t_delete_simple(keys)  f_macro_memory_structure_delete_simple(keys, f_thread_key_t)
-  #define f_macro_thread_keys_t_destroy_simple(keys) f_macro_memory_structure_destroy_simple(keys, f_thread_key_t)
+  #define f_macro_thread_keys_t_resize(status, keys, length) status = f_thread_keys_resize(length, &keys);
+  #define f_macro_thread_keys_t_adjust(status, keys, length) status = f_thread_keys_adjust(length, &keys);
 
-  #define f_macro_thread_keys_t_increase(status, keys)            f_macro_memory_structure_increase(status, keys, f_thread_key_t)
-  #define f_macro_thread_keys_t_increase_by(status, keys, amount) f_macro_memory_structure_increase_by(status, keys, f_thread_key_t, amount)
-  #define f_macro_thread_keys_t_decrease_by(status, keys, amount) f_macro_memory_structure_decrease_by(status, keys, f_thread_key_t, amount)
-  #define f_macro_thread_keys_t_decimate_by(status, keys, amount) f_macro_memory_structure_decimate_by(status, keys, f_thread_key_t, amount)
+  #define f_macro_thread_keys_t_delete_simple(keys)  f_thread_keys_resize(0, &keys);
+  #define f_macro_thread_keys_t_destroy_simple(keys) f_thread_keys_adjust(0, &keys);
+
+  #define f_macro_thread_keys_t_increase(status, keys)            status = f_thread_keys_increase(keys);
+  #define f_macro_thread_keys_t_increase_by(status, keys, amount) status = f_thread_keys_increase_by(amount, keys);
+  #define f_macro_thread_keys_t_decrease_by(status, keys, amount) status = f_thread_keys_decrease_by(amount, keys);
+  #define f_macro_thread_keys_t_decimate_by(status, keys, amount) status = f_thread_keys_decimate_by(amount, keys);
 #endif // _di_f_thread_keys_t_
 
 /**
@@ -270,6 +362,48 @@ extern "C" {
 #endif // _di_f_thread_locks_t_
 
 /**
+ * A typedef representing pthread_rwlockattr_t.
+ */
+#ifndef _di_f_thread_lock_attribute_t_
+  typedef pthread_rwlockattr_t f_thread_lock_attribute_t;
+
+  #define f_thread_lock_attribute_t_initialize 0
+
+  #define f_macro_thread_lock_attribute_t_clear(attribute) attribute = 0
+#endif // _di_f_thread_lock_attribute_t_
+
+/**
+ * An array of read/write lock attributees.
+ *
+ * array: the array of f_thread_lock_attribute_t.
+ * size: total amount of allocated space.
+ * used: total number of allocated spaces used.
+ */
+#ifndef _di_f_thread_lock_attributes_t_
+  typedef struct {
+    f_thread_lock_attribute_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } f_thread_lock_attributes_t;
+
+  #define f_thread_lock_attributes_t_initialize { 0, 0, 0 }
+
+  #define f_macro_thread_lock_attributes_t_clear(attributes) f_macro_memory_structure_clear(attributes)
+
+  #define f_macro_thread_lock_attributes_t_resize(status, attributes, length) status = f_thread_lock_attributes_resize(length, &attributes);
+  #define f_macro_thread_lock_attributes_t_adjust(status, attributes, length) status = f_thread_lock_attributes_adjust(length, &attributes);
+
+  #define f_macro_thread_lock_attributes_t_delete_simple(attributes)  f_thread_lock_attributes_resize(0, &attributes);
+  #define f_macro_thread_lock_attributes_t_destroy_simple(attributes) f_thread_lock_attributes_adjust(0, &attributes);
+
+  #define f_macro_thread_lock_attributes_t_increase(status, attributes)            status = f_thread_lock_attributes_increase(attributes);
+  #define f_macro_thread_lock_attributes_t_increase_by(status, attributes, amount) status = f_thread_lock_attributes_increase_by(amount, attributes);
+  #define f_macro_thread_lock_attributes_t_decrease_by(status, attributes, amount) status = f_thread_lock_attributes_decrease_by(amount, attributes);
+  #define f_macro_thread_lock_attributes_t_decimate_by(status, attributes, amount) status = f_thread_lock_attributes_decimate_by(amount, attributes);
+#endif // _di_f_thread_lock_attributes_t_
+
+/**
  * A typedef representing pthread_mutex_t.
  */
 #ifndef _di_f_thread_mutex_t_
@@ -449,6 +583,50 @@ extern "C" {
   #define f_macro_thread_sets_t_decimate_by(status, sets, amount) status = f_thread_sets_decimate_by(amount, sets);
 #endif // _di_f_thread_sets_t_
 
+/**
+ * A typedef representing pthread_spinlock_t.
+ */
+#ifndef _di_f_thread_spin_t_
+  typedef pthread_spinlock_t f_thread_spin_t;
+
+  #define f_thread_spin_t_initialize PTHREAD_MUTEX_INITIALIZER
+
+  #define f_macro_thread_spin_t_clear(spin) spin = 0
+
+  #define f_macro_thread_spin_t_delete_simple(spin) f_thread_spin_delete(&spin);
+#endif // _di_f_thread_spin_t_
+
+/**
+ * An array of thread spins.
+ *
+ * array: the array of f_thread_spin_t.
+ * size: total amount of allocated space.
+ * used: total number of allocated spaces used.
+ */
+#ifndef _di_f_thread_spins_t_
+  typedef struct {
+    f_thread_spin_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } f_thread_spins_t;
+
+  #define f_thread_spins_t_initialize { 0, 0, 0 }
+
+  #define f_macro_thread_spins_t_clear(spins) f_macro_memory_structure_clear(spins)
+
+  #define f_macro_thread_spins_t_resize(status, spins, length) status = f_thread_spins_resize(length, &spins);
+  #define f_macro_thread_spins_t_adjust(status, spins, length) status = f_thread_spins_adjust(length, &spins);
+
+  #define f_macro_thread_spins_t_delete_simple(spins)  f_thread_spins_resize(0, &spins);
+  #define f_macro_thread_spins_t_destroy_simple(spins) f_thread_spins_adjust(0, &spins);
+
+  #define f_macro_thread_spins_t_increase(status, spins)            status = f_thread_spins_increase(spins);
+  #define f_macro_thread_spins_t_increase_by(status, spins, amount) status = f_thread_spins_increase_by(amount, spins);
+  #define f_macro_thread_spins_t_decrease_by(status, spins, amount) status = f_thread_spins_decrease_by(amount, spins);
+  #define f_macro_thread_spins_t_decimate_by(status, spins, amount) status = f_thread_spins_decimate_by(amount, spins);
+#endif // _di_f_thread_spins_t_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 0295b95bd439a7ef6d1024cad1ff91f4fbde7295..7a43f6501989f4e536df9c4dd5e352d0db7ddea1 100644 (file)
@@ -62,6 +62,72 @@ extern "C" {
   }
 #endif // _di_f_thread_attribute_affinity_set_
 
+#ifndef _di_f_thread_attribute_clock_get_
+  f_status_t f_thread_attribute_clock_get(const f_thread_condition_attribute_t *attribute, clockid_t *id) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!id) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (pthread_condattr_getclock(attribute, id)) {
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_attribute_clock_get_
+
+#ifndef _di_f_thread_attribute_clock_set_
+  f_status_t f_thread_attribute_clock_set(const clockid_t id, f_thread_condition_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_condattr_setclock(attribute, id);
+
+    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_clock_set_
+
+#ifndef _di_f_thread_attribute_condition_shared_get_
+  f_status_t f_thread_attribute_condition_shared_get(const f_thread_condition_attribute_t *attribute, int *shared) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!shared) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (pthread_condattr_getpshared(attribute, shared)) {
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_attribute_condition_shared_get_
+
+#ifndef _di_f_thread_attribute_condition_shared_set_
+  f_status_t f_thread_attribute_condition_shared_set(const int shared, f_thread_condition_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_condattr_setpshared(attribute, shared);
+
+    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_condition_shared_set_
+
 #ifndef _di_f_thread_attribute_create_
   f_status_t f_thread_attribute_create(f_thread_attribute_t *attribute) {
 
@@ -379,6 +445,40 @@ extern "C" {
   }
 #endif // _di_f_thread_attribute_stack_set_
 
+#ifndef _di_f_thread_attribute_stack_size_get_
+  f_status_t f_thread_attribute_stack_size_get(const f_thread_attribute_t attribute, size_t *stack_size) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!stack_size) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_attr_getstacksize(&attribute, stack_size);
+
+    if (error) {
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_attribute_stack_size_get_
+
+#ifndef _di_f_thread_attribute_stack_size_set_
+  f_status_t f_thread_attribute_stack_size_set(const size_t stack_size, 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_setstacksize(attribute, stack_size);
+
+    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_stack_size_set_
+
 #ifndef _di_f_thread_attributes_adjust_
   f_status_t f_thread_attributes_adjust(const f_array_length_t length, f_thread_attributes_t *attributes) {
     #ifndef _di_level_0_parameter_checking_
@@ -472,164 +572,106 @@ extern "C" {
   }
 #endif // _di_f_thread_attributes_resize_
 
-#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_status_t 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_status_t f_thread_cancel_state_set(const int state, int *previous) {
+#ifndef _di_f_thread_barrier_attribute_create_
+  f_status_t f_thread_barrier_attribute_create(f_thread_barrier_attribute_t *attribute) {
 
-    const int error = pthread_setcancelstate(state, previous);
+    const int error = pthread_barrierattr_init(attribute);
 
     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_cancel_state_set_
-
-#ifndef _di_f_thread_cancel_test_
-  f_status_t f_thread_cancel_test() {
-
-    pthread_testcancel();
-
-    return F_none;
-  }
-#endif // _di_f_thread_cancel_test_
-
-#ifndef _di_f_thread_cancel_type_set_
-  f_status_t 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);
+#endif // _di_f_thread_barrier_attribute_create_
 
-      return F_status_set_error(F_failure);
-    }
+#ifndef _di_f_thread_barrier_attribute_delete_
+  f_status_t f_thread_barrier_attribute_delete(f_thread_barrier_attribute_t *attribute) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
-    return F_none;
+    return private_f_thread_barrier_attribute_delete(attribute);
   }
-#endif // _di_f_thread_cancel_type_set_
-
-#ifndef _di_f_thread_clock_get_id_
-  f_status_t f_thread_clock_get_id(const f_thread_id_t id_thread, clockid_t *id_clock) {
+#endif // _di_f_thread_barrier_attribute_delete_
 
-    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);
+#ifndef _di_f_thread_barrier_attribute_shared_get_
+  f_status_t f_thread_barrier_attribute_shared_get(const f_thread_barrier_attribute_t *attribute, int *shared) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!shared) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
+    if (pthread_barrierattr_getpshared(attribute, shared)) {
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_clock_get_id_
-
-#ifndef _di_f_thread_compare_
-  f_status_t 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_
+#endif // _di_f_thread_barrier_attribute_shared_get_
 
-#ifndef _di_f_thread_condition_attribute_create_
-  f_status_t f_thread_condition_attribute_create(f_thread_condition_attribute_t *attribute) {
+#ifndef _di_f_thread_barrier_attribute_shared_set_
+  f_status_t f_thread_barrier_attribute_shared_set(const int shared, f_thread_barrier_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_condattr_init(attribute);
+    const int error = pthread_barrierattr_setpshared(attribute, shared);
 
     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_condition_attribute_create_
-
-#ifndef _di_f_thread_condition_attribute_delete_
-  f_status_t f_thread_condition_attribute_delete(f_thread_condition_attribute_t *condition_attribute) {
-    #ifndef _di_level_0_parameter_checking_
-      if (!condition_attribute) return F_status_set_error(F_parameter);
-    #endif // _di_level_0_parameter_checking_
-
-    return private_f_thread_condition_attribute_delete(condition_attribute);
-  }
-#endif // _di_f_thread_condition_attribute_delete_
+#endif // _di_f_thread_barrier_attribute_shared_set_
 
-#ifndef _di_f_thread_condition_attributes_adjust_
-  f_status_t f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_adjust_
+  f_status_t f_thread_barrier_attributes_adjust(const f_array_length_t length, f_thread_barrier_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_condition_attributes_adjust(length, attributes);
+    return private_f_thread_barrier_attributes_adjust(length, attributes);
   }
-#endif // _di_f_thread_condition_attributes_adjust_
+#endif // _di_f_thread_barrier_attributes_adjust_
 
-#ifndef _di_f_thread_condition_attributes_decimate_by_
-  f_status_t f_thread_condition_attributes_decimate_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_decimate_by_
+  f_status_t f_thread_barrier_attributes_decimate_by(const f_array_length_t amount, f_thread_barrier_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_condition_attributes_adjust(attributes->size - amount, attributes);
+      return private_f_thread_barrier_attributes_adjust(attributes->size - amount, attributes);
     }
 
-    return private_f_thread_condition_attributes_adjust(0, attributes);
+    return private_f_thread_barrier_attributes_adjust(0, attributes);
   }
-#endif // _di_f_thread_condition_attributes_decimate_by_
+#endif // _di_f_thread_barrier_attributes_decimate_by_
 
-#ifndef _di_f_thread_condition_attributes_decrease_by_
-  f_status_t f_thread_condition_attributes_decrease_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_decrease_by_
+  f_status_t f_thread_barrier_attributes_decrease_by(const f_array_length_t amount, f_thread_barrier_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_condition_attributes_resize(attributes->size - amount, attributes);
+      return private_f_thread_barrier_attributes_resize(attributes->size - amount, attributes);
     }
 
-    return private_f_thread_condition_attributes_resize(0, attributes);
+    return private_f_thread_barrier_attributes_resize(0, attributes);
   }
-#endif // _di_f_thread_condition_attributes_decrease_by_
+#endif // _di_f_thread_barrier_attributes_decrease_by_
 
-#ifndef _di_f_thread_condition_attributes_increase_
-  f_status_t f_thread_condition_attributes_increase(f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_increase_
+  f_status_t f_thread_barrier_attributes_increase(f_thread_barrier_attributes_t *attributes) {
     #ifndef _di_level_0_parameter_checking_
       if (!attributes) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
@@ -645,15 +687,15 @@ extern "C" {
         size = f_array_length_t_size;
       }
 
-      return private_f_thread_condition_attributes_resize(size, attributes);
+      return private_f_thread_barrier_attributes_resize(size, attributes);
     }
 
     return F_data_not;
   }
-#endif // _di_f_thread_condition_attributes_increase_
+#endif // _di_f_thread_barrier_attributes_increase_
 
-#ifndef _di_f_thread_condition_attributes_increase_by_
-  f_status_t f_thread_condition_attributes_increase_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_increase_by_
+  f_status_t f_thread_barrier_attributes_increase_by(const f_array_length_t amount, f_thread_barrier_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);
@@ -664,35 +706,29 @@ extern "C" {
         return F_status_set_error(F_array_too_large);
       }
 
-      return private_f_thread_condition_attributes_resize(attributes->used + amount, attributes);
+      return private_f_thread_barrier_attributes_resize(attributes->used + amount, attributes);
     }
 
     return F_data_not;
   }
-#endif // _di_f_thread_condition_attributes_increase_by_
+#endif // _di_f_thread_barrier_attributes_increase_by_
 
-#ifndef _di_f_thread_condition_attributes_resize_
-  f_status_t f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_attributes_t *attributes) {
+#ifndef _di_f_thread_barrier_attributes_resize_
+  f_status_t f_thread_barrier_attributes_resize(const f_array_length_t length, f_thread_barrier_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_condition_attributes_resize(length, attributes);
+    return private_f_thread_barrier_attributes_resize(length, attributes);
   }
-#endif // _di_f_thread_condition_attributes_resize_
+#endif // _di_f_thread_barrier_attributes_resize_
 
-#ifndef _di_f_thread_condition_create_
-  f_status_t f_thread_condition_create(const f_thread_condition_attribute_t *attribute, 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_
+#ifndef _di_f_thread_barrier_create_
+  f_status_t f_thread_barrier_create(const unsigned int count, f_thread_barrier_attribute_t * const attribute, f_thread_barrier_t *barrier) {
 
-    const int error = pthread_cond_init(condition, attribute);
+    const int error = pthread_barrier_init(barrier, attribute, count);
 
     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);
 
       return F_status_set_error(F_failure);
@@ -700,199 +736,1225 @@ extern "C" {
 
     return F_none;
   }
-#endif // _di_f_thread_condition_create_
+#endif // _di_f_thread_barrier_create_
 
-#ifndef _di_f_thread_condition_delete_
-  f_status_t f_thread_condition_delete(f_thread_condition_t *condition) {
+#ifndef _di_f_thread_barrier_delete_
+  f_status_t f_thread_barrier_delete(f_thread_barrier_t *barrier) {
     #ifndef _di_level_0_parameter_checking_
-      if (!condition) return F_status_set_error(F_parameter);
+      if (!barrier) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_thread_condition_delete(condition);
+    return private_f_thread_barrier_delete(barrier);
   }
-#endif // _di_f_thread_condition_delete_
+#endif // _di_f_thread_barrier_delete_
 
-#ifndef _di_f_thread_condition_unblock_all_
-  f_status_t f_thread_condition_unblock_all(f_thread_condition_t *condition) {
+#ifndef _di_f_thread_barrier_wait_
+  f_status_t f_thread_barrier_wait(f_thread_barrier_t *barrier, int *result) {
     #ifndef _di_level_0_parameter_checking_
-      if (!condition) return F_status_set_error(F_parameter);
+      if (!barrier) 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);
+    if (result) {
+      *result = pthread_barrier_wait(barrier);
+    }
+    else {
+      pthread_barrier_wait(barrier);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_condition_unblock_all_
+#endif // _di_f_thread_barrier_wait_
 
-#ifndef _di_f_thread_condition_unblock_any_
-  f_status_t f_thread_condition_unblock_any(f_thread_condition_t *condition) {
+#ifndef _di_f_thread_barriers_adjust_
+  f_status_t f_thread_barriers_adjust(const f_array_length_t length, f_thread_barriers_t *barriers) {
     #ifndef _di_level_0_parameter_checking_
-      if (!condition) return F_status_set_error(F_parameter);
+      if (!barriers) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_cond_signal(condition);
+    return private_f_thread_barriers_adjust(length, barriers);
+  }
+#endif // _di_f_thread_barriers_adjust_
 
-    if (error) {
-      if (error == EINVAL) return F_status_set_error(F_parameter);
+#ifndef _di_f_thread_barriers_decimate_by_
+  f_status_t f_thread_barriers_decimate_by(const f_array_length_t amount, f_thread_barriers_t *barriers) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!barriers) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
-      return F_status_set_error(F_failure);
+    if (barriers->size - amount > 0) {
+      return private_f_thread_barriers_adjust(barriers->size - amount, barriers);
     }
 
-    return F_none;
+    return private_f_thread_barriers_adjust(0, barriers);
   }
-#endif // _di_f_thread_condition_unblock_any_
+#endif // _di_f_thread_barriers_decimate_by_
 
-#ifndef _di_f_thread_condition_wait_
-  f_status_t f_thread_condition_wait(f_thread_condition_t *condition, f_thread_mutex_t *mutex) {
+#ifndef _di_f_thread_barriers_decrease_by_
+  f_status_t f_thread_barriers_decrease_by(const f_array_length_t amount, f_thread_barriers_t *barriers) {
     #ifndef _di_level_0_parameter_checking_
-      if (!condition) return F_status_set_error(F_parameter);
-      if (!mutex) return F_status_set_error(F_parameter);
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!barriers) 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);
+    if (barriers->size - amount > 0) {
+      return private_f_thread_barriers_resize(barriers->size - amount, barriers);
     }
 
-    return F_none;
+    return private_f_thread_barriers_resize(0, barriers);
   }
-#endif // _di_f_thread_condition_wait_
+#endif // _di_f_thread_barriers_decrease_by_
 
-#ifndef _di_f_thread_condition_wait_timed_
-  f_status_t f_thread_condition_wait_timed(const struct timespec *wait, f_thread_condition_t *condition, f_thread_mutex_t *mutex) {
+#ifndef _di_f_thread_barriers_increase_
+  f_status_t f_thread_barriers_increase(f_thread_barriers_t *barriers) {
     #ifndef _di_level_0_parameter_checking_
-      if (!condition) return F_status_set_error(F_parameter);
-      if (!mutex) return F_status_set_error(F_parameter);
+      if (!barriers) 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);
+    if (barriers->used + 1 > barriers->size) {
+      f_array_length_t size = barriers->used + f_memory_default_allocation_step;
 
-      return F_status_set_error(F_failure);
-    }
+      if (size > f_array_length_t_size) {
+        if (barriers->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_barriers_resize(size, barriers);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_barriers_increase_
+
+#ifndef _di_f_thread_barriers_increase_by_
+  f_status_t f_thread_barriers_increase_by(const f_array_length_t amount, f_thread_barriers_t *barriers) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!barriers) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (barriers->used + amount > barriers->size) {
+      if (barriers->used + amount > f_array_length_t_size) {
+        return F_status_set_error(F_array_too_large);
+      }
+
+      return private_f_thread_barriers_resize(barriers->used + amount, barriers);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_barriers_increase_by_
+
+#ifndef _di_f_thread_barriers_resize_
+  f_status_t f_thread_barriers_resize(const f_array_length_t length, f_thread_barriers_t *barriers) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!barriers) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_barriers_resize(length, barriers);
+  }
+#endif // _di_f_thread_barriers_resize_
+
+#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_status_t 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_status_t 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_status_t f_thread_cancel_test() {
+
+    pthread_testcancel();
+
+    return F_none;
+  }
+#endif // _di_f_thread_cancel_test_
+
+#ifndef _di_f_thread_cancel_type_set_
+  f_status_t 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_status_t 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_status_t 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_attribute_concurrency_get_
+  f_status_t f_thread_attribute_concurrency_get(int *level) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!level) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    *level = pthread_getconcurrency();
+
+    return F_none;
+  }
+#endif // _di_f_thread_attribute_concurrency_get_
+
+#ifndef _di_f_thread_attribute_concurrency_set_
+  f_status_t f_thread_attribute_concurrency_set(const int level) {
+
+    const int error = pthread_setconcurrency(level);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EAGAIN) return F_status_set_error(F_resource_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_attribute_concurrency_set_
+
+#ifndef _di_f_thread_condition_attribute_create_
+  f_status_t f_thread_condition_attribute_create(f_thread_condition_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_condattr_init(attribute);
+
+    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_condition_attribute_create_
+
+#ifndef _di_f_thread_condition_attribute_delete_
+  f_status_t f_thread_condition_attribute_delete(f_thread_condition_attribute_t *condition_attribute) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!condition_attribute) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_condition_attribute_delete(condition_attribute);
+  }
+#endif // _di_f_thread_condition_attribute_delete_
+
+#ifndef _di_f_thread_condition_attributes_adjust_
+  f_status_t f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_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_condition_attributes_adjust(length, attributes);
+  }
+#endif // _di_f_thread_condition_attributes_adjust_
+
+#ifndef _di_f_thread_condition_attributes_decimate_by_
+  f_status_t f_thread_condition_attributes_decimate_by(const f_array_length_t amount, f_thread_condition_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_condition_attributes_adjust(attributes->size - amount, attributes);
+    }
+
+    return private_f_thread_condition_attributes_adjust(0, attributes);
+  }
+#endif // _di_f_thread_condition_attributes_decimate_by_
+
+#ifndef _di_f_thread_condition_attributes_decrease_by_
+  f_status_t f_thread_condition_attributes_decrease_by(const f_array_length_t amount, f_thread_condition_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_condition_attributes_resize(attributes->size - amount, attributes);
+    }
+
+    return private_f_thread_condition_attributes_resize(0, attributes);
+  }
+#endif // _di_f_thread_condition_attributes_decrease_by_
+
+#ifndef _di_f_thread_condition_attributes_increase_
+  f_status_t f_thread_condition_attributes_increase(f_thread_condition_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_condition_attributes_resize(size, attributes);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_condition_attributes_increase_
+
+#ifndef _di_f_thread_condition_attributes_increase_by_
+  f_status_t f_thread_condition_attributes_increase_by(const f_array_length_t amount, f_thread_condition_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->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_condition_attributes_resize(attributes->used + amount, attributes);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_condition_attributes_increase_by_
+
+#ifndef _di_f_thread_condition_attributes_resize_
+  f_status_t f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_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_condition_attributes_resize(length, attributes);
+  }
+#endif // _di_f_thread_condition_attributes_resize_
+
+#ifndef _di_f_thread_condition_create_
+  f_status_t f_thread_condition_create(const f_thread_condition_attribute_t *attribute, 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_init(condition, 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);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_condition_create_
+
+#ifndef _di_f_thread_condition_delete_
+  f_status_t f_thread_condition_delete(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_
+
+    return private_f_thread_condition_delete(condition);
+  }
+#endif // _di_f_thread_condition_delete_
+
+#ifndef _di_f_thread_condition_unblock_all_
+  f_status_t 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_status_t 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_status_t 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_status_t 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_adjust_
+  f_status_t f_thread_conditions_adjust(const f_array_length_t length, 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_adjust(length, conditions);
+  }
+#endif // _di_f_thread_conditions_adjust_
+
+#ifndef _di_f_thread_conditions_decimate_by_
+  f_status_t f_thread_conditions_decimate_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_adjust(conditions->size - amount, conditions);
+    }
+
+    return private_f_thread_conditions_adjust(0, conditions);
+  }
+#endif // _di_f_thread_conditions_decimate_by_
+
+#ifndef _di_f_thread_conditions_decrease_by_
+  f_status_t 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_resize(0, conditions);
+  }
+#endif // _di_f_thread_conditions_decrease_by_
+
+#ifndef _di_f_thread_conditions_increase_
+  f_status_t 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_data_not;
+  }
+#endif // _di_f_thread_conditions_increase_
+
+#ifndef _di_f_thread_conditions_increase_by_
+  f_status_t f_thread_conditions_increase_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->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_data_not;
+  }
+#endif // _di_f_thread_conditions_increase_by_
+
+#ifndef _di_f_thread_conditions_resize_
+  f_status_t f_thread_conditions_resize(const f_array_length_t length, 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_resize(length, conditions);
+  }
+#endif // _di_f_thread_conditions_resize_
+
+#ifndef _di_f_thread_create_
+  f_status_t 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 (!id) return F_status_set_error(F_parameter);
+      if (!routine) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_create(id, attribute, routine, argument);
+
+    if (error) {
+      if (error == EAGAIN) return F_status_set_error(F_resource_not);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_create_
+
+#ifndef _di_f_thread_exit_
+  f_status_t 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_join_
+  f_status_t 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_status_t f_thread_join_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_status_t f_thread_join_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_status_t 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_delete_
+  f_status_t f_thread_key_delete(f_thread_key_t *key) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!key) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_key_delete(key);
+  }
+#endif // _di_f_thread_key_delete_
+
+#ifndef _di_f_thread_key_get_
+  f_status_t 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_status_t 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_adjust_
+  f_status_t f_thread_keys_adjust(const f_array_length_t length, 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_adjust(length, keys);
+  }
+#endif // _di_f_thread_keys_adjust_
+
+#ifndef _di_f_thread_keys_decimate_by_
+  f_status_t f_thread_keys_decimate_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_adjust(keys->size - amount, keys);
+    }
+
+    return private_f_thread_keys_adjust(0, keys);
+  }
+#endif // _di_f_thread_keys_decimate_by_
+
+#ifndef _di_f_thread_keys_decrease_by_
+  f_status_t 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_resize(0, keys);
+  }
+#endif // _di_f_thread_keys_decrease_by_
+
+#ifndef _di_f_thread_keys_increase_
+  f_status_t 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_data_not;
+  }
+#endif // _di_f_thread_keys_increase_
+
+#ifndef _di_f_thread_keys_increase_by_
+  f_status_t f_thread_keys_increase_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->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_data_not;
+  }
+#endif // _di_f_thread_keys_increase_by_
+
+#ifndef _di_f_thread_keys_resize_
+  f_status_t f_thread_keys_resize(const f_array_length_t length, 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_resize(length, keys);
+  }
+#endif // _di_f_thread_keys_resize_
+
+#ifndef _di_f_thread_lock_attribute_create_
+  f_status_t f_thread_lock_attribute_create(f_thread_lock_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_rwlockattr_init(attribute);
+
+    // @todo figure out the error codes and update accordingly.
+    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);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_lock_attribute_create_
+
+#ifndef _di_f_thread_lock_attribute_delete_
+  f_status_t f_thread_lock_attribute_delete(f_thread_lock_attribute_t *attribute) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_lock_attribute_delete(attribute);
+  }
+#endif // _di_f_thread_lock_attribute_delete_
+
+#ifndef _di_f_thread_lock_attribute_shared_get_
+  f_status_t f_thread_lock_attribute_shared_get(const f_thread_lock_attribute_t *attribute, int *shared) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!shared) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (pthread_rwlockattr_getpshared(attribute, shared)) {
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_lock_attribute_shared_get_
+
+#ifndef _di_f_thread_lock_attribute_shared_set_
+  f_status_t f_thread_lock_attribute_shared_set(const int shared, f_thread_lock_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_rwlockattr_setpshared(attribute, shared);
+
+    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_lock_attribute_shared_set_
+
+#ifndef _di_f_thread_lock_attributes_adjust_
+  f_status_t f_thread_lock_attributes_adjust(const f_array_length_t length, f_thread_lock_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_lock_attributes_adjust(length, attributes);
+  }
+#endif // _di_f_thread_lock_attributes_adjust_
+
+#ifndef _di_f_thread_lock_attributes_decimate_by_
+  f_status_t f_thread_lock_attributes_decimate_by(const f_array_length_t amount, f_thread_lock_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_lock_attributes_adjust(attributes->size - amount, attributes);
+    }
+
+    return private_f_thread_lock_attributes_adjust(0, attributes);
+  }
+#endif // _di_f_thread_lock_attributes_decimate_by_
+
+#ifndef _di_f_thread_lock_attributes_decrease_by_
+  f_status_t f_thread_lock_attributes_decrease_by(const f_array_length_t amount, f_thread_lock_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_lock_attributes_resize(attributes->size - amount, attributes);
+    }
+
+    return private_f_thread_lock_attributes_resize(0, attributes);
+  }
+#endif // _di_f_thread_lock_attributes_decrease_by_
+
+#ifndef _di_f_thread_lock_attributes_increase_
+  f_status_t f_thread_lock_attributes_increase(f_thread_lock_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_lock_attributes_resize(size, attributes);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_lock_attributes_increase_
+
+#ifndef _di_f_thread_lock_attributes_increase_by_
+  f_status_t f_thread_lock_attributes_increase_by(const f_array_length_t amount, f_thread_lock_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->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_lock_attributes_resize(attributes->used + amount, attributes);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_lock_attributes_increase_by_
+
+#ifndef _di_f_thread_lock_attributes_resize_
+  f_status_t f_thread_lock_attributes_resize(const f_array_length_t length, f_thread_lock_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_lock_attributes_resize(length, attributes);
+  }
+#endif // _di_f_thread_lock_attributes_resize_
+
+#ifndef _di_f_thread_lock_create_
+  f_status_t f_thread_lock_create(const f_thread_lock_attribute_t *attribute, 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_init(lock, attribute);
+
+    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_lock_create_
+
+#ifndef _di_f_thread_lock_delete_
+  f_status_t f_thread_lock_delete(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_
+
+    return private_f_thread_lock_delete(lock);
+  }
+#endif // _di_f_thread_lock_delete_
+
+#ifndef _di_f_thread_lock_read_
+  f_status_t f_thread_lock_read(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 == EDEADLK) return F_status_set_error(F_deadlock);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == ETIMEDOUT) return F_time;
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_lock_read_
+
+#ifndef _di_f_thread_lock_read_timed_
+  f_status_t f_thread_lock_read_timed(const struct timespec *timeout, f_thread_lock_t *lock) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!timeout) return F_status_set_error(F_parameter);
+      if (!lock) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_rwlock_timedrdlock(lock, timeout);
+
+    if (error) {
+      if (error == EDEADLK) return F_status_set_error(F_deadlock);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == ETIMEDOUT) return F_time;
+
+      return F_status_set_error(F_failure);
+    }
 
     return F_none;
   }
-#endif // _di_f_thread_condition_wait_timed_
+#endif // _di_f_thread_lock_read_timed_
 
-#ifndef _di_f_thread_conditions_adjust_
-  f_status_t f_thread_conditions_adjust(const f_array_length_t length, f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_lock_read_try_
+  f_status_t f_thread_lock_read_try(f_thread_lock_t *lock) {
     #ifndef _di_level_0_parameter_checking_
-      if (!conditions) return F_status_set_error(F_parameter);
+      if (!lock) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_thread_conditions_adjust(length, conditions);
+    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_conditions_adjust_
+#endif // _di_f_thread_lock_read_try_
 
-#ifndef _di_f_thread_conditions_decimate_by_
-  f_status_t f_thread_conditions_decimate_by(const f_array_length_t amount, f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_lock_write_
+  f_status_t f_thread_lock_write(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_wrlock(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_write_
+
+#ifndef _di_f_thread_lock_write_timed_
+  f_status_t f_thread_lock_write_timed(const struct timespec *timeout, f_thread_lock_t *lock) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!timeout) return F_status_set_error(F_parameter);
+      if (!lock) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_rwlock_timedwrlock(lock, timeout);
+
+    if (error) {
+      if (error == EDEADLK) return F_status_set_error(F_deadlock);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == ETIMEDOUT) return F_time;
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_lock_write_timed_
+
+#ifndef _di_f_thread_lock_write_try_
+  f_status_t f_thread_lock_write_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_trywrlock(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_write_try_
+
+#ifndef _di_f_thread_locks_adjust_
+  f_status_t f_thread_locks_adjust(const f_array_length_t length, 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_adjust(length, locks);
+  }
+#endif // _di_f_thread_locks_adjust_
+
+#ifndef _di_f_thread_locks_decimate_by_
+  f_status_t f_thread_locks_decimate_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 (!conditions) return F_status_set_error(F_parameter);
+      if (!locks) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (conditions->size - amount > 0) {
-      return private_f_thread_conditions_adjust(conditions->size - amount, conditions);
+    if (locks->size - amount > 0) {
+      return private_f_thread_locks_adjust(locks->size - amount, locks);
     }
 
-    return private_f_thread_conditions_adjust(0, conditions);
+    return private_f_thread_locks_adjust(0, locks);
   }
-#endif // _di_f_thread_conditions_decimate_by_
+#endif // _di_f_thread_locks_decimate_by_
 
-#ifndef _di_f_thread_conditions_decrease_by_
-  f_status_t f_thread_conditions_decrease_by(const f_array_length_t amount, f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_locks_decrease_by_
+  f_status_t 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 (!conditions) return F_status_set_error(F_parameter);
+      if (!locks) 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);
+    if (locks->size - amount > 0) {
+      return private_f_thread_locks_resize(locks->size - amount, locks);
     }
 
-    return private_f_thread_conditions_resize(0, conditions);
+    return private_f_thread_locks_resize(0, locks);
   }
-#endif // _di_f_thread_conditions_decrease_by_
+#endif // _di_f_thread_locks_decrease_by_
 
-#ifndef _di_f_thread_conditions_increase_
-  f_status_t f_thread_conditions_increase(f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_locks_increase_
+  f_status_t f_thread_locks_increase(f_thread_locks_t *locks) {
     #ifndef _di_level_0_parameter_checking_
-      if (!conditions) return F_status_set_error(F_parameter);
+      if (!locks) 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 (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 (conditions->used + 1 > 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_conditions_resize(size, conditions);
+      return private_f_thread_locks_resize(size, locks);
     }
 
     return F_data_not;
   }
-#endif // _di_f_thread_conditions_increase_
+#endif // _di_f_thread_locks_increase_
 
-#ifndef _di_f_thread_conditions_increase_by_
-  f_status_t f_thread_conditions_increase_by(const f_array_length_t amount, f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_locks_increase_by_
+  f_status_t f_thread_locks_increase_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 (!conditions) return F_status_set_error(F_parameter);
+      if (!locks) 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) {
+    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_conditions_resize(conditions->used + amount, conditions);
+      return private_f_thread_locks_resize(locks->used + amount, locks);
     }
 
     return F_data_not;
   }
-#endif // _di_f_thread_conditions_increase_by_
+#endif // _di_f_thread_locks_increase_by_
 
-#ifndef _di_f_thread_conditions_resize_
-  f_status_t f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions) {
+#ifndef _di_f_thread_locks_resize_
+  f_status_t f_thread_locks_resize(const f_array_length_t length, f_thread_locks_t *locks) {
     #ifndef _di_level_0_parameter_checking_
-      if (!conditions) return F_status_set_error(F_parameter);
+      if (!locks) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_thread_conditions_resize(length, conditions);
+    return private_f_thread_locks_resize(length, locks);
   }
-#endif // _di_f_thread_conditions_resize_
+#endif // _di_f_thread_locks_resize_
 
-#ifndef _di_f_thread_create_
-  f_status_t f_thread_create(const f_thread_attribute_t *attribute, f_thread_id_t *id, void *(*routine) (void *), void *argument) {
+#ifndef _di_f_thread_mutex_attribute_create_
+  f_status_t f_thread_mutex_attribute_create(f_thread_mutex_attribute_t *attribute) {
     #ifndef _di_level_0_parameter_checking_
-      if (!id) return F_status_set_error(F_parameter);
-      if (!routine) return F_status_set_error(F_parameter);
+      if (!attribute) 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_mutexattr_init(attribute);
 
+    // @todo figure out the error codes and update accordingly.
     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);
@@ -900,116 +1962,112 @@ extern "C" {
 
     return F_none;
   }
-#endif // _di_f_thread_create_
+#endif // _di_f_thread_mutex_attribute_create_
 
-#ifndef _di_f_thread_exit_
-  f_status_t f_thread_exit(int *result) {
+#ifndef _di_f_thread_mutex_attribute_delete_
+  f_status_t f_thread_mutex_attribute_delete(f_thread_mutex_attribute_t *attribute) {
     #ifndef _di_level_0_parameter_checking_
-      if (!result) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    pthread_exit(result);
-
-    return F_none;
+    return private_f_thread_mutex_attribute_delete(attribute);
   }
-#endif // _di_f_thread_exit_
+#endif // _di_f_thread_mutex_attribute_delete_
 
-#ifndef _di_f_thread_join_
-  f_status_t f_thread_join(const f_thread_id_t id, void **result) {
+#ifndef _di_f_thread_mutex_attribute_priority_ceiling_get_
+  f_status_t f_thread_mutex_attribute_priority_ceiling_get(const f_thread_mutex_attribute_t *attribute, int *ceiling) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!ceiling) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_join(id, result);
+    const int error = pthread_mutexattr_getprioceiling(attribute, ceiling);
 
     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);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_join_
+#endif // _di_f_thread_mutex_attribute_priority_ceiling_get_
 
-#ifndef _di_f_thread_join_try_
-  f_status_t f_thread_join_try(const f_thread_id_t id, void **result) {
+#ifndef _di_f_thread_mutex_attribute_priority_ceiling_set_
+  f_status_t f_thread_mutex_attribute_priority_ceiling_set(const int ceiling, f_thread_mutex_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_tryjoin_np(id, result);
+    const int error = pthread_mutexattr_setprioceiling(attribute, ceiling);
 
     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 == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_join_try_
-
-#ifndef _di_f_thread_join_timed_
-  f_status_t f_thread_join_timed(const f_thread_id_t id, const struct timespec wait, void **result) {
-
-    const int error = pthread_timedjoin_np(id, result, &wait);
+#endif // _di_f_thread_mutex_attribute_priority_ceiling_set_
 
-    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;
+#ifndef _di_f_thread_mutex_attribute_shared_get_
+  f_status_t f_thread_mutex_attribute_shared_get(const f_thread_mutex_attribute_t *attribute, int *shared) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!shared) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
+    if (pthread_mutexattr_getpshared(attribute, shared)) {
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_join_timed_
+#endif // _di_f_thread_mutex_attribute_shared_get_
 
-#ifndef _di_f_thread_key_create_
-  f_status_t f_thread_key_create(void (*routine) (void *), f_thread_key_t *key) {
+#ifndef _di_f_thread_mutex_attribute_shared_set_
+  f_status_t f_thread_mutex_attribute_shared_set(const int shared, f_thread_mutex_attribute_t *attribute) {
     #ifndef _di_level_0_parameter_checking_
-      if (!routine) return F_status_set_error(F_parameter);
-      if (!key) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_key_create(key, routine);
+    const int error = pthread_mutexattr_setpshared(attribute, shared);
 
     if (error) {
-      if (error == EAGAIN) return F_status_set_error(F_resource_not);
-      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_key_create_
+#endif // _di_f_thread_mutex_attribute_shared_set_
 
-#ifndef _di_f_thread_key_get_
-  f_status_t f_thread_key_get(const f_thread_key_t key, void **value) {
+#ifndef _di_f_thread_mutex_attribute_type_get_
+  f_status_t f_thread_mutex_attribute_type_get(const f_thread_mutex_attribute_t *attribute, int *type) {
     #ifndef _di_level_0_parameter_checking_
-      if (!value) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!type) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    *value = pthread_getspecific(key);
+    if (pthread_mutexattr_gettype(attribute, type)) {
+      return F_status_set_error(F_failure);
+    }
 
     return F_none;
   }
-#endif // _di_f_thread_key_get_
+#endif // _di_f_thread_mutex_attribute_type_get_
 
-#ifndef _di_f_thread_key_set_
-  f_status_t f_thread_key_set(const f_thread_key_t key, const void *value) {
+#ifndef _di_f_thread_mutex_attribute_type_set_
+  f_status_t f_thread_mutex_attribute_type_set(const int type, f_thread_mutex_attribute_t *attribute) {
     #ifndef _di_level_0_parameter_checking_
-      if (!value) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_setspecific(key, value);
+    const int error = pthread_mutexattr_settype(attribute, type);
 
     if (error) {
       if (error == EINVAL) return F_status_set_error(F_parameter);
@@ -1019,47 +2077,47 @@ extern "C" {
 
     return F_none;
   }
-#endif // _di_f_thread_key_set_
+#endif // _di_f_thread_mutex_attribute_type_set_
 
-#ifndef _di_f_thread_lock_
-  f_status_t f_thread_lock(f_thread_lock_t *lock) {
+#ifndef _di_f_thread_mutex_attribute_protocol_get_
+  f_status_t f_thread_mutex_attribute_protocol_get(const f_thread_mutex_attribute_t *attribute, int *protocol) {
     #ifndef _di_level_0_parameter_checking_
-      if (!lock) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
+      if (!protocol) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_rwlock_rdlock(lock);
+    const int error = pthread_mutexattr_getprotocol(attribute, protocol);
 
     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);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_lock_
+#endif // _di_f_thread_mutex_attribute_protocol_get_
 
-#ifndef _di_f_thread_lock_try_
-  f_status_t f_thread_lock_try(f_thread_lock_t *lock) {
+#ifndef _di_f_thread_mutex_attribute_protocol_set_
+  f_status_t f_thread_mutex_attribute_protocol_set(const int protocol, f_thread_mutex_attribute_t *attribute) {
     #ifndef _di_level_0_parameter_checking_
-      if (!lock) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_rwlock_tryrdlock(lock);
+    const int error = pthread_mutexattr_setprotocol(attribute, protocol);
 
     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);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
+      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_lock_try_
+#endif // _di_f_thread_mutex_attribute_protocol_set_
 
 #ifndef _di_f_thread_mutex_attributes_adjust_
   f_status_t f_thread_mutex_attributes_adjust(const f_array_length_t length, f_thread_mutex_attributes_t *attributes) {
@@ -1072,67 +2130,34 @@ extern "C" {
 #endif // _di_f_thread_mutex_attributes_adjust_
 
 #ifndef _di_f_thread_mutex_attributes_decimate_by_
-  f_status_t f_thread_mutex_attributes_decimate_by(const f_array_length_t amount, f_thread_mutex_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_mutex_attributes_adjust(attributes->size - amount, attributes);
-    }
-
-    return private_f_thread_mutex_attributes_adjust(0, attributes);
-  }
-#endif // _di_f_thread_mutex_attributes_decimate_by_
-
-#ifndef _di_f_thread_mutex_attributes_decrease_by_
-  f_status_t f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_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_mutex_attributes_resize(attributes->size - amount, attributes);
-    }
-
-    return private_f_thread_mutex_attributes_resize(0, attributes);
-  }
-#endif // _di_f_thread_mutex_attributes_decrease_by_
-
-#ifndef _di_f_thread_mutex_attribute_create_
-  f_status_t f_thread_mutex_attribute_create(f_thread_mutex_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_mutexattr_init(attribute);
-
-    // @todo figure out the error codes and update accordingly.
-    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);
+  f_status_t f_thread_mutex_attributes_decimate_by(const f_array_length_t amount, f_thread_mutex_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_
 
-      return F_status_set_error(F_failure);
+    if (attributes->size - amount > 0) {
+      return private_f_thread_mutex_attributes_adjust(attributes->size - amount, attributes);
     }
 
-    return F_none;
+    return private_f_thread_mutex_attributes_adjust(0, attributes);
   }
-#endif // _di_f_thread_mutex_attribute_create_
+#endif // _di_f_thread_mutex_attributes_decimate_by_
 
-#ifndef _di_f_thread_mutex_attribute_delete_
-  f_status_t f_thread_mutex_attribute_delete(f_thread_mutex_attribute_t *attribute) {
+#ifndef _di_f_thread_mutex_attributes_decrease_by_
+  f_status_t f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_attributes_t *attributes) {
     #ifndef _di_level_0_parameter_checking_
-      if (!attribute) return F_status_set_error(F_parameter);
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!attributes) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_thread_mutex_attribute_delete(attribute);
+    if (attributes->size - amount > 0) {
+      return private_f_thread_mutex_attributes_resize(attributes->size - amount, attributes);
+    }
+
+    return private_f_thread_mutex_attributes_resize(0, attributes);
   }
-#endif // _di_f_thread_mutex_attribute_delete_
+#endif // _di_f_thread_mutex_attributes_decrease_by_
 
 #ifndef _di_f_thread_mutex_attributes_increase_
   f_status_t f_thread_mutex_attributes_increase(f_thread_mutex_attributes_t *attributes) {
@@ -1239,6 +2264,30 @@ extern "C" {
   }
 #endif // _di_f_thread_mutex_lock_
 
+#ifndef _di_f_thread_mutex_lock_timed_
+  f_status_t f_thread_mutex_lock_timed(const struct timespec *timeout, f_thread_mutex_t *mutex) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!timeout) 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_mutex_timedlock(mutex, timeout);
+
+    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);
+      if (error == ENOTRECOVERABLE) return F_status_set_error(F_recover_not);
+      if (error == EOWNERDEAD) return F_status_set_error(F_thread_not);
+      if (error == ETIMEDOUT) return F_time;
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_thread_mutex_lock_timed_
+
 #ifndef _di_f_thread_mutex_lock_try_
   f_status_t f_thread_mutex_lock_try(f_thread_mutex_t *mutex) {
     #ifndef _di_level_0_parameter_checking_
@@ -1259,6 +2308,49 @@ extern "C" {
   }
 #endif // _di_f_thread_mutex_lock_try_
 
+#ifndef _di_f_thread_mutex_priority_ceiling_get_
+  f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t *mutex, int *ceiling) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!mutex) return F_status_set_error(F_parameter);
+      if (!ceiling) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_mutex_getprioceiling(mutex, ceiling);
+
+    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_mutex_priority_ceiling_get_
+
+#ifndef _di_f_thread_mutex_priority_ceiling_set_
+  f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t *mutex, int *previous) {
+    #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_setprioceiling(mutex, ceiling, previous);
+
+    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);
+      if (error == ENOTRECOVERABLE) return F_status_set_error(F_recover_not);
+      if (error == EOWNERDEAD) return F_status_set_error(F_thread_not);
+      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_priority_ceiling_set_
+
 #ifndef _di_f_thread_mutex_unlock_
   f_status_t f_thread_mutex_unlock(f_thread_mutex_t *mutex) {
     #ifndef _di_level_0_parameter_checking_
@@ -1392,6 +2484,62 @@ extern "C" {
   }
 #endif // _di_f_thread_once_
 
+#ifndef _di_f_thread_scheduler_parameter_get_
+  f_status_t f_thread_scheduler_parameter_get(const f_thread_id_t id, int *policy, struct sched_param *parameter) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!policy) return F_status_set_error(F_parameter);
+      if (!parameter) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_getschedparam(id, policy, parameter);
+
+    if (error) {
+      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_scheduler_parameter_get_
+
+#ifndef _di_f_thread_scheduler_parameter_set_
+  f_status_t f_thread_scheduler_parameter_set(const f_thread_id_t id, const int policy, const struct sched_param *parameter) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!policy) return F_status_set_error(F_parameter);
+      if (!parameter) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_setschedparam(id, policy, parameter);
+
+    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_scheduler_parameter_set_
+
+#ifndef _di_f_thread_scheduler_priority_set_
+  f_status_t f_thread_scheduler_priority_set(const f_thread_id_t id, const int priority) {
+
+    const int error = pthread_setschedprio(id, priority);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
+      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_scheduler_priority_set_
+
 #ifndef _di_f_thread_sets_adjust_
   f_status_t f_thread_sets_adjust(const f_array_length_t length, f_thread_sets_t *sets) {
     #ifndef _di_level_0_parameter_checking_
@@ -1545,6 +2693,210 @@ extern "C" {
   }
 #endif // _di_f_thread_signal_queue_
 
+#ifndef _di_f_thread_spin_create_
+  f_status_t f_thread_spin_create(const int shared, f_thread_spin_t *spin) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spin) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_spin_init(spin, shared);
+
+    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_spin_create_
+
+#ifndef _di_f_thread_spin_delete_
+  f_status_t f_thread_spin_delete(f_thread_spin_t *spin) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spin) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_spin_delete(spin);
+  }
+#endif // _di_f_thread_spin_delete_
+
+#ifndef _di_f_thread_spin_lock_
+  f_status_t f_thread_spin_lock(f_thread_spin_t *spin) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spin) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_spin_lock(spin);
+
+    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_spin_lock_
+
+#ifndef _di_f_thread_spin_lock_try_
+  f_status_t f_thread_spin_lock_try(f_thread_spin_t *spin) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spin) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_spin_trylock(spin);
+
+    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_spin_lock_try_
+
+#ifndef _di_f_thread_spin_unlock_
+  f_status_t f_thread_spin_unlock(f_thread_spin_t *spin) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spin) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int error = pthread_spin_unlock(spin);
+
+    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_spin_unlock_
+
+#ifndef _di_f_thread_spins_adjust_
+  f_status_t f_thread_spins_adjust(const f_array_length_t length, f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_spins_adjust(length, spins);
+  }
+#endif // _di_f_thread_spins_adjust_
+
+#ifndef _di_f_thread_spins_decimate_by_
+  f_status_t f_thread_spins_decimate_by(const f_array_length_t amount, f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (spins->size - amount > 0) {
+      return private_f_thread_spins_adjust(spins->size - amount, spins);
+    }
+
+    return private_f_thread_spins_adjust(0, spins);
+  }
+#endif // _di_f_thread_spins_decimate_by_
+
+#ifndef _di_f_thread_spins_decrease_by_
+  f_status_t f_thread_spins_decrease_by(const f_array_length_t amount, f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (spins->size - amount > 0) {
+      return private_f_thread_spins_resize(spins->size - amount, spins);
+    }
+
+    return private_f_thread_spins_resize(0, spins);
+  }
+#endif // _di_f_thread_spins_decrease_by_
+
+#ifndef _di_f_thread_spins_increase_
+  f_status_t f_thread_spins_increase(f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (spins->used + 1 > spins->size) {
+      f_array_length_t size = spins->used + f_memory_default_allocation_step;
+
+      if (size > f_array_length_t_size) {
+        if (spins->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_spins_resize(size, spins);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_spins_increase_
+
+#ifndef _di_f_thread_spins_increase_by_
+  f_status_t f_thread_spins_increase_by(const f_array_length_t amount, f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!amount) return F_status_set_error(F_parameter);
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (spins->used + amount > spins->size) {
+      if (spins->used + amount > f_array_length_t_size) {
+        return F_status_set_error(F_array_too_large);
+      }
+
+      return private_f_thread_spins_resize(spins->used + amount, spins);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_thread_spins_increase_by_
+
+#ifndef _di_f_thread_spins_resize_
+  f_status_t f_thread_spins_resize(const f_array_length_t length, f_thread_spins_t *spins) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!spins) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_thread_spins_resize(length, spins);
+  }
+#endif // _di_f_thread_spins_resize_
+
+#ifndef _di_f_thread_unlock_
+  f_status_t f_thread_unlock(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_unlock(lock);
+
+    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_unlock_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 35a9c0656043c5a38a5d8ff7e8ce6d7c62c1b143..51239a13084e03e133c2a00a6b5ab17f72575fae 100644 (file)
 #ifndef _F_thread_h
 #define _F_thread_h
 
-// @todo pthread_attr_getstackaddr()
-// @todo pthread_attr_getstacksize()
-// @todo pthread_attr_setstackaddr()
-// @todo pthread_attr_setstacksize()
-// @todo pthread_barrier_destroy
-// @todo pthread_barrier_init
-// @todo pthread_barrier_wait
-// @todo pthread_barrierattr_destroy
-// @todo pthread_barrierattr_getpshared
-// @todo pthread_barrierattr_init
-// @todo pthread_barrierattr_setpshared
-// @todo pthread_condattr_getclock
-// @todo pthread_condattr_getpshared
-// @todo pthread_condattr_setclock
-// @todo pthread_condattr_setpshared
-// @todo pthread_getconcurrency
-// @todo pthread_getschedparam
-// @todo pthread_key_delete
-// @todo pthread_mutex_getprioceiling
-// @todo pthread_mutex_setprioceiling
-// @todo pthread_mutex_timedlock
-// @todo pthread_mutexattr_getprioceiling
-// @todo pthread_mutexattr_getprotocol
-// @todo pthread_mutexattr_getpshared
-// @todo pthread_mutexattr_gettype
-// @todo pthread_mutexattr_setprioceiling
-// @todo pthread_mutexattr_setprotocol
-// @todo pthread_mutexattr_setpshared
-// @todo pthread_mutexattr_settype
-// @todo pthread_rwlock_destroy
-// @todo pthread_rwlock_init
-// @todo pthread_rwlock_timedrdlock
-// @todo pthread_rwlock_timedwrlock
-// @todo pthread_rwlock_trywrlock
-// @todo pthread_rwlock_unlock
-// @todo pthread_rwlock_wrlock
-// @todo pthread_rwlockattr_destroy
-// @todo pthread_rwlockattr_getpshared
-// @todo pthread_rwlockattr_init
-// @todo pthread_rwlockattr_setpshared
-
 // include pre-requirements
 #define _GNU_SOURCE
 
@@ -142,6 +101,86 @@ extern "C" {
 #endif // _di_f_thread_attribute_affinity_set_
 
 /**
+ * Get the clock selection thread condition attribute.
+ *
+ * @param attribute
+ *   The thread condition attribute.
+ * @param id
+ *   The clock ID.
+ *
+ * @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_condattr_getclock()
+ */
+#ifndef _di_f_thread_attribute_clock_get_
+  extern f_status_t f_thread_attribute_clock_get(const f_thread_condition_attribute_t *attribute, clockid_t *id);
+#endif // _di_f_thread_attribute_clock_get_
+
+/**
+ * Set the clock selection thread condition attribute.
+ *
+ * @param id
+ *   The clock ID.
+ * @param attribute
+ *   The thread condition attribute.
+ *
+ * @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_condattr_setclock()
+ */
+#ifndef _di_f_thread_attribute_clock_set_
+  extern f_status_t f_thread_attribute_clock_set(const clockid_t id, f_thread_condition_attribute_t *attribute);
+#endif // _di_f_thread_attribute_clock_set_
+
+/**
+ * Get the process shared thread condition attribute.
+ *
+ * @param attribute
+ *   The thread condition attribute.
+ * @param shared
+ *   The process shared attribute value.
+ *
+ * @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_condattr_getpshared()
+ */
+#ifndef _di_f_thread_attribute_condition_shared_get_
+  extern f_status_t f_thread_attribute_condition_shared_get(const f_thread_condition_attribute_t *attribute, int *shared);
+#endif // _di_f_thread_attribute_condition_shared_get_
+
+/**
+ * Set the process shared thread condition attribute.
+ *
+ * @param shared
+ *   The process shared attribute value.
+ * @param attribute
+ *   The thread condition attribute.
+ *
+ * @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_condattr_setpshared()
+ */
+#ifndef _di_f_thread_attribute_condition_shared_set_
+  extern f_status_t f_thread_attribute_condition_shared_set(const int shared, f_thread_condition_attribute_t *attribute);
+#endif // _di_f_thread_attribute_condition_shared_set_
+
+/**
  * Create (initialize) a thread attribute structure.
  *
  * @param attribute
@@ -489,7 +528,7 @@ extern "C" {
  * Set the stack of the thread attribute.
  *
  * @param stack_size
- *   The size of the stack_set.
+ *   The size of the stack.
  * @param stack
  *   The stack to assign.
  * @param attribute
@@ -509,7 +548,47 @@ extern "C" {
 #endif // _di_f_thread_attribute_stack_set_
 
 /**
- * Resize the string attributes array.
+ * Get the stack size of the thread attribute.
+ *
+ * @param attribute
+ *   The thread attributes to process.
+ * @param stack_size
+ *   The assigned size of the stack.
+ *
+ * @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_getstacksize()
+ */
+#ifndef _di_f_thread_attribute_stack_size_get_
+  extern f_status_t f_thread_attribute_stack_size_get(const f_thread_attribute_t attribute, size_t *stack_size);
+#endif // _di_f_thread_attribute_stack_size_get_
+
+/**
+ * Set the stack size of the thread attribute.
+ *
+ * @param stack_size
+ *   The size of the stack.
+ * @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_setstacksize()
+ */
+#ifndef _di_f_thread_attribute_stack_size_set_
+  extern f_status_t f_thread_attribute_stack_size_set(const size_t stack_size, f_thread_attribute_t *attribute);
+#endif // _di_f_thread_attribute_stack_size_set_
+
+/**
+ * Resize the thread attributes array.
  *
  * @param length
  *   The new size to use.
@@ -527,7 +606,7 @@ extern "C" {
 #endif // _di_f_thread_attributes_adjust_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread 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.
@@ -549,7 +628,7 @@ extern "C" {
 #endif // _di_f_thread_attributes_decimate_by_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread 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.
@@ -571,7 +650,7 @@ extern "C" {
 #endif // _di_f_thread_attributes_decrease_by_
 
 /**
- * Increase the size of the string attributes array, but only if necessary.
+ * Increase the size of the thread 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.
@@ -592,9 +671,9 @@ extern "C" {
 #endif // _di_f_thread_attributes_increase_
 
 /**
- * Resize the string attributes array to a larger size.
+ * Resize the thread attributes array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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.
  *
@@ -616,7 +695,7 @@ extern "C" {
 #endif // _di_f_thread_attributes_increase_by_
 
 /**
- * Resize the string attributes array.
+ * Resize the thread attributes array.
  *
  * @param length
  *   The new size to use.
@@ -634,81 +713,35 @@ extern "C" {
 #endif // _di_f_thread_attributes_resize_
 
 /**
- * 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_status_t f_thread_cancel(const f_thread_id_t id);
-#endif // _di_f_thread_cancel_
-
-/**
- * Assign a cancellation state.
+ * Create (initialize) a thread barrier attribute structure.
  *
- * @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.)
+ * @param attribute
+ *   (optional) The attribute to set.
+ *   Set to NULL to not use (in which case the default attribute is used).
  *
  * @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_setcancelstate()
+ * @see pthread_barrierattr_init()
  */
-#ifndef _di_f_thread_cancel_state_set_
-  extern f_status_t f_thread_cancel_state_set(const int state, int *previous);
-#endif // _di_f_thread_cancel_state_set_
+#ifndef _di_f_thread_barrier_attribute_create_
+  extern f_status_t f_thread_barrier_attribute_create(f_thread_barrier_attribute_t *attribute);
+#endif // _di_f_thread_barrier_attribute_create_
 
 /**
- * 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.
+ * Delete a thread barrier attribute structure.
  *
- * @return
- *   F_none on success.
+ * On successfully delete, the pointer address is set to 0.
  *
- * @see pthread_testcancel()
- */
-#ifndef _di_f_thread_cancel_test_
-  extern f_status_t f_thread_cancel_test();
-#endif // _di_f_thread_cancel_test_
-
-/**
- * Assign a cancellation type.
+ * The pthread_barrierattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
  *
- * @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.)
+ * @param attribute
+ *   The thread barrier_attributes to delete.
  *
  * @return
  *   F_none on success.
@@ -716,55 +749,19 @@ extern "C" {
  *   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_status_t 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_getcpuclockid()
- */
-#ifndef _di_f_thread_clock_get_id_
-  extern f_status_t 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()
+ * @see pthread_barrierattr_destroy()
  */
-#ifndef _di_f_thread_compare_
-  extern f_status_t f_thread_compare(const f_thread_id_t id1, const f_thread_id_t id2);
-#endif // _di_f_thread_compare_
+#ifndef _di_f_thread_barrier_attribute_delete_
+  extern f_status_t f_thread_barrier_attribute_delete(f_thread_barrier_attribute_t *attribute);
+#endif // _di_f_thread_barrier_attribute_delete_
 
 /**
- * Initialize a attribute.
+ * Get the barrier process shared thread attribute.
  *
  * @param attribute
- *   The attribute to set.
- *   This assigns the default to the attribute.
+ *   The barrier thread attribute.
+ * @param shared
+ *   The process shared attribute value.
  *
  * @return
  *   F_none on success.
@@ -772,41 +769,39 @@ extern "C" {
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_condattr_init()
+ * @see pthread_barrierattr_getpshared()
  */
-#ifndef _di_f_thread_condition_attribute_create_
-  extern f_status_t f_thread_condition_attribute_create(f_thread_condition_attribute_t *attribute);
-#endif // _di_f_thread_condition_attribute_create_
+#ifndef _di_f_thread_barrier_attribute_shared_get_
+  extern f_status_t f_thread_barrier_attribute_shared_get(const f_thread_barrier_attribute_t *attribute, int *shared);
+#endif // _di_f_thread_barrier_attribute_shared_get_
 
 /**
- * Delete a thread attribute.
- *
- * The pthread_condattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
- * Therefore there is only this function for both deleting and destroying.
+ * Set the barrier process shared thread attribute.
  *
+ * @param shared
+ *   The process shared attribute value.
  * @param attribute
- *   The attribute to delete.
+ *   The barrier thread attribute.
  *
  * @return
  *   F_none on success.
  *
- *   F_busy (with error bit) if the attribute is busy.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_condattr_destroy()
+ * @see pthread_barrierattr_setpshared()
  */
-#ifndef _di_f_thread_condition_attribute_delete_
-  extern f_status_t f_thread_condition_attribute_delete(f_thread_condition_attribute_t *attribute);
-#endif // _di_f_thread_condition_attribute_delete_
+#ifndef _di_f_thread_barrier_attribute_shared_set_
+  extern f_status_t f_thread_barrier_attribute_shared_set(const int shared, f_thread_barrier_attribute_t *attribute);
+#endif // _di_f_thread_barrier_attribute_shared_set_
 
 /**
- * Resize the string attributes array.
+ * Resize the thread barrier attributes array.
  *
  * @param length
  *   The new size to use.
  * @param attributes
- *   The string attributes array to resize.
+ *   The thread attributes array to resize.
  *
  * @return
  *   F_none on success.
@@ -814,12 +809,12 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_condition_attributes_adjust_
-  extern f_status_t f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_adjust_
+#ifndef _di_f_thread_barrier_attributes_adjust_
+  extern f_status_t f_thread_barrier_attributes_adjust(const f_array_length_t length, f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_adjust_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread barrier 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.
@@ -828,7 +823,7 @@ extern "C" {
  * @param amount
  *   A positive number representing how much to decimate the size by.
  * @param attributes
- *   The string attributes array to resize.
+ *   The thread attributes array to resize.
  *
  * @return
  *   F_none on success.
@@ -836,12 +831,12 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_condition_attributes_decimate_by_
-  extern f_status_t f_thread_condition_attributes_decimate_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_decimate_by_
+#ifndef _di_f_thread_barrier_attributes_decimate_by_
+  extern f_status_t f_thread_barrier_attributes_decimate_by(const f_array_length_t amount, f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_decimate_by_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread barrier 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.
@@ -850,7 +845,7 @@ extern "C" {
  * @param amount
  *   A positive number representing how much to decrease the size by.
  * @param attributes
- *   The string attributes array to resize.
+ *   The thread attributes array to resize.
  *
  * @return
  *   F_none on success.
@@ -858,18 +853,18 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_condition_attributes_decrease_by_
-  extern f_status_t f_thread_condition_attributes_decrease_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_decrease_by_
+#ifndef _di_f_thread_barrier_attributes_decrease_by_
+  extern f_status_t f_thread_barrier_attributes_decrease_by(const f_array_length_t amount, f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_decrease_by_
 
 /**
- * Increase the size of the string attributes array, but only if necessary.
+ * Increase the size of the thread barrier 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 attributes array to resize.
+ *   The thread attributes array to resize.
  *
  * @return
  *   F_none on success.
@@ -879,21 +874,21 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_condition_attributes_increase_
-  extern f_status_t f_thread_condition_attributes_increase(f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_increase_
+#ifndef _di_f_thread_barrier_attributes_increase_
+  extern f_status_t f_thread_barrier_attributes_increase(f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_increase_
 
 /**
- * Resize the string attributes array to a larger size.
+ * Resize the thread barrier attributes array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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 attributes array to resize.
+ *   The thread attributes array to resize.
  *
  * @return
  *   F_none on success.
@@ -903,17 +898,17 @@ extern "C" {
  *   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_condition_attributes_increase_by_
-  extern f_status_t f_thread_condition_attributes_increase_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_increase_by_
+#ifndef _di_f_thread_barrier_attributes_increase_by_
+  extern f_status_t f_thread_barrier_attributes_increase_by(const f_array_length_t amount, f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_increase_by_
 
 /**
- * Resize the string attributes array.
+ * Resize the thread barrier attributes array.
  *
  * @param length
  *   The new size to use.
  * @param attributes
- *   The string attributes array to adjust.
+ *   The thread attributes array to adjust.
  *
  * @return
  *   F_none on success.
@@ -921,76 +916,1205 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_condition_attributes_resize_
-  extern f_status_t f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_attributes_t *attributes);
-#endif // _di_f_thread_condition_attributes_resize_
+#ifndef _di_f_thread_barrier_attributes_resize_
+  extern f_status_t f_thread_barrier_attributes_resize(const f_array_length_t length, f_thread_barrier_attributes_t *attributes);
+#endif // _di_f_thread_barrier_attributes_resize_
 
 /**
- * Initialize a condition.
+ * Create (initialize) a thread barrier structure.
  *
- * @param attribute
- *   (optional) The attribute to set.
- *   Set to NULL to not use (in which case the default attribute is used).
- * @param condition
- *   The condition to wait on.
+ * @param barrier
+ *   (optional) The barrier to set.
+ *   Set to NULL to not use (in which case the default barrier is used).
  *
  * @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_cond_init()
+ * @see pthread_barrier_init()
  */
-#ifndef _di_f_thread_condition_create_
-  extern f_status_t f_thread_condition_create(const f_thread_condition_attribute_t *attribute, f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_create_
+#ifndef _di_f_thread_barrier_create_
+  extern f_status_t f_thread_barrier_create(const unsigned int count, f_thread_barrier_attribute_t * const attribute, f_thread_barrier_t *barrier);
+#endif // _di_f_thread_barrier_create_
 
 /**
- * Delete a thread condition.
+ * Delete a thread barrier structure.
  *
- * The pthread_cond_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * On successfully delete, the pointer address is set to 0.
+ *
+ * The pthread_barrier_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
  * Therefore there is only this function for both deleting and destroying.
  *
- * @param condition
- *   The condition to delete.
+ * @param barrier
+ *   The thread barriers to delete.
  *
  * @return
  *   F_none on success.
  *
- *   F_busy (with error bit) if the condition is busy.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_cond_destroy()
+ * @see pthread_barrier_destroy()
  */
-#ifndef _di_f_thread_condition_delete_
-  extern f_status_t f_thread_condition_delete(f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_delete_
+#ifndef _di_f_thread_barrier_delete_
+  extern f_status_t f_thread_barrier_delete(f_thread_barrier_t *barrier);
+#endif // _di_f_thread_barrier_delete_
 
 /**
- * Unblock all threads waiting on a condition.
+ * Wait on a barrier, effectively synchronizing multiple threads with some barrier.
  *
- * @param condition
- *   The condition to broadcast the unblock signal to.
+ * @param barrier
+ *   The barrier to wait on.
+ * @param result
+ *   (optional) the return value, which will be PTHREAD_BARRIER_SERIAL_THREAD for one thread and 0 for others.
+ *   Set to NULL to not use.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see pthread_barrier_wait()
+ */
+#ifndef _di_f_thread_barrier_wait_
+  extern f_status_t f_thread_barrier_wait(f_thread_barrier_t *barrier, int *result);
+#endif // _di_f_thread_barrier_wait_
+
+/**
+ * Resize the thread barriers array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param barriers
+ *   The thread barriers array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_barriers_adjust_
+  extern f_status_t f_thread_barriers_adjust(const f_array_length_t length, f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_adjust_
+
+/**
+ * Resize the thread barriers 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 decimate the size by.
+ * @param barriers
+ *   The thread barriers array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_barriers_decimate_by_
+  extern f_status_t f_thread_barriers_decimate_by(const f_array_length_t amount, f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_decimate_by_
+
+/**
+ * Resize the thread barriers 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 barriers
+ *   The thread barriers array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_barriers_decrease_by_
+  extern f_status_t f_thread_barriers_decrease_by(const f_array_length_t amount, f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_decrease_by_
+
+/**
+ * Increase the size of the thread barriers 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 barriers
+ *   The thread barriers array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_barriers_increase_
+  extern f_status_t f_thread_barriers_increase(f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_increase_
+
+/**
+ * Resize the thread barriers 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 barriers
+ *   The thread barriers array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_barriers_increase_by_
+  extern f_status_t f_thread_barriers_increase_by(const f_array_length_t amount, f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_increase_by_
+
+/**
+ * Resize the thread barriers array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param barriers
+ *   The thread barriers array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_barriers_resize_
+  extern f_status_t f_thread_barriers_resize(const f_array_length_t length, f_thread_barriers_t *barriers);
+#endif // _di_f_thread_barriers_resize_
+
+/**
+ * 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_status_t 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_status_t 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_status_t 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_status_t 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_getcpuclockid()
+ */
+#ifndef _di_f_thread_clock_get_id_
+  extern f_status_t 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_status_t f_thread_compare(const f_thread_id_t id1, const f_thread_id_t id2);
+#endif // _di_f_thread_compare_
+
+/**
+ * Get the level of concurrency.
+ *
+ * A level of 0 designates the system to automatically choose concurrency level.
+ * Any non-zero level is considered a hint and will be followed at the systems discretion.
+ *
+ * @param level
+ *   The concurrency level.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_resource_not (with error bit) if the new level would cause the system to exceed available resources.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_getconcurrency()
+ */
+#ifndef _di_f_thread_attribute_concurrency_get_
+  extern f_status_t f_thread_attribute_concurrency_get(int *level);
+#endif // _di_f_thread_attribute_concurrency_get_
+
+/**
+ * Set the level of concurrency.
+ *
+ * A level of 0 designates the system to automatically choose concurrency level.
+ * Any non-zero level is considered a hint and will be followed at the systems discretion.
+ *
+ * @param level
+ *   The concurrency level.
+ *
+ * @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_setconcurrency()
+ */
+#ifndef _di_f_thread_attribute_concurrency_set_
+  extern f_status_t f_thread_attribute_concurrency_set(const int level);
+#endif // _di_f_thread_attribute_concurrency_set_
+
+/**
+ * Initialize a attribute.
+ *
+ * @param attribute
+ *   The attribute to set.
+ *   This assigns the default to the attribute.
+ *
+ * @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_condattr_init()
+ */
+#ifndef _di_f_thread_condition_attribute_create_
+  extern f_status_t f_thread_condition_attribute_create(f_thread_condition_attribute_t *attribute);
+#endif // _di_f_thread_condition_attribute_create_
+
+/**
+ * Delete a thread attribute.
+ *
+ * The pthread_condattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
+ *
+ * @param attribute
+ *   The attribute to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_busy (with error bit) if the attribute is busy.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_condattr_destroy()
+ */
+#ifndef _di_f_thread_condition_attribute_delete_
+  extern f_status_t f_thread_condition_attribute_delete(f_thread_condition_attribute_t *attribute);
+#endif // _di_f_thread_condition_attribute_delete_
+
+/**
+ * Resize the thread attributes array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param attributes
+ *   The string attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_condition_attributes_adjust_
+  extern f_status_t f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_adjust_
+
+/**
+ * Resize the thread 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 decimate the size by.
+ * @param attributes
+ *   The string attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_condition_attributes_decimate_by_
+  extern f_status_t f_thread_condition_attributes_decimate_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_decimate_by_
+
+/**
+ * Resize the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_condition_attributes_decrease_by_
+  extern f_status_t f_thread_condition_attributes_decrease_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_decrease_by_
+
+/**
+ * Increase the size of the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_condition_attributes_increase_
+  extern f_status_t f_thread_condition_attributes_increase(f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_increase_
+
+/**
+ * Resize the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_condition_attributes_increase_by_
+  extern f_status_t f_thread_condition_attributes_increase_by(const f_array_length_t amount, f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_increase_by_
+
+/**
+ * Resize the thread attributes array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param attributes
+ *   The string attributes array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_condition_attributes_resize_
+  extern f_status_t f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_attributes_t *attributes);
+#endif // _di_f_thread_condition_attributes_resize_
+
+/**
+ * Initialize a condition.
+ *
+ * @param attribute
+ *   (optional) The attribute to set.
+ *   Set to NULL to not use (in which case the default attribute is used).
+ * @param condition
+ *   The condition to wait on.
+ *
+ * @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_init()
+ */
+#ifndef _di_f_thread_condition_create_
+  extern f_status_t f_thread_condition_create(const f_thread_condition_attribute_t *attribute, f_thread_condition_t *condition);
+#endif // _di_f_thread_condition_create_
+
+/**
+ * Delete a thread condition.
+ *
+ * The pthread_cond_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
+ *
+ * @param condition
+ *   The condition to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_busy (with error bit) if the condition is busy.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_cond_destroy()
+ */
+#ifndef _di_f_thread_condition_delete_
+  extern f_status_t f_thread_condition_delete(f_thread_condition_t *condition);
+#endif // _di_f_thread_condition_delete_
+
+/**
+ * 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_status_t 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_status_t 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_status_t 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_status_t 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 thread conditions array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param conditions
+ *   The string conditions array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_conditions_adjust_
+  extern f_status_t f_thread_conditions_adjust(const f_array_length_t length, f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_adjust_
+
+/**
+ * Resize the thread 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 decimate the size by.
+ * @param conditions
+ *   The string conditions array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_conditions_decimate_by_
+  extern f_status_t f_thread_conditions_decimate_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_decimate_by_
+
+/**
+ * Resize the thread 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 conditions array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_conditions_decrease_by_
+  extern f_status_t f_thread_conditions_decrease_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_decrease_by_
+
+/**
+ * Increase the size of the thread 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 conditions array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_conditions_increase_
+  extern f_status_t f_thread_conditions_increase(f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_increase_
+
+/**
+ * Resize the thread 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 conditions array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_status_t f_thread_conditions_increase_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_increase_by_
+
+/**
+ * Resize the thread conditions array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param conditions
+ *   The string conditions array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_conditions_resize_
+  extern f_status_t f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions);
+#endif // _di_f_thread_conditions_resize_
+
+/**
+ * Create a thread.
+ *
+ * @param attribute
+ *   (optional) The thread attributes.
+ *   Set to NULL to use default 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
+ *   (optional) The structure containing all arguments to pass to the routine.
+ *   Set to NULL to not pass an argument.
+ *
+ * @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_status_t 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_status_t 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_status_t f_thread_exit(int *result);
+#endif // _di_f_thread_exit_
+
+/**
+ * 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_status_t 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_status_t f_thread_join_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_status_t f_thread_join_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_status_t f_thread_key_create(void (*routine) (void *), f_thread_key_t *key);
+#endif // _di_f_thread_key_create_
+
+/**
+ * Delete a thread key.
+ *
+ * The pthread_key_delete() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
+ *
+ * @param key
+ *   The key 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_key_delete()
+ */
+#ifndef _di_f_thread_key_delete_
+  extern f_status_t f_thread_key_delete(f_thread_key_t *key);
+#endif // _di_f_thread_key_delete_
+
+/**
+ * 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_status_t 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_status_t f_thread_key_set(const f_thread_key_t key, const void *value);
+#endif // _di_f_thread_key_set_
+
+/**
+ * Resize the thread keys array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param keys
+ *   The string keys array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_keys_adjust_
+  extern f_status_t f_thread_keys_adjust(const f_array_length_t length, f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_adjust_
+
+/**
+ * Resize the thread 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 decimate the size by.
+ * @param keys
+ *   The string keys array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_keys_decimate_by_
+  extern f_status_t f_thread_keys_decimate_by(const f_array_length_t amount, f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_decimate_by_
+
+/**
+ * Resize the thread 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 keys array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_keys_decrease_by_
+  extern f_status_t f_thread_keys_decrease_by(const f_array_length_t amount, f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_decrease_by_
+
+/**
+ * Increase the size of the thread 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 keys array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_keys_increase_
+  extern f_status_t f_thread_keys_increase(f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_increase_
+
+/**
+ * Resize the thread 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 keys array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_status_t f_thread_keys_increase_by(const f_array_length_t amount, f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_increase_by_
+
+/**
+ * Resize the thread keys array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param keys
+ *   The string keys array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_keys_resize_
+  extern f_status_t f_thread_keys_resize(const f_array_length_t length, f_thread_keys_t *keys);
+#endif // _di_f_thread_keys_resize_
+
+/**
+ * Create a thread lock attribute.
+ *
+ * @param attribute
+ *   The lock attributes to create.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_busy (with error bit) if the lock 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 lockes is reached.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_rwlockattr_init()
+ */
+#ifndef _di_f_thread_lock_attribute_create_
+  extern f_status_t f_thread_lock_attribute_create(f_thread_lock_attribute_t *attribute);
+#endif // _di_f_thread_lock_attribute_create_
+
+/**
+ * Delete a thread lock attribute.
+ *
+ * The pthread_lockattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
+ *
+ * @param attribute
+ *   The attribute to delete.
  *
  * @return
  *   F_none on success.
  *
+ *   F_busy (with error bit) if the lock is busy.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_cond_broadcast()
+ * @see pthread_rwlockattr_destroy()
  */
-#ifndef _di_f_thread_condition_unblock_all_
-  extern f_status_t f_thread_condition_unblock_all(f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_unblock_all_
+#ifndef _di_f_thread_lock_attribute_delete_
+  extern f_status_t f_thread_lock_attribute_delete(f_thread_lock_attribute_t *attribute);
+#endif // _di_f_thread_lock_attribute_delete_
 
 /**
- * Unblock all threads waiting on a condition.
+ * Get the lock attribute process shared thread attribute.
  *
- * @param condition
- *   The condition to broadcast the unblock signal to.
+ * @param attribute
+ *   The lock attribute.
+ * @param shared
+ *   The lock shared attribute value.
  *
  * @return
  *   F_none on success.
@@ -998,69 +2122,345 @@ extern "C" {
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_cond_signal()
+ * @see pthread_rwlockattr_getpshared()
  */
-#ifndef _di_f_thread_condition_unblock_any_
-  extern f_status_t f_thread_condition_unblock_any(f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_unblock_any_
+#ifndef _di_f_thread_lock_attribute_shared_get_
+  extern f_status_t f_thread_lock_attribute_shared_get(const f_thread_lock_attribute_t *attribute, int *shared);
+#endif // _di_f_thread_lock_attribute_shared_get_
 
 /**
- * Wait until condition is triggered.
+ * Set the lock attribute process shared thread attribute.
  *
- * This is a blocking operation.
+ * @param attribute
+ *   The lock attribute.
+ * @param shared
+ *   The lock shared attribute value.
  *
- * @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_rwlockattr_setpshared()
+ */
+#ifndef _di_f_thread_lock_attribute_shared_set_
+  extern f_status_t f_thread_lock_attribute_shared_set(const int shared, f_thread_lock_attribute_t *attribute);
+#endif // _di_f_thread_lock_attribute_shared_set_
+
+/**
+ * Resize the thread attributes array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param attributes
+ *   The string attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_lock_attributes_adjust_
+  extern f_status_t f_thread_lock_attributes_adjust(const f_array_length_t length, f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_adjust_
+
+/**
+ * Resize the thread 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 decimate the size by.
+ * @param attributes
+ *   The string attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_lock_attributes_decimate_by_
+  extern f_status_t f_thread_lock_attributes_decimate_by(const f_array_length_t amount, f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_decimate_by_
+
+/**
+ * Resize the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_lock_attributes_decrease_by_
+  extern f_status_t f_thread_lock_attributes_decrease_by(const f_array_length_t amount, f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_decrease_by_
+
+/**
+ * Increase the size of the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_lock_attributes_increase_
+  extern f_status_t f_thread_lock_attributes_increase(f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_increase_
+
+/**
+ * Resize the thread 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 attributes array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_lock_attributes_increase_by_
+  extern f_status_t f_thread_lock_attributes_increase_by(const f_array_length_t amount, f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_increase_by_
+
+/**
+ * Resize the thread attributes array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param attributes
+ *   The string attributes array to adjust.
  *
  * @return
  *   F_none on success.
  *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_lock_attributes_resize_
+  extern f_status_t f_thread_lock_attributes_resize(const f_array_length_t length, f_thread_lock_attributes_t *attributes);
+#endif // _di_f_thread_lock_attributes_resize_
+
+/**
+ * Create a thread read/write lock.
+ *
+ * @param attribute
+ *   The lock attribute.
+ * @param lock
+ *   The lock to create.
+ *
+ * @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_resource_not (with error bit) if max lockes is reached.
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_cond_wait()
+ * @see pthread_rwlock_init()
  */
-#ifndef _di_f_thread_condition_wait_
-  extern f_status_t f_thread_condition_wait(f_thread_condition_t *condition, f_thread_mutex_t *mutex);
-#endif // _di_f_thread_condition_wait_
+#ifndef _di_f_thread_lock_create_
+  extern f_status_t f_thread_lock_create(const f_thread_lock_attribute_t *attribute, f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_create_
 
 /**
- * Wait until condition is triggered, blocking until the timeout expires.
+ * Delete a thread read/write lock.
  *
- * This is a semi-blocking operation.
- * This will block until timeout and then no longer block.
+ * The pthread_lock_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
  *
- * @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.
+ * @param lock
+ *   The lock to delete.
  *
  * @return
  *   F_none on success.
- *   F_time on success, and wait timeout was reached before condition was triggered.
  *
+ *   F_busy (with error bit) if the lock is busy.
  *   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()
+ * @see pthread_rwlock_destroy()
  */
-#ifndef _di_f_thread_condition_wait_timed_
-  extern f_status_t 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_
+#ifndef _di_f_thread_lock_delete_
+  extern f_status_t f_thread_lock_delete(f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_delete_
+
+/**
+ * Lock the read part of a read/write lock.
+ *
+ * This is a blocking function.
+ *
+ * @param lock
+ *   The thread 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.
+ *
+ * @see pthread_rwlock_rdlock()
+ */
+#ifndef _di_f_thread_lock_read_
+  extern f_status_t f_thread_lock_read(f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_read_
+
+/**
+ * Lock the read part of a read/write lock, waiting for a set period of time to get the lock if already locked.
+ *
+ * If the read part of the read/write lock is already locked and the timeout expires, then the lock attempt fails.
+ *
+ * This is a blocking function (until timeout expires).
+ *
+ * @param timeout
+ *   The timeout.
+ * @param lock
+ *   The read/write lock.
+ *
+ * @return
+ *   F_none on success.
+ *   F_time if the timeout was reached before obtaining the lock.
+ *
+ *   F_deadlock (with error bit) if operation would cause a deadlock.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see pthread_rwlock_timedrdlock()
+ */
+#ifndef _di_f_thread_lock_read_timed_
+  extern f_status_t f_thread_lock_read_timed(const struct timespec *timeout, f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_read_timed_
+
+/**
+ * Try to lock the read part of a read/write lock.
+ *
+ * If lock is already locked, return immediately.
+ *
+ * This is a non-blocking function.
+ *
+ * @param lock
+ *   The thread lock.
+ *
+ * @return
+ *   F_none on success.
+ *   F_busy on success, but the lock is already locked.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_resource_not (with error bit) if max locks is reached.
+ *
+ * @see pthread_rwlock_tryrdlock()
+ */
+#ifndef _di_f_thread_lock_read_try_
+  extern f_status_t f_thread_lock_read_try(f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_read_try_
+
+/**
+ * Lock the write part of a read/write lock.
+ *
+ * This is a blocking function.
+ *
+ * @param lock
+ *   The thread 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 locks is reached.
+ *
+ * @see pthread_rwlock_wrlock()
+ */
+#ifndef _di_f_thread_lock_write_
+  extern f_status_t f_thread_lock_write(f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_write_
+
+/**
+ * Lock the write part of a read/write lock, waiting for a set period of time to get the lock if already locked.
+ *
+ * If the write part of the read/write lock is already locked and the timeout expires, then the lock attempt fails.
+ *
+ * This is a blocking function (until timeout expires).
+ *
+ * @param timeout
+ *   The timeout.
+ * @param lock
+ *   The read/write lock.
+ *
+ * @return
+ *   F_none on success.
+ *   F_time if the timeout was reached before obtaining the lock.
+ *
+ *   F_deadlock (with error bit) if operation would cause a deadlock.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see pthread_rwlock_timedwrlock()
+ */
+#ifndef _di_f_thread_lock_write_timed_
+  extern f_status_t f_thread_lock_write_timed(const struct timespec *timeout, f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_write_timed_
+
+/**
+ * Try to lock the read part of a read/write lock.
+ *
+ * If lock is already locked, return immediately.
+ *
+ * This is a non-blocking function.
+ *
+ * @param lock
+ *   The thread lock.
+ *
+ * @return
+ *   F_none on success.
+ *   F_busy on success, but the lock is already locked.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_resource_not (with error bit) if max locks is reached.
+ *
+ * @see pthread_rwlock_trywrlock()
+ */
+#ifndef _di_f_thread_lock_write_try_
+  extern f_status_t f_thread_lock_write_try(f_thread_lock_t *lock);
+#endif // _di_f_thread_lock_write_try_
 
 /**
- * Resize the string conditions array.
+ * Resize the read/write locks array.
  *
  * @param length
  *   The new size to use.
- * @param conditions
- *   The string conditions array to resize.
+ * @param locks
+ *   The string locks array to resize.
  *
  * @return
  *   F_none on success.
@@ -1068,12 +2468,12 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_conditions_adjust_
-  extern f_status_t f_thread_conditions_adjust(const f_array_length_t length, f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_adjust_
+#ifndef _di_f_thread_locks_adjust_
+  extern f_status_t f_thread_locks_adjust(const f_array_length_t length, f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_adjust_
 
 /**
- * Resize the string conditions array to a smaller size.
+ * Resize the read/write 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.
@@ -1081,8 +2481,8 @@ extern "C" {
  *
  * @param amount
  *   A positive number representing how much to decimate the size by.
- * @param conditions
- *   The string conditions array to resize.
+ * @param locks
+ *   The string locks array to resize.
  *
  * @return
  *   F_none on success.
@@ -1090,12 +2490,12 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_conditions_decimate_by_
-  extern f_status_t f_thread_conditions_decimate_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_decimate_by_
+#ifndef _di_f_thread_locks_decimate_by_
+  extern f_status_t f_thread_locks_decimate_by(const f_array_length_t amount, f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_decimate_by_
 
 /**
- * Resize the string conditions array to a smaller size.
+ * Resize the read/write 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.
@@ -1103,8 +2503,8 @@ extern "C" {
  *
  * @param amount
  *   A positive number representing how much to decrease the size by.
- * @param conditions
- *   The string conditions array to resize.
+ * @param locks
+ *   The string locks array to resize.
  *
  * @return
  *   F_none on success.
@@ -1112,18 +2512,18 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_conditions_decrease_by_
-  extern f_status_t f_thread_conditions_decrease_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_decrease_by_
+#ifndef _di_f_thread_locks_decrease_by_
+  extern f_status_t f_thread_locks_decrease_by(const f_array_length_t amount, f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_decrease_by_
 
 /**
- * Increase the size of the string conditions array, but only if necessary.
+ * Increase the size of the read/write 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 conditions array to resize.
+ * @param locks
+ *   The string locks array to resize.
  *
  * @return
  *   F_none on success.
@@ -1133,21 +2533,21 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_conditions_increase_
-  extern f_status_t f_thread_conditions_increase(f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_increase_
+#ifndef _di_f_thread_locks_increase_
+  extern f_status_t f_thread_locks_increase(f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_increase_
 
 /**
- * Resize the string conditions array to a larger size.
+ * Resize the read/write locks array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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 conditions array to resize.
+ * @param locks
+ *   The string locks array to resize.
  *
  * @return
  *   F_none on success.
@@ -1157,17 +2557,17 @@ extern "C" {
  *   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_status_t f_thread_conditions_increase_by(const f_array_length_t amount, f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_increase_by_
+#ifndef _di_f_thread_locks_increase_by_
+  extern f_status_t f_thread_locks_increase_by(const f_array_length_t amount, f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_increase_by_
 
 /**
- * Resize the string conditions array.
+ * Resize the read/write locks array.
  *
  * @param length
  *   The new size to use.
- * @param conditions
- *   The string conditions array to adjust.
+ * @param locks
+ *   The string locks array to adjust.
  *
  * @return
  *   F_none on success.
@@ -1175,271 +2575,217 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_thread_conditions_resize_
-  extern f_status_t f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions);
-#endif // _di_f_thread_conditions_resize_
+#ifndef _di_f_thread_locks_resize_
+  extern f_status_t f_thread_locks_resize(const f_array_length_t length, f_thread_locks_t *locks);
+#endif // _di_f_thread_locks_resize_
 
 /**
- * Create a thread.
+ * Create a thread mutex attribute.
  *
  * @param attribute
- *   (optional) The thread attributes.
- *   Set to NULL to use default 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
- *   (optional) The structure containing all arguments to pass to the routine.
- *   Set to NULL to not pass an argument.
+ *   The mutex attributes 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 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_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_create()
+ * @see pthread_mutexattr_init()
  */
-#ifndef _di_f_thread_create_
-  extern f_status_t f_thread_create(const f_thread_attribute_t *attribute, f_thread_id_t *id, void *(*routine) (void *), void *argument);
-#endif // _di_f_thread_create_
+#ifndef _di_f_thread_mutex_attribute_create_
+  extern f_status_t f_thread_mutex_attribute_create(f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_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
- *
+ * Delete a thread mutex attribute.
  *
- * @see pthread_detach()
- */
-#ifndef _di_f_thread_detach_
-  extern f_status_t f_thread_detach(const f_thread_id_t id);
-#endif // _di_f_thread_detach_
-
-/**
- * Have the current thread exit.
+ * The pthread_mutexattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
  *
- * @param result
- *   The code returned by the exited thread.
+ * @param attribute
+ *   The attribute 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_exit()
+ * @see pthread_mutexattr_destroy()
  */
-#ifndef _di_f_thread_exit_
-  extern f_status_t f_thread_exit(int *result);
-#endif // _di_f_thread_exit_
+#ifndef _di_f_thread_mutex_attribute_delete_
+  extern f_status_t f_thread_mutex_attribute_delete(f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_delete_
 
 /**
- * Wait until the given thread exits and then join it to the current thread.
- *
- * This is a blocking operation.
+ * Get the mutex attribute priority ceiling.
  *
- * @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.
+ * @param attribute
+ *   The thread mutex attribute.
+ * @param ceiling
+ *   The priority ceiling.
  *
  * @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
- *
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
  *
- * @see pthread_join()
+ * @see pthread_mutexattr_getprioceiling()
  */
-#ifndef _di_f_thread_join_
-  extern f_status_t f_thread_join(const f_thread_id_t id, void **result);
-#endif // _di_f_thread_join_
+#ifndef _di_f_thread_mutex_attribute_priority_ceiling_get_
+  extern f_status_t f_thread_mutex_attribute_priority_ceiling_get(const f_thread_mutex_attribute_t *attribute, int *ceiling);
+#endif // _di_f_thread_mutex_attribute_priority_ceiling_get_
 
 /**
- * Try to join the given thread to the current thread.
+ * Set the mutex attribute priority ceiling.
  *
- * 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.
+ * @param ceiling
+ *   The priority ceiling.
+ * @param attribute
+ *   The thread mutex attribute.
  *
  * @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
- *
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
  *
- * @see pthread_tryjoin_np()
+ * @see pthread_mutexattr_setprioceiling()
  */
-#ifndef _di_f_thread_join_try_
-  extern f_status_t f_thread_join_try(const f_thread_id_t id, void **result);
-#endif // _di_f_thread_join_try_
+#ifndef _di_f_thread_mutex_attribute_priority_ceiling_set_
+  extern f_status_t f_thread_mutex_attribute_priority_ceiling_set(const int ceiling, f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_priority_ceiling_set_
 
 /**
- * Try to join the given thread to the current thread, blocking until the timeout expires.
+ * Get the mutex attribute process shared thread attribute.
  *
- * 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.
+ * @param attribute
+ *   The mutex attribute.
+ * @param shared
+ *   The mutex shared attribute value.
  *
  * @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.
- *
+ *   F_failure (with error bit) on any other error.
  *
- * @see pthread_timedjoin_np()
+ * @see pthread_mutexattr_getpshared()
  */
-#ifndef _di_f_thread_join_timed_
-  extern f_status_t f_thread_join_timed(const f_thread_id_t id, const struct timespec wait, void **result);
-#endif // _di_f_thread_join_timed_
+#ifndef _di_f_thread_mutex_attribute_shared_get_
+  extern f_status_t f_thread_mutex_attribute_shared_get(const f_thread_mutex_attribute_t *attribute, int *shared);
+#endif // _di_f_thread_mutex_attribute_shared_get_
 
 /**
- * Create a thread key.
+ * Set the mutex attribute process shared thread attribute.
  *
- * @param routine
- *   The function to execute for deallocation/deleting.
- * @param key
- *   The thread key.
+ * @param attribute
+ *   The mutex attribute.
+ * @param shared
+ *   The mutex shared attribute value.
  *
  * @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()
+ * @see pthread_mutexattr_setpshared()
  */
-#ifndef _di_f_thread_key_create_
-  extern f_status_t f_thread_key_create(void (*routine) (void *), f_thread_key_t *key);
-#endif // _di_f_thread_key_create_
+#ifndef _di_f_thread_mutex_attribute_shared_set_
+  extern f_status_t f_thread_mutex_attribute_shared_set(const int shared, f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_shared_set_
 
 /**
- * Get the value of a thread key.
+ * Get the mutex attribute type.
  *
- * @param key
- *   The thread key.
- * @param value
- *   The assigned thread key value.
+ * @param attribute
+ *   The mutex attribute.
+ * @param type
+ *   The type.
  *
  * @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_getspecific()
+ * @see pthread_mutexattr_gettype()
  */
-#ifndef _di_f_thread_key_get_
-  extern f_status_t f_thread_key_get(const f_thread_key_t key, void **value);
-#endif // _di_f_thread_key_get_
+#ifndef _di_f_thread_mutex_attribute_type_get_
+  extern f_status_t f_thread_mutex_attribute_type_get(const f_thread_mutex_attribute_t *attribute, int *type);
+#endif // _di_f_thread_mutex_attribute_type_get_
 
 /**
- * Get the value of a thread key.
+ * Set the mutex attribute process shared thread attribute.
  *
- * @param key
- *   The thread key.
- * @param value
- *   The thread key value to assign.
+ * @param type
+ *   The type.
+ * @param attribute
+ *   The mutex attribute.
  *
  * @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_setspecific()
+ * @see pthread_mutexattr_settype()
  */
-#ifndef _di_f_thread_key_set_
-  extern f_status_t f_thread_key_set(const f_thread_key_t key, const void *value);
-#endif // _di_f_thread_key_set_
+#ifndef _di_f_thread_mutex_attribute_type_set_
+  extern f_status_t f_thread_mutex_attribute_type_set(const int type, f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_type_set_
 
 /**
- * Make a read lock on the read/write lock.
+ * Get the mutex attribute protocol.
  *
- * @param lock
- *   The read/write lock.
+ * @param attribute
+ *   The thread mutex attribute.
+ * @param protocol
+ *   The protocol.
  *
  * @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.
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
  *
- * @see pthread_rwlock_rdlock()
+ * @see pthread_mutexattr_getprotocol()
  */
-#ifndef _di_f_thread_lock_
-  extern f_status_t f_thread_lock(f_thread_lock_t *lock);
-#endif // _di_f_thread_lock_
+#ifndef _di_f_thread_mutex_attribute_protocol_get_
+  extern f_status_t f_thread_mutex_attribute_protocol_get(const f_thread_mutex_attribute_t *attribute, int *protocol);
+#endif // _di_f_thread_mutex_attribute_protocol_get_
 
 /**
- * Try to make a read lock on the read/write lock.
+ * Set the mutex attribute protocol.
  *
- * @param lock
- *   The read/write lock.
+ * @param protocol
+ *   The protocol.
+ * @param attribute
+ *   The thread mutex attribute.
  *
  * @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.
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
+ *   F_supported_not (with error bit) if the protocol is not supported.
  *
- * @see pthread_rwlock_tryrdlock()
+ * @see pthread_mutexattr_setprotocol()
  */
-#ifndef _di_f_thread_lock_try_
-  extern f_status_t f_thread_lock_try(f_thread_lock_t *lock);
-#endif // _di_f_thread_lock_try_
+#ifndef _di_f_thread_mutex_attribute_protocol_set_
+  extern f_status_t f_thread_mutex_attribute_protocol_set(const int protocol, f_thread_mutex_attribute_t *attribute);
+#endif // _di_f_thread_mutex_attribute_protocol_set_
 
 /**
- * Resize the string attributes array.
+ * Resize the thread attributes array.
  *
  * @param length
  *   The new size to use.
@@ -1457,7 +2803,7 @@ extern "C" {
 #endif // _di_f_thread_mutex_attributes_adjust_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread 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.
@@ -1479,7 +2825,7 @@ extern "C" {
 #endif // _di_f_thread_mutex_attributes_decimate_by_
 
 /**
- * Resize the string attributes array to a smaller size.
+ * Resize the thread 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.
@@ -1494,58 +2840,14 @@ extern "C" {
  *   F_none on success.
  *
  *   F_memory_not (with error bit) on out of memory.
- *   F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_f_thread_mutex_attributes_decrease_by_
-  extern f_status_t f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_attributes_t *attributes);
-#endif // _di_f_thread_mutex_attributes_decrease_by_
-
-/**
- * Create a thread mutex attribute.
- *
- * @param attribute
- *   The mutex attributes 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_mutexattr_init()
- */
-#ifndef _di_f_thread_mutex_attribute_create_
-  extern f_status_t f_thread_mutex_attribute_create(f_thread_mutex_attribute_t *attribute);
-#endif // _di_f_thread_mutex_attribute_create_
-
-/**
- * Delete a thread mutex attribute.
- *
- * The pthread_mutexattr_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
- * Therefore there is only this function for both deleting and destroying.
- *
- * @param attribute
- *   The attribute 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_mutexattr_destroy()
- */
-#ifndef _di_f_thread_mutex_attribute_delete_
-  extern f_status_t f_thread_mutex_attribute_delete(f_thread_mutex_attribute_t *attribute);
-#endif // _di_f_thread_mutex_attribute_delete_
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_mutex_attributes_decrease_by_
+  extern f_status_t f_thread_mutex_attributes_decrease_by(const f_array_length_t amount, f_thread_mutex_attributes_t *attributes);
+#endif // _di_f_thread_mutex_attributes_decrease_by_
 
 /**
- * Increase the size of the string attributes array, but only if necessary.
+ * Increase the size of the thread 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.
@@ -1566,9 +2868,9 @@ extern "C" {
 #endif // _di_f_thread_mutex_attributes_increase_
 
 /**
- * Resize the string attributes array to a larger size.
+ * Resize the thread attributes array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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.
  *
@@ -1590,7 +2892,7 @@ extern "C" {
 #endif // _di_f_thread_mutex_attributes_increase_by_
 
 /**
- * Resize the string attributes array.
+ * Resize the thread attributes array.
  *
  * @param length
  *   The new size to use.
@@ -1607,7 +2909,6 @@ extern "C" {
   extern f_status_t f_thread_mutex_attributes_resize(const f_array_length_t length, f_thread_mutex_attributes_t *attributes);
 #endif // _di_f_thread_mutex_attributes_resize_
 
-
 /**
  * Create a thread mutex.
  *
@@ -1677,6 +2978,35 @@ extern "C" {
 #endif // _di_f_thread_mutex_lock_
 
 /**
+ * Lock the mutex, waiting for a set period of time to get the lock if already locked.
+ *
+ * If the mutex is already locked and the timeout expires, then the lock attempt fails.
+ *
+ * This is a blocking function (until timeout expires).
+ *
+ * @param timeout
+ *   The timeout.
+ * @param mutex
+ *   The thread mutex.
+ *
+ * @return
+ *   F_none on success.
+ *   F_time if the timeout was reached before obtaining the lock.
+ *
+ *   F_deadlock (with error bit) if operation would cause a deadlock.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
+ *   F_recover_not (with error bit) if the state protected by the mutex is not recoverable.
+ *   F_resource_not (with error bit) if max mutex locks is reached.
+ *   F_thread_not (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead).
+ *
+ * @see pthread_mutex_timedlock()
+ */
+#ifndef _di_f_thread_mutex_lock_timed_
+  extern f_status_t f_thread_mutex_lock_timed(const struct timespec *timeout, f_thread_mutex_t *mutex);
+#endif // _di_f_thread_mutex_lock_timed_
+
+/**
  * Try to lock the mutex.
  *
  * If mutex is already locked, return immediately.
@@ -1700,6 +3030,53 @@ extern "C" {
 #endif // _di_f_thread_mutex_lock_try_
 
 /**
+ * Get the mutex priority ceiling.
+ *
+ * @param mutex
+ *   The thread mutex.
+ * @param ceiling
+ *   The priority ceiling.
+ *
+ * @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.
+ *
+ * @see pthread_mutex_getprioceiling()
+ */
+#ifndef _di_f_thread_mutex_priority_ceiling_get_
+  extern f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t *mutex, int *ceiling);
+#endif // _di_f_thread_mutex_priority_ceiling_get_
+
+/**
+ * Set the mutex priority ceiling.
+ *
+ * @param ceiling
+ *   The priority ceiling.
+ * @param mutex
+ *   The thread mutex.
+ * @param previous
+ *   (optional) The previous priority ceiling.
+ *   Set to NULL to not use.
+ *
+ * @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_prohibited (with error bit) if not allowed to perform the operation.
+ *   F_recover_not (with error bit) if the state protected by the mutex is not recoverable (for a "robust" mutex).
+ *   F_resource_not (with error bit) if max mutex locks is reached.
+ *   F_thread_not (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead).
+ *
+ * @see pthread_mutex_setprioceiling()
+ */
+#ifndef _di_f_thread_mutex_priority_ceiling_set_
+  extern f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t *mutex, int *previous);
+#endif // _di_f_thread_mutex_priority_ceiling_set_
+
+/**
  * Unlock the mutex.
  *
  * @param mutex
@@ -1719,7 +3096,7 @@ extern "C" {
 #endif // _di_f_thread_mutex_unlock_
 
 /**
- * Resize the string mutexs array.
+ * Resize the thread mutexs array.
  *
  * @param length
  *   The new size to use.
@@ -1737,7 +3114,7 @@ extern "C" {
 #endif // _di_f_thread_mutexs_adjust_
 
 /**
- * Resize the string mutexs array to a smaller size.
+ * Resize the thread 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.
@@ -1759,7 +3136,7 @@ extern "C" {
 #endif // _di_f_thread_mutexs_decimate_by_
 
 /**
- * Resize the string mutexs array to a smaller size.
+ * Resize the thread 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.
@@ -1781,7 +3158,7 @@ extern "C" {
 #endif // _di_f_thread_mutexs_decrease_by_
 
 /**
- * Increase the size of the string mutexs array, but only if necessary.
+ * Increase the size of the thread 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.
@@ -1802,9 +3179,9 @@ extern "C" {
 #endif // _di_f_thread_mutexs_increase_
 
 /**
- * Resize the string mutexs array to a larger size.
+ * Resize the thread mutexs array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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.
  *
@@ -1826,7 +3203,7 @@ extern "C" {
 #endif // _di_f_thread_mutexs_increase_by_
 
 /**
- * Resize the string mutexs array.
+ * Resize the thread mutexs array.
  *
  * @param length
  *   The new size to use.
@@ -1863,7 +3240,75 @@ extern "C" {
 #endif // _di_f_thread_once_
 
 /**
- * Resize the string sets array.
+ * Get the thread scheduler parameter.
+ *
+ * @param id
+ *   The thread ID.
+ * @param policy
+ *   The scheduler policy
+ * @param parameter
+ *   The scheduler parameter
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_supported_not (with error bit) if the policy or scheduling parameter is invalid.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_getschedparam()
+ */
+#ifndef _di_f_thread_scheduler_parameter_get_
+  extern f_status_t f_thread_scheduler_parameter_get(const f_thread_id_t id, int *policy, struct sched_param *parameter);
+#endif // _di_f_thread_scheduler_parameter_get_
+
+/**
+ * Set the thread scheduler parameter.
+ *
+ * @param id
+ *   The thread ID.
+ * @param policy
+ *   The scheduler policy
+ * @param parameter
+ *   The scheduler parameter
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if insufficient privileges or scheduler (or policy) does not allow operation.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_setschedparam()
+ */
+#ifndef _di_f_thread_scheduler_parameter_set_
+  extern f_status_t f_thread_scheduler_parameter_set(const f_thread_id_t id, const int policy, const struct sched_param *parameter);
+#endif // _di_f_thread_scheduler_parameter_set_
+
+/**
+ * Set the thread scheduler priority.
+ *
+ * @param id
+ *   The thread ID.
+ * @param priority
+ *   The scheduler priority.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if insufficient privileges.
+ *   F_found_not (with error bit) no thread by the given ID was found.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_setschedprio()
+ */
+#ifndef _di_f_thread_scheduler_priority_set_
+  extern f_status_t f_thread_scheduler_priority_set(const f_thread_id_t id, const int priority);
+#endif // _di_f_thread_scheduler_priority_set_
+
+/**
+ * Resize the thread sets array.
  *
  * @param length
  *   The new size to use.
@@ -1881,7 +3326,7 @@ extern "C" {
 #endif // _di_f_thread_sets_adjust_
 
 /**
- * Resize the string sets array to a smaller size.
+ * Resize the thread sets 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.
@@ -1903,7 +3348,7 @@ extern "C" {
 #endif // _di_f_thread_sets_decimate_by_
 
 /**
- * Resize the string sets array to a smaller size.
+ * Resize the thread sets 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.
@@ -1925,7 +3370,7 @@ extern "C" {
 #endif // _di_f_thread_sets_decrease_by_
 
 /**
- * Increase the size of the string sets array, but only if necessary.
+ * Increase the size of the thread sets 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.
@@ -1946,9 +3391,9 @@ extern "C" {
 #endif // _di_f_thread_sets_increase_
 
 /**
- * Resize the string sets array to a larger size.
+ * Resize the thread sets array to a larger size.
  *
- * This will resize making the string larger based on the given length.
+ * 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.
  *
@@ -1970,7 +3415,7 @@ extern "C" {
 #endif // _di_f_thread_sets_increase_by_
 
 /**
- * Resize the string sets array.
+ * Resize the thread sets array.
  *
  * @param length
  *   The new size to use.
@@ -2062,6 +3507,257 @@ extern "C" {
   extern f_status_t f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value);
 #endif // _di_f_thread_signal_queue_
 
+/**
+ * Create a thread spin lock.
+ *
+ * @param shared
+ *   The shared process setting.
+ * @param spin
+ *   The spin to create.
+ *
+ * @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_resource_not (with error bit) if max spines is reached.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_spin_init()
+ */
+#ifndef _di_f_thread_spin_create_
+  extern f_status_t f_thread_spin_create(const int shared, f_thread_spin_t *spin);
+#endif // _di_f_thread_spin_create_
+
+/**
+ * Delete a thread spin lock.
+ *
+ * The pthread_spin_destroy() function has no distinction like the *_destroy() and the *_delete() used by the FLL project.
+ * Therefore there is only this function for both deleting and destroying.
+ *
+ * @param spin
+ *   The spin to delete.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_busy (with error bit) if the spin is busy.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_failure (with error bit) on any other error.
+ *
+ * @see pthread_spin_destroy()
+ */
+#ifndef _di_f_thread_spin_delete_
+  extern f_status_t f_thread_spin_delete(f_thread_spin_t *spin);
+#endif // _di_f_thread_spin_delete_
+
+/**
+ * Lock the spin lock.
+ *
+ * This is a blocking function.
+ *
+ * @param spin
+ *   The thread spin.
+ *
+ * @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 spin locks is reached.
+ *
+ * @see pthread_spin_lock()
+ */
+#ifndef _di_f_thread_spin_lock_
+  extern f_status_t f_thread_spin_lock(f_thread_spin_t *spin);
+#endif // _di_f_thread_spin_lock_
+
+/**
+ * Try to lock the spin lock.
+ *
+ * If spin is already locked, return immediately.
+ *
+ * This is a non-blocking function.
+ *
+ * @param spin
+ *   The thread spin.
+ *
+ * @return
+ *   F_none on success.
+ *   F_busy on success, but the spin is already locked.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_resource_not (with error bit) if max spin locks is reached.
+ *
+ * @see pthread_spin_trylock()
+ */
+#ifndef _di_f_thread_spin_lock_try_
+  extern f_status_t f_thread_spin_lock_try(f_thread_spin_t *spin);
+#endif // _di_f_thread_spin_lock_try_
+
+/**
+ * Unlock the spin lock.
+ *
+ * @param spin
+ *   The thread spin.
+ *
+ * @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 spin is not owned by current thread).
+ *   F_resource_not (with error bit) if max spin locks is reached.
+ *
+ * @see pthread_spin_unlock()
+ */
+#ifndef _di_f_thread_spin_unlock_
+  extern f_status_t f_thread_spin_unlock(f_thread_spin_t *spin);
+#endif // _di_f_thread_spin_unlock_
+
+/**
+ * Resize the thread spin locks array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param spins
+ *   The string spins array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_spins_adjust_
+  extern f_status_t f_thread_spins_adjust(const f_array_length_t length, f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_adjust_
+
+/**
+ * Resize the thread spin 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 decimate the size by.
+ * @param spins
+ *   The string spins array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_spins_decimate_by_
+  extern f_status_t f_thread_spins_decimate_by(const f_array_length_t amount, f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_decimate_by_
+
+/**
+ * Resize the thread spin 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 spins
+ *   The string spins array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_spins_decrease_by_
+  extern f_status_t f_thread_spins_decrease_by(const f_array_length_t amount, f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_decrease_by_
+
+/**
+ * Increase the size of the thread spin 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 spins
+ *   The string spins array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_spins_increase_
+  extern f_status_t f_thread_spins_increase(f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_increase_
+
+/**
+ * Resize the thread spin 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 spins
+ *   The string spins array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   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_spins_increase_by_
+  extern f_status_t f_thread_spins_increase_by(const f_array_length_t amount, f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_increase_by_
+
+/**
+ * Resize the thread spin locks array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param spins
+ *   The string spins array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_thread_spins_resize_
+  extern f_status_t f_thread_spins_resize(const f_array_length_t length, f_thread_spins_t *spins);
+#endif // _di_f_thread_spins_resize_
+
+/**
+ * Unlock the read/write lock.
+ *
+ * @param lock
+ *   The thread lock.
+ *
+ * @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 lock is not owned by current thread).
+ *   F_resource_not (with error bit) if max lock locks is reached.
+ *
+ * @see pthread_rwlock_unlock()
+ */
+#ifndef _di_f_thread_unlock_
+  extern f_status_t f_thread_unlock(f_thread_lock_t *lock);
+#endif // _di_f_thread_unlock_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 8b906a1e080b250f2cb366801ee58409623a8cd0..2731bf89f058f522a5f06ea9e9adf4f156499403 100644 (file)
@@ -524,6 +524,12 @@ extern "C" {
         case F_ready_not:
           *string = FL_status_string_ready_not;
           break;
+        case F_recover:
+          *string = FL_status_string_recover;
+          break;
+        case F_recover_not:
+          *string = FL_status_string_recover_not;
+          break;
         case F_recurse:
           *string = FL_status_string_recurse;
           break;
index d2e7b85ec5558fe3306efefcf92caa0ea9109064..98b8c1598b532975096fa44f9b14088a751df481 100644 (file)
@@ -269,6 +269,8 @@ extern "C" {
     #define FL_status_string_read_only         "F_read_only"
     #define FL_status_string_ready             "F_ready"
     #define FL_status_string_ready_not         "F_ready_not"
+    #define FL_status_string_recover           "F_recover"
+    #define FL_status_string_recover_not       "F_recover_not"
     #define FL_status_string_recurse           "F_recurse"
     #define FL_status_string_recurse_not       "F_recurse_not"
     #define FL_status_string_relative          "F_relative"
@@ -422,6 +424,8 @@ extern "C" {
     #define FL_status_string_read_only_length         11
     #define FL_status_string_ready_length             7
     #define FL_status_string_ready_not_length         11
+    #define FL_status_string_recover_length           9
+    #define FL_status_string_recover_not_length       13
     #define FL_status_string_recurse_length           9
     #define FL_status_string_recurse_not_length       13
     #define FL_status_string_relative_length          10
index bc6e381eb9a5440ca867ba28039c570090388e4d..18f77296781542143623bf77e5addbb18133bd7d 100644 (file)
@@ -886,6 +886,16 @@ extern "C" {
         return F_none;
       }
 
+      if (fl_string_compare(string, FL_status_string_recover, length, FL_status_string_recover_length) == F_equal_to) {
+        *code = F_recover;
+        return F_none;
+      }
+
+      if (fl_string_compare(string, FL_status_string_recover_not, length, FL_status_string_recover_not_length) == F_equal_to) {
+        *code = F_recover_not;
+        return F_none;
+      }
+
       if (fl_string_compare(string, FL_status_string_recurse, length, FL_status_string_recurse_length) == F_equal_to) {
         *code = F_recurse;
         return F_none;