]> Kevux Git Server - fll/commitdiff
Update: add missing thread functionality and fix an initializer.
authorKevin Day <thekevinday@gmail.com>
Sat, 23 Jan 2021 22:59:21 +0000 (16:59 -0600)
committerKevin Day <thekevinday@gmail.com>
Sat, 23 Jan 2021 22:59:21 +0000 (16:59 -0600)
level_0/f_thread/c/private-thread.c
level_0/f_thread/c/private-thread.h
level_0/f_thread/c/thread-common.h
level_0/f_thread/c/thread.c
level_0/f_thread/c/thread.h

index fad975dee1a9e73275dc1c58f60430686ea865a9..da63306413c1ba686aa1acd9e30a03e2af3e1cb3 100644 (file)
@@ -66,6 +66,134 @@ extern "C" {
   }
 #endif // !defined(_di_f_thread_attributes_decrease_) || !defined(_di_f_thread_attributes_decrease_by_) || !defined(_di_f_thread_attributes_increase_) || !defined(_di_f_thread_attributes_increase_by_)
 
+#if !defined(_di_f_thread_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) {
+
+    const int error = pthread_condattr_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_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_)
+
+#if !defined(_di_f_thread_condition_attributes_adjust_) || !defined(_di_f_thread_condition_attributes_decimate_by_)
+  f_status_t private_f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_condition_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(attributes->size, length, sizeof(f_thread_condition_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_condition_attributes_adjust_) || !defined(_di_f_thread_condition_attributes_decimate_by_)
+
+#if !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_)
+  f_status_t private_f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_attributes_t *attributes) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < attributes->size; ++i) {
+
+      status = private_f_thread_condition_attribute_delete(&attributes->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(attributes->size, length, sizeof(f_thread_condition_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_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_)
+
+#if !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_) || !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_) || !defined(_di_f_thread_conditions_resize_)
+  f_status_t private_f_thread_condition_delete(f_thread_condition_t *condition) {
+
+    const int error = pthread_cond_destroy(condition);
+
+    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_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_) || !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_) || !defined(_di_f_thread_conditions_resize_)
+
+#if !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_)
+  f_status_t private_f_thread_conditions_adjust(const f_array_length_t length, f_thread_conditions_t *conditions) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < conditions->size; ++i) {
+
+      status = private_f_thread_condition_delete(&conditions->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_adjust(conditions->size, length, sizeof(f_thread_condition_t), (void **) & conditions->array);
+
+    if (F_status_is_error_not(status)) {
+      conditions->size = length;
+
+      if (conditions->used > conditions->size) {
+        conditions->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_)
+
+#if !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_)
+  f_status_t private_f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions) {
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = length; i < conditions->size; ++i) {
+
+      status = private_f_thread_condition_delete(&conditions->array[i]);
+      if (F_status_is_error(status)) return status;
+    } // for
+
+    status = f_memory_resize(conditions->size, length, sizeof(f_thread_condition_t), (void **) & conditions->array);
+
+    if (F_status_is_error_not(status)) {
+      conditions->size = length;
+
+      if (conditions->used > conditions->size) {
+        conditions->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // !defined(_di_f_thread_conditions_decrease_) || !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_)
+
 #if !defined(_di_f_thread_mutexs_adjust_) || !defined(_di_f_thread_mutexs_decimate_by_) || !defined(_di_f_thread_mutexs_decrease_) || !defined(_di_f_thread_mutexs_decrease_by_) || !defined(_di_f_thread_mutexs_increase_) || !defined(_di_f_thread_mutexs_increase_by_) || !defined(_di_f_thread_mutexs_resize_)
   f_status_t private_f_thread_mutex_delete(f_thread_mutex_t *mutex) {
 
index e23ff830637b45a3ff3dfe764a4021239ec32203..f34b41b8d5b9673b27c57a8009110734e58e04d3 100644 (file)
@@ -30,6 +30,8 @@ extern "C" {
  *
  *   F_failure (with error bit) on error.
  *
+ * @see pthread_attr_destroy()
+ *
  * @see f_thread_attributes_adjust()
  * @see f_thread_attributes_decimate_by()
  * @see f_thread_attributes_decrease()
@@ -103,6 +105,158 @@ extern "C" {
  *
  * @param length
  *   The new size to use.
+ * @param attribute
+ *   The attribute to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_condattr_destroy()
+ *
+ * @see f_thread_condition_attributes_adjust()
+ * @see f_thread_condition_attributes_decimate_by()
+ * @see f_thread_condition_attributes_decrease()
+ * @see f_thread_condition_attributes_decrease_by()
+ * @see f_thread_condition_attributes_increase()
+ * @see f_thread_condition_attributes_increase_by()
+ * @see f_thread_condition_attributes_resize()
+ */
+#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_)
+  extern f_status_t private_f_thread_condition_attribute_delete(f_thread_condition_attribute_t *attribute) f_gcc_attribute_visibility_internal;
+#endif // !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_)
+
+/**
+ * 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_condition_attributes_adjust()
+ * @see f_thread_condition_attributes_decimate_by()
+ */
+#if !defined(_di_f_thread_condition_attributes_adjust_) || !defined(_di_f_thread_condition_attributes_decimate_by_)
+  extern f_status_t private_f_thread_condition_attributes_adjust(const f_array_length_t length, f_thread_condition_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_condition_attributes_adjust_) || !defined(_di_f_thread_condition_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_condition_attributes_decrease_by()
+ * @see f_thread_condition_attributes_increase()
+ * @see f_thread_condition_attributes_increase_by()
+ */
+#if !defined(_di_f_thread_condition_attributes_decrease_by_) || !defined(_di_f_thread_condition_attributes_increase_) || !defined(_di_f_thread_condition_attributes_increase_by_)
+  extern f_status_t private_f_thread_condition_attributes_resize(const f_array_length_t length, f_thread_condition_attributes_t *attributes) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_condition_attributes_decrease_by_) || !defined(_di_f_thread_condition_attributes_increase_) || !defined(_di_f_thread_condition_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 conditions
+ *   The conditions to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_failure (with error bit) on error.
+ *
+ * @see pthread_cond_destroy()
+ *
+ * @see f_thread_conditions_adjust()
+ * @see f_thread_conditions_decimate_by()
+ * @see f_thread_conditions_decrease()
+ * @see f_thread_conditions_decrease_by()
+ * @see f_thread_conditions_increase()
+ * @see f_thread_conditions_increase_by()
+ * @see f_thread_conditions_resize()
+ */
+#if !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_) || !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_) || !defined(_di_f_thread_conditions_resize_)
+  extern f_status_t private_f_thread_condition_delete(f_thread_condition_t *condition) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_) || !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_) || !defined(_di_f_thread_conditions_resize_)
+
+/**
+ * Private implementation for resizing.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The new size to use.
+ * @param conditions
+ *   The conditions to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_memory_adjust()
+ * @see f_thread_conditions_adjust()
+ * @see f_thread_conditions_decimate_by()
+ */
+#if !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_decimate_by_)
+  extern f_status_t private_f_thread_conditions_adjust(const f_array_length_t length, f_thread_conditions_t *conditions) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_conditions_adjust_) || !defined(_di_f_thread_conditions_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 conditions
+ *   The conditions to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_thread_conditions_decrease_by()
+ * @see f_thread_conditions_increase()
+ * @see f_thread_conditions_increase_by()
+ */
+#if !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_increase_by_)
+  extern f_status_t private_f_thread_conditions_resize(const f_array_length_t length, f_thread_conditions_t *conditions) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_thread_conditions_decrease_by_) || !defined(_di_f_thread_conditions_increase_) || !defined(_di_f_thread_conditions_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 mutexs
  *   The mutexs to adjust.
  *
@@ -111,6 +265,8 @@ extern "C" {
  *
  *   F_failure (with error bit) on error.
  *
+ * @see pthread_mutex_destroy()
+ *
  * @see f_thread_mutexs_adjust()
  * @see f_thread_mutexs_decimate_by()
  * @see f_thread_mutexs_decrease()
index 4131614a57aa8eb825a27a353ba0828bab5e858c..5bfb6fd05f2ea350b5e64a7e8a43bc23f2f7589e 100644 (file)
@@ -67,9 +67,11 @@ extern "C" {
 #ifndef _di_f_thread_condition_t_
   typedef pthread_cond_t f_thread_condition_t;
 
-  #define f_thread_condition_t_initialize 0
+  #define f_thread_condition_t_initialize PTHREAD_COND_INITIALIZER;
 
   #define f_macro_thread_condition_t_clear(condition) condition = 0
+
+  #define f_macro_thread_condition_t_delete_simple(condition) f_thread_condition_delete(&condition);
 #endif // _di_f_thread_condition_t_
 
 /**
@@ -89,19 +91,65 @@ extern "C" {
 
   #define f_thread_conditions_t_initialize { 0, 0, 0 }
 
-  #define f_macro_thread_conditions_t_resize(status, conditions, length) f_macro_memory_structure_resize(status, conditions, f_thread_condition_t, length)
-  #define f_macro_thread_conditions_t_adjust(status, conditions, length) f_macro_memory_structure_adjust(status, conditions, f_thread_condition_t, length)
+  #define f_macro_thread_conditions_t_clear(conditions) f_macro_memory_structure_clear(conditions)
+
+  #define f_macro_thread_conditions_t_resize(status, conditions, length) status = f_thread_conditions_resize(length, &conditions);
+  #define f_macro_thread_conditions_t_adjust(status, conditions, length) status = f_thread_conditions_adjust(length, &conditions);
 
-  #define f_macro_thread_conditions_t_delete_simple(conditions)  f_macro_memory_structure_delete_simple(conditions, f_thread_condition_t)
-  #define f_macro_thread_conditions_t_destroy_simple(conditions) f_macro_memory_structure_destroy_simple(conditions, f_thread_condition_t)
+  #define f_macro_thread_conditions_t_delete_simple(conditions)  f_thread_conditions_resize(0, &conditions);
+  #define f_macro_thread_conditions_t_destroy_simple(conditions) f_thread_conditions_adjust(0, &conditions);
 
-  #define f_macro_thread_conditions_t_increase(status, conditions)            f_macro_memory_structure_increase(status, conditions, f_thread_condition_t)
-  #define f_macro_thread_conditions_t_increase_by(status, conditions, amount) f_macro_memory_structure_increase_by(status, conditions, f_thread_condition_t, amount)
-  #define f_macro_thread_conditions_t_decrease_by(status, conditions, amount) f_macro_memory_structure_decrease_by(status, conditions, f_thread_condition_t, amount)
-  #define f_macro_thread_conditions_t_decimate_by(status, conditions, amount) f_macro_memory_structure_decimate_by(status, conditions, f_thread_condition_t, amount)
+  #define f_macro_thread_conditions_t_increase(status, conditions)            status = f_thread_conditions_increase(conditions);
+  #define f_macro_thread_conditions_t_increase_by(status, conditions, amount) status = f_thread_conditions_increase_by(amount, conditions);
+  #define f_macro_thread_conditions_t_decrease_by(status, conditions, amount) status = f_thread_conditions_decrease_by(amount, conditions);
+  #define f_macro_thread_conditions_t_decimate_by(status, conditions, amount) status = f_thread_conditions_decimate_by(amount, conditions);
 #endif // _di_f_thread_conditions_t_
 
 /**
+ * A typedef representing pthread_cond_t.
+ */
+#ifndef _di_f_thread_condition_attribute_t_
+  typedef pthread_condattr_t f_thread_condition_attribute_t;
+
+  #define f_thread_condition_attribute_t_initialize 0;
+
+  #define f_macro_thread_condition_attribute_t_clear(attribute) attribute = 0
+
+  #define f_macro_thread_condition_attribute_t_delete_simple(attribute) f_thread_condition_attribute_delete(&attribute);
+#endif // _di_f_thread_condition_attribute_t_
+
+/**
+ * An array of thread condition attributes.
+ *
+ * array: the array of f_thread_condition_attribute_t.
+ * size: total amount of allocated space.
+ * used: total number of allocated spaces used.
+ */
+#ifndef _di_f_thread_condition_attributes_t_
+  typedef struct {
+    f_thread_condition_attribute_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } f_thread_condition_attributes_t;
+
+  #define f_thread_condition_attributes_t_initialize { 0, 0, 0 }
+
+  #define f_macro_thread_condition_attributes_t_clear(attributes) f_macro_memory_structure_clear(attributes)
+
+  #define f_macro_thread_condition_attributes_t_resize(status, attributes, length) status = f_thread_condition_attributes_resize(length, &attributes);
+  #define f_macro_thread_condition_attributes_t_adjust(status, attributes, length) status = f_thread_condition_attributes_adjust(length, &attributes);
+
+  #define f_macro_thread_condition_attributes_t_delete_simple(attributes)  f_thread_condition_attributes_resize(0, &condition_attributes);
+  #define f_macro_thread_condition_attributes_t_destroy_simple(attributes) f_thread_condition_attributes_adjust(0, &condition_attributes);
+
+  #define f_macro_thread_condition_attributes_t_increase(status, attributes)            status = f_thread_condition_attributes_increase(attributes);
+  #define f_macro_thread_condition_attributes_t_increase_by(status, attributes, amount) status = f_thread_condition_attributes_increase_by(amount, attributes);
+  #define f_macro_thread_condition_attributes_t_decrease_by(status, attributes, amount) status = f_thread_condition_attributes_decrease_by(amount, attributes);
+  #define f_macro_thread_condition_attributes_t_decimate_by(status, attributes, amount) status = f_thread_condition_attributes_decimate_by(amount, attributes);
+#endif // _di_f_thread_condition_attributes_t_
+
+/**
  * A typedef representing pthread_t.
  */
 #ifndef _di_f_thread_id_t_
index 1819f986db544f983eebf7773fe9255f183461bf..fda017d0e682f18882657cff50fcadb1aaf5081b 100644 (file)
@@ -64,9 +64,6 @@ extern "C" {
 
 #ifndef _di_f_thread_attribute_create_
   f_status_t f_thread_attribute_create(f_thread_attribute_t *attribute) {
-    #ifndef _di_level_0_parameter_checking_
-      if (!attribute) return F_status_set_error(F_parameter);
-    #endif // _di_level_0_parameter_checking_
 
     const int error = pthread_attr_init(attribute);
 
@@ -562,6 +559,159 @@ extern "C" {
   }
 #endif // _di_f_thread_compare_
 
+#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_
@@ -638,6 +788,99 @@ extern "C" {
   }
 #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_
index 436a86f65cafed801abfe5dd275336450cbc3bbc..13e8e0dc52cac8c2323bdcaa3df00132965f9ceb 100644 (file)
@@ -104,7 +104,8 @@ extern "C" {
  * Create (initialize) a thread attribute structure.
  *
  * @param attribute
- *   The thread attributes to create.
+ *   (optional) The attribute to set.
+ *   Set to NULL to not use (in which case the default attribute is used).
  *
  * @return
  *   F_none on success.
@@ -718,6 +719,215 @@ extern "C" {
 #endif // _di_f_thread_compare_
 
 /**
+ * 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_cond_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 string 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 string 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 string 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 string 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 string attributes array to a larger size.
+ *
+ * This will resize making the string 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 string 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
@@ -804,7 +1014,132 @@ extern "C" {
 #endif // _di_f_thread_condition_wait_timed_
 
 /**
- * Get the user account by the user id.
+ * Resize the string 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 string 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 string 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 string 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 string conditions array to a larger size.
+ *
+ * This will resize making the string 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 string 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.