]> Kevux Git Server - fll/commitdiff
Update: Finish adding functions to f_schedule.
authorKevin Day <Kevin@kevux.org>
Sun, 31 Aug 2025 20:49:01 +0000 (15:49 -0500)
committerKevin Day <Kevin@kevux.org>
Mon, 1 Sep 2025 01:41:23 +0000 (20:41 -0500)
This adds:
  - `f_schedule_affinity_get()`
  - `f_schedule_affinity_set()`
  - `f_schedule_attribute_get()`
  - `f_schedule_attribute_set()`
  - `f_schedule_policy_robin_interval_get()`
  - `f_schedule_priority_get_max()`
  - `f_schedule_priority_get_min()`
  - `f_schedule_yield()`

Note: the `f_schedule_attribute_get()` and `f_schedule_attribute_set()` have to use `syscall()` directly due to design problems with glibc.
The `struct sched_attr` is also an incomplete/broken type in glibc.
I have declared my own type based on the kernel structure.
It is unclear on how well this will work in practice.
I am also uncertain of the best way to mock a variadic function like `syscall()`.
The mocks for these are therefore incomplete.

28 files changed:
level_0/f_schedule/c/schedule.c
level_0/f_schedule/c/schedule.h
level_0/f_schedule/c/schedule/common.h
level_0/f_schedule/data/build/settings-mocks
level_0/f_schedule/data/build/settings-tests
level_0/f_schedule/tests/unit/c/mock-schedule.c
level_0/f_schedule/tests/unit/c/mock-schedule.h
level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-policy_get.c
level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-priority_get.c
level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-value_get.c
level_0/f_schedule/tests/unit/c/test-schedule-yield.c [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule-yield.h [new file with mode: 0644]
level_0/f_schedule/tests/unit/c/test-schedule.c
level_0/f_schedule/tests/unit/c/test-schedule.h

index 2c38f638a5f297b6812e6127e94fd4a4f08e1d18..f2d0e4664cddce6b81a729669a434567cee23c75 100644 (file)
@@ -4,6 +4,96 @@
 extern "C" {
 #endif
 
+#ifndef _di_f_schedule_affinity_get_
+  f_status_t f_schedule_affinity_get(const pid_t id, size_t * const size, cpu_set_t * const affinity) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!size) return F_status_set_error(F_parameter);
+      if (!affinity) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    cpu_set_t set = { 0 };
+
+    const int result = sched_getaffinity(id, *size, &set);
+
+    if (result == -1) {
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == ESRCH) return F_status_set_error(F_search);
+
+      return F_status_set_error(F_failure);
+    }
+
+    *size = (size_t) result;
+    *affinity = set;
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_affinity_get_
+
+#ifndef _di_f_schedule_affinity_set_
+  f_status_t f_schedule_affinity_set(const pid_t id, const size_t size, const cpu_set_t affinity) {
+
+    if (sched_setaffinity(id, size, &affinity) == -1) {
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == ESRCH) return F_status_set_error(F_search);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_affinity_set_
+
+#ifndef _di_f_schedule_attribute_get_
+  f_status_t f_schedule_attribute_get(const pid_t id, const unsigned int flags, const unsigned int size, f_schedule_attribute_t * const attribute) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!size) return F_status_set_error(F_parameter);
+      if (!attribute) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_schedule_attribute_t result = f_schedule_attribute_t_initialize;
+
+    if (syscall(SYS_sched_getattr, id, &result, size, flags) == -1) {
+      if (errno == E2BIG) return F_status_set_error(F_too_large);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ESRCH) return F_status_set_error(F_search);
+
+      return F_status_set_error(F_failure);
+    }
+
+    #undef internal_macro_f_schedule_attribute_get
+
+    *attribute = result;
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_attribute_get_
+
+#ifndef _di_f_schedule_attribute_set_
+  f_status_t f_schedule_attribute_set(const pid_t id, const unsigned int flags, const f_schedule_attribute_t attribute) {
+
+    // The standard shows the attribute as a non-constant.
+    // Create a new non-constant to pass the attributes such that this function can still safely specify attribute parameter as a constant.
+    f_schedule_attribute_t attr = attribute;
+
+    if (syscall(SYS_sched_setattr, id, &attr, flags) == -1) {
+      if (errno == E2BIG) return F_status_set_error(F_too_large);
+      if (errno == EBUSY) return F_status_set_error(F_busy);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EOPNOTSUPP) return F_status_set_error(F_support_not);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == ESRCH) return F_status_set_error(F_search);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_attribute_set_
+
 #ifndef _di_f_schedule_nice_
   f_status_t f_schedule_nice(const int niceness) {
 
@@ -45,6 +135,29 @@ extern "C" {
   }
 #endif // _di_f_schedule_policy_get_
 
+#ifndef _di_f_schedule_policy_robin_interval_get_
+  f_status_t f_schedule_policy_robin_interval_get(const pid_t id, f_time_spec_t * const interval) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!interval) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_time_spec_t result = f_time_spec_t_initialize;
+
+    if (sched_rr_get_interval(id, &result) == -1) {
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == ESRCH) return F_status_set_error(F_search);
+
+      return F_status_set_error(F_failure);
+    }
+
+    *interval = result;
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_policy_robin_interval_get_
+
 #ifndef _di_f_schedule_policy_set_
   f_status_t f_schedule_policy_set(const pid_t id, const int policy, const f_schedule_value_t * const value) {
     #ifndef _di_level_0_parameter_checking_
@@ -86,6 +199,46 @@ extern "C" {
   }
 #endif // _di_f_schedule_priority_get_
 
+#ifndef _di_f_schedule_priority_get_max_
+  f_status_t f_schedule_priority_get_max(const int type, int * const priority) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!priority) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int result = sched_get_priority_max(type);
+
+    if (result == -1) {
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+
+      return F_status_set_error(F_failure);
+    }
+
+    *priority = result;
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_priority_get_max_
+
+#ifndef _di_f_schedule_priority_get_min_
+  f_status_t f_schedule_priority_get_min(const int type, int * const priority) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!priority) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const int result = sched_get_priority_min(type);
+
+    if (result == -1) {
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+
+      return F_status_set_error(F_failure);
+    }
+
+    *priority = result;
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_priority_get_min_
+
 #ifndef _di_f_schedule_priority_set_
   f_status_t f_schedule_priority_set(const int type, const id_t id, const int priority) {
 
@@ -142,6 +295,17 @@ extern "C" {
   }
 #endif // _di_f_schedule_value_set_
 
+#ifndef _di_f_schedule_yield_
+  f_status_t f_schedule_yield() {
+
+    if (sched_yield() == -1) {
+      return F_status_set_error(F_failure);
+    }
+
+    return F_okay;
+  }
+#endif // _di_f_schedule_yield_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 9dca3df63e6efdab2579619a711b25018fd744cf..53cca54c652772aa20042429188130da993abf56 100644 (file)
 #ifndef _F_schedule_h
 #define _F_schedule_h
 
+// To enable appropiate sched.h functions and macros.
+#ifndef _GNU_SOURCE
+  #define _GNU_SOURCE
+#endif // _GNU_SOURCE
+
 // Libc includes.
 #include <sched.h>
 #include <sys/resource.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -28,6 +34,132 @@ extern "C" {
 #endif
 
 /**
+ * Get the processor affinity.
+ *
+ * @param id
+ *   The process ID.
+ *
+ *   If id is 0, then the affinity of the current process thread is returned.
+ * @param size
+ *   The size of the affinity set in bytes.
+ *
+ *   This must be set to the expected affinity set size.
+ *   If this value is too low, then F_parameter (with error bit) may be returned.
+ *
+ *   On success, the size is modified with the retrieved size of the affinity set.
+ *
+ *   Must not be NULL.
+ * @param affinity
+ *   The retrieved affinity set.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_buffer (with error bit) if unable to populate the affinity set.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set.
+ *   F_search (with error bit) if ID could not be found.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_getaffinity()
+ */
+#ifndef _di_f_schedule_affinity_get_
+  extern f_status_t f_schedule_affinity_get(const pid_t id, size_t * const size, cpu_set_t * const affinity);
+#endif // _di_f_schedule_affinity_get_
+
+/**
+ * Set the processor affinity.
+ *
+ * @param id
+ *   The process ID, process group ID, or user ID.
+ * @param size
+ *   The size of the affinity set in bytes.
+ * @param affinity
+ *   The affinity set to assign.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_buffer (with error bit) if unable to populate the affinity set.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set.
+ *   F_search (with error bit) if ID could not be found.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_setaffinity()
+ */
+#ifndef _di_f_schedule_affinity_set_
+  extern f_status_t f_schedule_affinity_set(const pid_t id, const size_t size, const cpu_set_t affinity);
+#endif // _di_f_schedule_affinity_set_
+
+/**
+ * Get the processor attribute.
+ *
+ * @param id
+ *   The process ID.
+ *
+ *   If id is 0, then the attribute of the current process thread is returned.
+ * @param flags
+ *   The flags beyond the standard f_schedule_attribute_*_d.
+ *   This is pretty much always 0.
+ * @param size
+ *   The size of the attribute structure in bytes..
+ * @param attribute
+ *   The retrieved attribute set.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_search (with error bit) if ID could not be found.
+ *   F_too_large (with error bit) if the size and attribute are too small.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_getattr()
+ * @see SYS_sched_getattr()
+ */
+#ifndef _di_f_schedule_attribute_get_
+  extern f_status_t f_schedule_attribute_get(const pid_t id, const unsigned int flags, const unsigned int size, f_schedule_attribute_t * const attribute);
+#endif // _di_f_schedule_attribute_get_
+
+/**
+ * Set the processor attribute.
+ *
+ * @param id
+ *   The process ID, process group ID, or user ID.
+ * @param flags
+ *   The flags beyond the standard f_schedule_attribute_*_d.
+ *   This is pretty much always 0.
+ * @param attribute
+ *   The attribute set to assign.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_busy (with error bit) if scheduler is too busy to perform operation.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set.
+ *   F_search (with error bit) if ID could not be found.
+ *   F_support_not (with error bit) if the system does not support this operation for the current scheduler policy.
+ *   F_too_large (with error bit) if the size and attribute are too small.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_setattr()
+ * @see SYS_sched_setattr()
+ */
+#ifndef _di_f_schedule_attribute_set_
+  extern f_status_t f_schedule_attribute_set(const pid_t id, const unsigned int flags, const f_schedule_attribute_t attribute);
+#endif // _di_f_schedule_attribute_set_
+
+/**
  * Set the niceness of the current process.
  *
  * The niceness affects the priority of the process for processor scheduling purposes.
@@ -86,6 +218,34 @@ extern "C" {
 #endif // _di_f_schedule_policy_get_
 
 /**
+ * Get the interval of the round-robin process policy.
+ *
+ * @param id
+ *   The process ID.
+ *
+ *   If id is 0, then the interval of the current process thread is returned.
+ * @param interval
+ *   The retrieved interval.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_buffer (with error bit) if unable to populate interval with the time.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_search (with error bit) if ID could not be found.
+ *   F_support_not (with error bit) if the system call is not supported.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_rr_get_interval()
+ */
+#ifndef _di_f_schedule_policy_robin_interval_get_
+  extern f_status_t f_schedule_policy_robin_interval_get(const pid_t id, f_time_spec_t * const interval);
+#endif // _di_f_schedule_policy_robin_interval_get_
+
+/**
  * Set the process policy.
  *
  * @param id
@@ -144,6 +304,60 @@ extern "C" {
 #endif // _di_f_schedule_priority_get_
 
 /**
+ * Get the maximum process priority available.
+ *
+ * @param type
+ *   The type being whose schedule priority is being retrieved
+ *   One of f_schedule_priority_*_d.
+ * @param priority
+ *   The retrieved priority.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_access_denied (with error bit) If caller has insufficient priviledges to get the priority.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set.
+ *   F_search (with error bit) if ID could not be found.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_get_priority_max()
+ */
+#ifndef _di_f_schedule_priority_get_max_
+  extern f_status_t f_schedule_priority_get_max(const int type, int * const priority);
+#endif // _di_f_schedule_priority_get_max_
+
+/**
+ * Get the minimum process priority available.
+ *
+ * @param type
+ *   The type being whose schedule priority is being retrieved
+ *   One of f_schedule_priority_*_d.
+ * @param priority
+ *   The retrieved priority.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_access_denied (with error bit) If caller has insufficient priviledges to get the priority.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set.
+ *   F_search (with error bit) if ID could not be found.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_get_priority_min()
+ */
+#ifndef _di_f_schedule_priority_get_min_
+  extern f_status_t f_schedule_priority_get_min(const int type, int * const priority);
+#endif // _di_f_schedule_priority_get_min_
+
+/**
  * Set the process priority.
  *
  * @param type
@@ -222,17 +436,20 @@ extern "C" {
   extern f_status_t f_schedule_value_set(const pid_t id, const f_schedule_value_t * const value);
 #endif // _di_f_schedule_value_set_
 
-/*
- * @todo: add all of these:
-       sched_get_priority_max()
-       sched_get_priority_min()
-       sched_rr_get_interval()
-       sched_yield()
-       sched_setaffinity()
-       sched_getaffinity()
-       sched_setattr()
-       sched_getattr()
-*/
+/**
+ * Explicitly release contol of the CPU so that other process threads can utilize the CPU.
+ *
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see sched_yield()
+ */
+#ifndef _di_f_schedule_yield_
+  extern f_status_t f_schedule_yield();
+#endif // _di_f_schedule_yield_
 
 #ifdef __cplusplus
 } // extern "C"
