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.
F_read_only,
F_ready,
F_ready_not,
+ F_recover,
+ F_recover_not,
F_recurse,
F_recurse_not,
F_relative,
}
#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) {
}
#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) {
}
#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
*
* @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.
*
*
* 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.
*
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
#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_
#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_
/**
#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_
/**
#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_
#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
}
#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) {
}
#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_
}
#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_
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);
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);
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);
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);
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) {
#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) {
}
#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_
}
#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_
}
#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_
}
#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
#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
#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
* 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
#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.
#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.
#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.
#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.
#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.
*
#endif // _di_f_thread_attributes_increase_by_
/**
- * Resize the string attributes array.
+ * Resize the thread attributes array.
*
* @param length
* The new size to use.
#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.
* 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.
* 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.
* 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.
* @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.
* 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.
* @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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
*
* @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.
* 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.
*
* @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.
* 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.
* 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.
* 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.
* 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.
#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.
#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.
* 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.
#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.
*
#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.
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.
*
#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.
#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
#endif // _di_f_thread_mutex_unlock_
/**
- * Resize the string mutexs array.
+ * Resize the thread mutexs array.
*
* @param length
* The new size to use.
#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.
#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.
#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.
#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.
*
#endif // _di_f_thread_mutexs_increase_by_
/**
- * Resize the string mutexs array.
+ * Resize the thread mutexs array.
*
* @param length
* The new size to use.
#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.
#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.
#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.
#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.
#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.
*
#endif // _di_f_thread_sets_increase_by_
/**
- * Resize the string sets array.
+ * Resize the thread sets array.
*
* @param length
* The new size to use.
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
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;
#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"
#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
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;