index 2f1d6fa192b858ea5a631d409d3baf7225e2d118..b53d2234216b5b6109012df707243ae88f33ebb2 100644 (file)
@@ -17,6 +17,24 @@ extern "C" {
 #endif
 
 /**
+ * Thread scheduler attribute defines.
+ *
+ * f_schedule_attribute_*_d:
+ *   - clamp_max:  The schedule util maximum is set.
+ *   - clamp_min:  The schedule util minimum is set.
+ *   - fork_reset: Forked child processes do not inherit scheduling policies.
+ *   - overrun:    Allow accessing overrun information.
+ *   - reclaim:    Enabling reclaiming unused bandwidth.
+ */
+#ifndef _di_f_schedule_attribute_d_
+  #define f_schedule_attribute_clamp_max_d  SCHED_FLAG_UTIL_CLAMP_MAX
+  #define f_schedule_attribute_clamp_min_d  SCHED_FLAG_UTIL_CLAMP_MIN
+  #define f_schedule_attribute_fork_reset_d SCHED_FLAG_RESET_ON_FORK
+  #define f_schedule_attribute_overrun_d    SCHED_FLAG_DL_OVERRUN
+  #define f_schedule_attribute_reclaim_d    SCHED_FLAG_RECLAIM
+#endif // _di_f_schedule_attribute_d_
+
+/**
  * Thread scheduler policy defines.
  *
  * f_schedule_policy_*_d:
@@ -49,6 +67,92 @@ extern "C" {
 #endif // _di_f_schedule_priority_d_
 
 /**
+ * A typedef for representing a sched_att structure from <linux/sched/types.h>.
+ *
+ * Note: "struct sched_attr" is an incomplete type on systems like glibc.
+ *       The approach here is to entirely replace it and use syscalls.
+ *
+ * The following is the known structure (be sure to check types.h for the actual structure on any particular system):
+ *   - __u32 size
+ *   - __u32 sched_policy
+ *   - __u64 sched_flags
+ *   - __s32 sched_nice
+ *   - __u32 sched_priority
+ *   - __u64 sched_runtime
+ *   - __u64 sched_deadline
+ *   - __u64 sched_period
+ *   - __u32 sched_util_min
+ *   - __u32 sched_util_max
+ */
+#ifndef _di_f_schedule_attribute_t_
+  typedef struct {
+    uint32_t size;
+    uint32_t sched_policy;
+    uint64_t sched_flags;
+    int32_t sched_nice;
+    uint32_t sched_priority;
+    uint64_t sched_runtime;
+    uint64_t sched_deadline;
+    uint64_t sched_period;
+  } f_schedule_attribute_t;
+
+  #define f_schedule_attribute_t_initialize { \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+  }
+
+  #define macro_f_schedule_attribute_t_initialize_1(size) { \
+    size, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+  }
+
+  #define macro_f_schedule_attribute_t_initialize_2(size, policy, flags) { \
+    size, \
+    policy, \
+    flags, \
+    0, \
+    0, \
+    0, \
+    0, \
+    0, \
+  }
+
+  #define macro_f_schedule_attribute_t_initialize_3(size, policy, flags, nice, priority) { \
+    size, \
+    policy, \
+    flags, \
+    nice, \
+    priority, \
+    0, \
+    0, \
+    0, \
+  }
+
+  #define macro_f_schedule_attribute_t_initialize_4(size, policy, flags, nice, priority, runtime, deadline, period) { \
+    size, \
+    policy, \
+    flags, \
+    nice, \
+    priority, \
+    runtime, \
+    deadline, \
+    period, \
+  }
+#endif // _di_f_schedule_attribute_t_
+
+/**
  * A typedef for representing a sched_param structure from <sched.h>.
  *
  * Note that the actual path might be something like <bits/types/struct_sched_param.h>.
index af58b0ca59e92499d3fc28f7d592a0e210d6909d..267f76640a453753948ee3a3893bfcff8be8488a 100644 (file)
@@ -66,8 +66,17 @@ flags_library -fPIC
 # Inject mocks.
 flags -Wl,--wrap=getpriority
 flags -Wl,--wrap=nice
+flags -Wl,--wrap=sched_getaffinity
+#flags -Wl,--wrap=sched_getattr
+flags -Wl,--wrap=sched_get_priority_max
+flags -Wl,--wrap=sched_get_priority_min
 flags -Wl,--wrap=sched_getparam
 flags -Wl,--wrap=sched_getscheduler
+flags -Wl,--wrap=sched_rr_get_interval
+flags -Wl,--wrap=sched_setaffinity
+#flags -Wl,--wrap=sched_setattr
 flags -Wl,--wrap=sched_setparam
 flags -Wl,--wrap=sched_setscheduler
+flags -Wl,--wrap=sched_yield
 flags -Wl,--wrap=setpriority
+#flags -Wl,--wrap=syscall
index 670b31b0fb8713744e9cd0d4493ca9e4e0653168..30c164ea81024617f200b205f4cce0f5e913ce05 100644 (file)
@@ -25,10 +25,13 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_schedule
 
+build_sources_program test-schedule-affinity_get.c test-schedule-affinity_set.c
+build_sources_program test-schedule-attribute_get.c test-schedule-attribute_set.c
 build_sources_program test-schedule-nice.c
-build_sources_program test-schedule-policy_get.c test-schedule-policy_set.c
-build_sources_program test-schedule-priority_get.c test-schedule-priority_set.c
+build_sources_program test-schedule-policy_get.c test-schedule-policy_robin_interval_get.c test-schedule-policy_set.c
+build_sources_program test-schedule-priority_get.c test-schedule-priority_get_max.c test-schedule-priority_get_min.c test-schedule-priority_set.c
 build_sources_program test-schedule-value_get.c test-schedule-value_set.c
+build_sources_program test-schedule-yield.c
 build_sources_program test-schedule.c
 
 build_script no
index 513aabc204844214d32fa9abdacf7408ad0e544a..9e1726cac47d4c9ac10748d15454e301e9865242 100644 (file)
@@ -4,6 +4,8 @@
 extern "C" {
 #endif
 
+int mock_unwrap_syscall = 1;
+
 int __wrap_getpriority(int which, id_t who) {
 
   const bool failure = mock_type(bool);
@@ -30,6 +32,92 @@ int __wrap_nice(int inc) {
   return 0;
 }
 
+int __wrap_sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sched_setattr(pid_t pid, f_schedule_attribute_t *attr, unsigned int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  cpu_set_t *mock_mask = mock_ptr_type(cpu_set_t *);
+
+  *mask = *mock_mask;
+
+  return mock_type(int);
+}
+
+int __wrap_sched_getattr(pid_t pid, f_schedule_attribute_t *attr, unsigned int size, unsigned int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  f_schedule_attribute_t *mock_attr = mock_ptr_type(f_schedule_attribute_t *);
+
+  *attr = *mock_attr;
+
+  return 0;
+}
+
+int __wrap_sched_get_priority_max(int policy) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
+int __wrap_sched_get_priority_min(int policy) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
 int __wrap_sched_getparam(pid_t pid, struct sched_param *param) {
 
   const bool failure = mock_type(bool);
@@ -60,6 +148,23 @@ int __wrap_sched_getscheduler(pid_t pid) {
   return mock_type(int);
 }
 
+int __wrap_sched_rr_get_interval(pid_t pid, struct timespec *tp) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  f_time_spec_t *mock_time = mock_ptr_type(f_time_spec_t *);
+
+  *tp = *mock_time;
+
+  return 0;
+}
+
 int __wrap_sched_setparam(pid_t pid, const struct sched_param *param) {
 
   const bool failure = mock_type(bool);
@@ -99,6 +204,27 @@ int __wrap_setpriority(int which, id_t who, int prio) {
   return 0;
 }
 
+int __wrap_sched_yield() {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+/* How can this be done?
+long __wrap_syscall(long number, ...) {
+
+  if (mock_unwrap_syscall) {
+    return __real_syscall(number, );
+  }
+} */
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 9f1c93de6bbe510c9472911f2bd78bc5249894c9..97ef99ab6a6a9d656baaab0bf86508750e061b91 100644 (file)
@@ -28,14 +28,26 @@ extern "C" {
 
 const static int mock_errno_generic = 32767;
 
+extern int mock_unwrap_syscall;
+
+extern long __real_syscall(long number, ...);
+
 extern int __wrap_getpriority(int which, id_t who);
 extern int __wrap_nice(int inc);
+extern int __wrap_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
+extern int __wrap_sched_getattr(pid_t pid, f_schedule_attribute_t *attr, unsigned int size, unsigned int flags);
+extern int __wrap_sched_get_priority_max(int policy);
+extern int __wrap_sched_get_priority_min(int policy);
 extern int __wrap_sched_getparam(pid_t pid, struct sched_param *param);
 extern int __wrap_sched_getscheduler(pid_t pid);
+extern int __wrap_sched_rr_get_interval(pid_t pid, struct timespec *tp);
+extern int __wrap_sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
+extern int __wrap_sched_setattr(pid_t pid, f_schedule_attribute_t *attr, unsigned int flags);
 extern int __wrap_sched_setparam(pid_t pid, const struct sched_param *param);
 extern int __wrap_sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
 extern int __wrap_setpriority(int which, id_t who, int prio);
-
+extern int __wrap_sched_yield();
+//extern long __wrap_syscall(long number, ...);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.c
new file mode 100644 (file)
index 0000000..1fdb181
--- /dev/null
@@ -0,0 +1,89 @@
+#include "test-schedule.h"
+#include "test-schedule-affinity_get.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_affinity_get__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EFAULT,
+      EINVAL,
+      EPERM,
+      ESRCH,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_buffer,
+      F_parameter,
+      F_prohibited,
+      F_search,
+      F_failure,
+    };
+
+    for (int i = 0; i < 5; ++i) {
+
+      size_t size = 0;
+      cpu_set_t affinity = { 0 };
+
+      will_return(__wrap_sched_getaffinity, true);
+      will_return(__wrap_sched_getaffinity, errnos[i]);
+
+      const f_status_t status = f_schedule_affinity_get(0, &size, &affinity);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_affinity_get__parameter_checking(void **state) {
+
+  size_t size = 0;
+  cpu_set_t affinity = { 0 };
+
+  {
+    const f_status_t status = f_schedule_affinity_get(0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_schedule_affinity_get(0, &size, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_schedule_affinity_get(0, 0, &affinity);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_schedule_affinity_get__works(void **state) {
+
+  const size_t expected_size = 2;
+  cpu_set_t expected_affinity = { 0 };
+
+  {
+    size_t size = 1;
+    cpu_set_t affinity = { 0 };
+
+    will_return(__wrap_sched_getaffinity, false);
+    will_return(__wrap_sched_getaffinity, &expected_affinity);
+    will_return(__wrap_sched_getaffinity, expected_size);
+
+    const f_status_t status = f_schedule_affinity_get(0, &size, &affinity);
+
+    assert_int_equal(status, F_okay);
+    assert_int_equal(size, expected_size);
+    assert_int_equal(affinity.__bits[0], expected_affinity.__bits[0]);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-affinity_get.h
new file mode 100644 (file)
index 0000000..0ff609a
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_affinity_get_h
+#define _TEST__F_schedule_affinity_get_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_affinity_get()
+ */
+extern void test__f_schedule_affinity_get__fails(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_schedule_affinity_get()
+ */
+extern void test__f_schedule_affinity_get__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_affinity_get()
+ */
+extern void test__f_schedule_affinity_get__works(void **state);
+
+#endif // _TEST__F_schedule_affinity_get_h
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.c b/level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.c
new file mode 100644 (file)
index 0000000..77fdf38
--- /dev/null
@@ -0,0 +1,56 @@
+#include "test-schedule.h"
+#include "test-schedule-affinity_set.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_affinity_set__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EFAULT,
+      EINVAL,
+      EPERM,
+      ESRCH,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_buffer,
+      F_parameter,
+      F_prohibited,
+      F_search,
+      F_failure,
+    };
+
+    for (int i = 0; i < 5; ++i) {
+
+      cpu_set_t affinity = { 0 };
+
+      will_return(__wrap_sched_setaffinity, true);
+      will_return(__wrap_sched_setaffinity, errnos[i]);
+
+      const f_status_t status = f_schedule_affinity_set(0, 0, affinity);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_affinity_set__works(void **state) {
+
+  {
+    cpu_set_t affinity = { 0 };
+
+    will_return(__wrap_sched_setaffinity, false);
+
+    const f_status_t status = f_schedule_affinity_set(0, 0, affinity);
+
+    assert_int_equal(status, F_okay);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.h b/level_0/f_schedule/tests/unit/c/test-schedule-affinity_set.h
new file mode 100644 (file)
index 0000000..0087629
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_affinity_set_h
+#define _TEST__F_schedule_affinity_set_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_affinity_set()
+ */
+extern void test__f_schedule_affinity_set__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_affinity_set()
+ */
+extern void test__f_schedule_affinity_set__works(void **state);
+
+#endif // _TEST__F_schedule_affinity_set_h
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.c
new file mode 100644 (file)
index 0000000..fceae79
--- /dev/null
@@ -0,0 +1,67 @@
+#include "test-schedule.h"
+#include "test-schedule-attribute_get.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_attribute_get__fails(void **state) {
+
+  {
+    int errnos[] = {
+      E2BIG,
+      EINVAL,
+      ESRCH,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_too_large,
+      F_parameter,
+      F_search,
+      F_failure,
+    };
+
+    for (int i = 0; i < 4; ++i) {
+
+      f_schedule_attribute_t attribute = f_schedule_attribute_t_initialize;
+
+      will_return(__wrap_sched_getattr, true);
+      will_return(__wrap_sched_getattr, errnos[i]);
+
+      const f_status_t status = f_schedule_attribute_get(0, 0, 0, &attribute);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_attribute_get__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_schedule_attribute_get(0, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_schedule_attribute_get__works(void **state) {
+
+  f_schedule_attribute_t expected_attribute = macro_f_schedule_attribute_t_initialize_1(sizeof(f_schedule_attribute_t));
+
+  {
+    f_schedule_attribute_t attribute = f_schedule_attribute_t_initialize;
+
+    //will_return(__wrap_sched_getattr, false);
+    //will_return(__wrap_sched_getattr, &expected_attribute);
+
+    const f_status_t status = f_schedule_attribute_get(0, 0, expected_attribute.size, &attribute);
+
+    assert_int_equal(status, F_okay);
+    assert_int_equal(attribute.size, expected_attribute.size);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-attribute_get.h
new file mode 100644 (file)
index 0000000..6c4c1b1
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_attribute_get_h
+#define _TEST__F_schedule_attribute_get_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_attribute_get()
+ */
+extern void test__f_schedule_attribute_get__fails(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_schedule_attribute_get()
+ */
+extern void test__f_schedule_attribute_get__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_attribute_get()
+ */
+extern void test__f_schedule_attribute_get__works(void **state);
+
+#endif // _TEST__F_schedule_attribute_get_h
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.c b/level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.c
new file mode 100644 (file)
index 0000000..be229bd
--- /dev/null
@@ -0,0 +1,60 @@
+#include "test-schedule.h"
+#include "test-schedule-attribute_set.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_attribute_set__fails(void **state) {
+
+  const f_schedule_attribute_t attribute = f_schedule_attribute_t_initialize;
+
+  {
+    int errnos[] = {
+      E2BIG,
+      EBUSY,
+      EINVAL,
+      EOPNOTSUPP,
+      EPERM,
+      ESRCH,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_too_large,
+      F_busy,
+      F_parameter,
+      F_support_not,
+      F_prohibited,
+      F_search,
+      F_failure,
+    };
+
+    for (int i = 0; i < 7; ++i) {
+
+      will_return(__wrap_sched_setattr, true);
+      will_return(__wrap_sched_setattr, errnos[i]);
+
+      const f_status_t status = f_schedule_attribute_set(0, 0, attribute);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_attribute_set__works(void **state) {
+
+  const f_schedule_attribute_t attribute = f_schedule_attribute_t_initialize;
+
+  {
+    //will_return(__wrap_sched_setattr, false);
+
+    const f_status_t status = f_schedule_attribute_set(0, 0, attribute);
+
+    assert_int_equal(status, F_okay);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.h b/level_0/f_schedule/tests/unit/c/test-schedule-attribute_set.h
new file mode 100644 (file)
index 0000000..707d729
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_attribute_set_h
+#define _TEST__F_schedule_attribute_set_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_attribute_set()
+ */
+extern void test__f_schedule_attribute_set__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_attribute_set()
+ */
+extern void test__f_schedule_attribute_set__works(void **state);
+
+#endif // _TEST__F_schedule_attribute_set_h
index d745fb2133ef3cfd8928436302e5eed869a06c4f..1ca9b6ae8df79dcf5cd4dfc01ed017bd7a883933 100644 (file)
@@ -45,7 +45,6 @@ void test__f_schedule_policy_get__parameter_checking(void **state) {
   }
 }
 
-
 void test__f_schedule_policy_get__works(void **state) {
 
   const int expected = 2;
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.c
new file mode 100644 (file)
index 0000000..959db9d
--- /dev/null
@@ -0,0 +1,70 @@
+#include "test-schedule.h"
+#include "test-schedule-policy_robin_interval_get.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_policy_robin_interval_get__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EFAULT,
+      EINVAL,
+      EPERM,
+      ESRCH,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_buffer,
+      F_parameter,
+      F_prohibited,
+      F_search,
+      F_failure,
+    };
+
+    for (int i = 0; i < 5; ++i) {
+
+      f_time_spec_t time = f_time_spec_t_initialize;
+
+      will_return(__wrap_sched_rr_get_interval, true);
+      will_return(__wrap_sched_rr_get_interval, errnos[i]);
+
+      const f_status_t status = f_schedule_policy_robin_interval_get(0, &time);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_policy_robin_interval_get__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_schedule_policy_robin_interval_get(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_schedule_policy_robin_interval_get__works(void **state) {
+
+  f_time_spec_t expected = macro_f_time_spec_t_initialize_1(100, 200);
+
+  {
+    f_time_spec_t time = f_time_spec_t_initialize;
+
+    will_return(__wrap_sched_rr_get_interval, false);
+    will_return(__wrap_sched_rr_get_interval, &expected);
+
+    const f_status_t status = f_schedule_policy_robin_interval_get(0, &time);
+
+    assert_int_equal(status, F_okay);
+    assert_int_equal(time.tv_sec, expected.tv_sec);
+    assert_int_equal(time.tv_nsec, expected.tv_nsec);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-policy_robin_interval_get.h
new file mode 100644 (file)
index 0000000..d92f79f
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_policy_robin_interval_get_h
+#define _TEST__F_schedule_policy_robin_interval_get_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_policy_robin_interval_get()
+ */
+extern void test__f_schedule_policy_robin_interval_get__fails(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_schedule_policy_robin_interval_get()
+ */
+extern void test__f_schedule_policy_robin_interval_get__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_policy_robin_interval_get()
+ */
+extern void test__f_schedule_policy_robin_interval_get__works(void **state);
+
+#endif // _TEST__F_schedule_policy_robin_interval_get_h
index 3ca582fd0f5dbc58818cb45a76e5714d0edaaf9d..d5793ba3d8379468465d11bb7a7d94fab24c4ed9 100644 (file)
@@ -47,7 +47,6 @@ void test__f_schedule_priority_get__parameter_checking(void **state) {
   }
 }
 
-
 void test__f_schedule_priority_get__works(void **state) {
 
   const int expected = 2;
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.c b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.c
new file mode 100644 (file)
index 0000000..59085e1
--- /dev/null
@@ -0,0 +1,63 @@
+#include "test-schedule.h"
+#include "test-schedule-priority_get_max.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_priority_get_max__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EINVAL,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_parameter,
+      F_failure,
+    };
+
+    for (int i = 0; i < 2; ++i) {
+
+      int priority = 0;
+
+      will_return(__wrap_sched_get_priority_max, true);
+      will_return(__wrap_sched_get_priority_max, errnos[i]);
+
+      const f_status_t status = f_schedule_priority_get_max(0, &priority);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_priority_get_max__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_schedule_priority_get_max(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_schedule_priority_get_max__works(void **state) {
+
+  const int expected = 2;
+
+  {
+    int priority = 0;
+
+    will_return(__wrap_sched_get_priority_max, false);
+    will_return(__wrap_sched_get_priority_max, expected);
+
+    const f_status_t status = f_schedule_priority_get_max(0, &priority);
+
+    assert_int_equal(status, F_okay);
+    assert_int_equal(priority, expected);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.h b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_max.h
new file mode 100644 (file)
index 0000000..656610e
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_priority_get_max_h
+#define _TEST__F_schedule_priority_get_max_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_priority_get_max()
+ */
+extern void test__f_schedule_priority_get_max__fails(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_schedule_priority_get_max()
+ */
+extern void test__f_schedule_priority_get_max__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_priority_get_max()
+ */
+extern void test__f_schedule_priority_get_max__works(void **state);
+
+#endif // _TEST__F_schedule_priority_get_max_h
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.c b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.c
new file mode 100644 (file)
index 0000000..150d249
--- /dev/null
@@ -0,0 +1,63 @@
+#include "test-schedule.h"
+#include "test-schedule-priority_get_min.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_priority_get_min__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EINVAL,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_parameter,
+      F_failure,
+    };
+
+    for (int i = 0; i < 2; ++i) {
+
+      int priority = 0;
+
+      will_return(__wrap_sched_get_priority_min, true);
+      will_return(__wrap_sched_get_priority_min, errnos[i]);
+
+      const f_status_t status = f_schedule_priority_get_min(0, &priority);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_priority_get_min__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_schedule_priority_get_min(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_schedule_priority_get_min__works(void **state) {
+
+  const int expected = 2;
+
+  {
+    int priority = 0;
+
+    will_return(__wrap_sched_get_priority_min, false);
+    will_return(__wrap_sched_get_priority_min, expected);
+
+    const f_status_t status = f_schedule_priority_get_min(0, &priority);
+
+    assert_int_equal(status, F_okay);
+    assert_int_equal(priority, expected);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.h b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get_min.h
new file mode 100644 (file)
index 0000000..2b902c0
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_priority_get_min_h
+#define _TEST__F_schedule_priority_get_min_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_priority_get_min()
+ */
+extern void test__f_schedule_priority_get_min__fails(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_schedule_priority_get_min()
+ */
+extern void test__f_schedule_priority_get_min__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_priority_get_min()
+ */
+extern void test__f_schedule_priority_get_min__works(void **state);
+
+#endif // _TEST__F_schedule_priority_get_min_h
index 6cff16f7d28b61b126e14638360a260081195ba4..0171ff1958a99c343506499840c6c78b88346659 100644 (file)
@@ -45,7 +45,6 @@ void test__f_schedule_value_get__parameter_checking(void **state) {
   }
 }
 
-
 void test__f_schedule_value_get__works(void **state) {
 
   f_schedule_value_t expected = macro_f_schedule_value_t_initialize_1(2);
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-yield.c b/level_0/f_schedule/tests/unit/c/test-schedule-yield.c
new file mode 100644 (file)
index 0000000..c90cc55
--- /dev/null
@@ -0,0 +1,44 @@
+#include "test-schedule.h"
+#include "test-schedule-yield.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_schedule_yield__fails(void **state) {
+
+  {
+    int errnos[] = {
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_failure,
+    };
+
+    for (int i = 0; i < 1; ++i) {
+
+      will_return(__wrap_sched_yield, true);
+      will_return(__wrap_sched_yield, errnos[i]);
+
+      const f_status_t status = f_schedule_yield();
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_schedule_yield__works(void **state) {
+
+  {
+    will_return(__wrap_sched_yield, false);
+
+    const f_status_t status = f_schedule_yield();
+
+    assert_int_equal(status, F_okay);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-yield.h b/level_0/f_schedule/tests/unit/c/test-schedule-yield.h
new file mode 100644 (file)
index 0000000..8815e19
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Schedule
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the schedule project.
+ */
+#ifndef _TEST__F_schedule_yield_h
+#define _TEST__F_schedule_yield_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_schedule_yield()
+ */
+extern void test__f_schedule_yield__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_schedule_yield()
+ */
+extern void test__f_schedule_yield__works(void **state);
+
+#endif // _TEST__F_schedule_yield_h
index ec808131d3229dad4c0efa2498eea371d35757e4..4ceb251d11b001fc94efcd7bfdb0e915ff622dfb 100644 (file)
@@ -19,6 +19,18 @@ int setdown(void **state) {
 int main(void) {
 
   const struct CMUnitTest tests[] = {
+    cmocka_unit_test(test__f_schedule_affinity_get__fails),
+    cmocka_unit_test(test__f_schedule_affinity_get__works),
+
+    cmocka_unit_test(test__f_schedule_affinity_set__fails),
+    cmocka_unit_test(test__f_schedule_affinity_set__works),
+
+    //cmocka_unit_test(test__f_schedule_attribute_get__fails),
+    cmocka_unit_test(test__f_schedule_attribute_get__works),
+
+    //cmocka_unit_test(test__f_schedule_attribute_set__fails),
+    cmocka_unit_test(test__f_schedule_attribute_set__works),
+
     cmocka_unit_test(test__f_schedule_nice__fails),
     cmocka_unit_test(test__f_schedule_nice__works),
 
@@ -28,12 +40,21 @@ int main(void) {
     cmocka_unit_test(test__f_schedule_policy_get__fails),
     cmocka_unit_test(test__f_schedule_policy_get__works),
 
+    cmocka_unit_test(test__f_schedule_policy_robin_interval_get__fails),
+    cmocka_unit_test(test__f_schedule_policy_robin_interval_get__works),
+
     cmocka_unit_test(test__f_schedule_policy_set__fails),
     cmocka_unit_test(test__f_schedule_policy_set__works),
 
     cmocka_unit_test(test__f_schedule_priority_get__fails),
     cmocka_unit_test(test__f_schedule_priority_get__works),
 
+    cmocka_unit_test(test__f_schedule_priority_get_max__fails),
+    cmocka_unit_test(test__f_schedule_priority_get_max__works),
+
+    cmocka_unit_test(test__f_schedule_priority_get_min__fails),
+    cmocka_unit_test(test__f_schedule_priority_get_min__works),
+
     cmocka_unit_test(test__f_schedule_priority_set__fails),
     cmocka_unit_test(test__f_schedule_priority_set__works),
 
@@ -43,14 +64,25 @@ int main(void) {
     cmocka_unit_test(test__f_schedule_value_set__fails),
     cmocka_unit_test(test__f_schedule_value_set__works),
 
+    cmocka_unit_test(test__f_schedule_yield__fails),
+    cmocka_unit_test(test__f_schedule_yield__works),
+
     #ifndef _di_level_0_parameter_checking_
+      cmocka_unit_test(test__f_schedule_affinity_get__parameter_checking),
+      // f_schedule_affinity_set() doesn't use parameter checking.
+      cmocka_unit_test(test__f_schedule_attribute_get__parameter_checking),
+      // f_schedule_attribute_set() doesn't use parameter checking.
       // f_schedule_nice() doesn't use parameter checking.
       cmocka_unit_test(test__f_schedule_policy_get__parameter_checking),
+      cmocka_unit_test(test__f_schedule_policy_robin_interval_get__parameter_checking),
       cmocka_unit_test(test__f_schedule_policy_set__parameter_checking),
       cmocka_unit_test(test__f_schedule_priority_get__parameter_checking),
+      cmocka_unit_test(test__f_schedule_priority_get_max__parameter_checking),
+      cmocka_unit_test(test__f_schedule_priority_get_min__parameter_checking),
       // f_schedule_priority_set() doesn't use parameter checking.
       cmocka_unit_test(test__f_schedule_value_get__parameter_checking),
       cmocka_unit_test(test__f_schedule_value_set__parameter_checking),
+      // f_schedule_yield() doesn't use parameter checking.
     #endif // _di_level_0_parameter_checking_
   };
 
index 8c5932b8aec66c262bc64674471a1556cd7cac28..c8c22a6b33faa847fc4e2dd0d6fdeb3191e99b91 100644 (file)
 #include "mock-schedule.h"
 
 // Test includes.
+#include "test-schedule-affinity_get.h"
+#include "test-schedule-affinity_set.h"
+#include "test-schedule-attribute_get.h"
+#include "test-schedule-attribute_set.h"
 #include "test-schedule-nice.h"
 #include "test-schedule-policy_get.h"
+#include "test-schedule-policy_robin_interval_get.h"
 #include "test-schedule-policy_set.h"
 #include "test-schedule-priority_get.h"
+#include "test-schedule-priority_get_max.h"
+#include "test-schedule-priority_get_min.h"
 #include "test-schedule-priority_set.h"
 #include "test-schedule-value_get.h"
 #include "test-schedule-value_set.h"
+#include "test-schedule-yield.h"
 
 #ifdef __cplusplus
 extern "C" {