浏览代码

faux.schev: Unfinished subsystem

Serj Kalichev 3 年之前
父节点
当前提交
f57a013e2d
共有 3 个文件被更改,包括 191 次插入25 次删除
  1. 1 0
      faux/list.h
  2. 19 7
      faux/list/list.c
  3. 171 18
      faux/schev/schev.c

+ 1 - 0
faux/list.h

@@ -51,6 +51,7 @@ faux_list_node_t *faux_list_add(faux_list_t *list, void *data);
 faux_list_node_t *faux_list_add_find(faux_list_t *list, void *data);
 void *faux_list_takeaway(faux_list_t *list, faux_list_node_t *node);
 int faux_list_del(faux_list_t *list, faux_list_node_t *node);
+void faux_list_empty(faux_list_t *list);
 
 faux_list_node_t *faux_list_match_node(const faux_list_t *list,
 	faux_list_kcmp_fn matchFn, const void *userkey,

+ 19 - 7
faux/list/list.c

@@ -230,16 +230,13 @@ faux_list_t *faux_list_new(faux_list_sorted_t sorted, faux_list_unique_t unique,
 }
 
 
-/** @brief Free bidirectional list
+/** @brief Empty list
  *
- * Free all nodes and user data from list and finally
- * free the list itself. It uses special callback
- * function specified by user (while faux_list_new()) to free the abstract
- * user data.
+ * Removes and frees all list entries.
  *
- * @param [in] list List to free.
+ * @param [in] list List to empty.
  */
-void faux_list_free(faux_list_t *list)
+void faux_list_empty(faux_list_t *list)
 {
 	faux_list_node_t *iter = NULL;
 
@@ -249,6 +246,21 @@ void faux_list_free(faux_list_t *list)
 	while ((iter = faux_list_head(list))) {
 		faux_list_del(list, iter);
 	}
+}
+
+
+/** @brief Free bidirectional list
+ *
+ * Free all nodes and user data from list and finally
+ * free the list itself. It uses special callback
+ * function specified by user (while faux_list_new()) to free the abstract
+ * user data.
+ *
+ * @param [in] list List to free.
+ */
+void faux_list_free(faux_list_t *list)
+{
+	faux_list_empty(list);
 	faux_free(list);
 }
 

+ 171 - 18
faux/schev/schev.c

@@ -52,37 +52,47 @@ void faux_schev_free(faux_schev_t *schev)
 }
 
 
+static int _schev_schedule_ev(faux_schev_t *schev, faux_ev_t *ev)
+{
+	faux_list_node_t *node = NULL;
+
+	assert(schev);
+	assert(ev);
+	if (!schev || !ev)
+		return -1;
+
+	node = faux_list_add(schev->list, ev);
+	if (!node) // Something went wrong
+		return -1;
+
+	return 0;
+}
+
 /** @brief Internal function to add event to scheduling list.
  *
  * @param [in] sched Allocated and initialized sched object.
  * @param [in] time Absolute time of future event.
- * @param [in] Event ID.
- * @param [in] Pointer to arbitrary data linked to event.
- * @param [in] Periodic flag.
- * @param [in] Number of cycles (FAUX_SCHEV_CYCLES_INFINITE for infinite).
- * @param [in] Periodic interval.
+ * @param [in] ev_id Event ID.
+ * @param [in] data Pointer to arbitrary data linked to event.
+ * @param [in] periodic Periodic flag.
+ * @param [in] period Periodic interval.
+ * @param [in] cycles_num Number of cycles (FAUX_SCHEV_CYCLES_INFINITE for infinite).
  * @return 0 - success, < 0 on error.
  */
 static int _schev_schedule(faux_schev_t *schev, const struct timespec *time,
 	int ev_id, void *data, faux_schev_periodic_t periodic,
-	const struct timespec *interval, int cycles_num)
+	const struct timespec *period, int cycles_num)
 {
 	faux_ev_t *ev = NULL;
-	faux_list_node_t *node = NULL;
-
-	assert(schev);
-	if (!schev)
-		return -1;
 
 	ev = faux_ev_new(time, ev_id, data);
 	assert(ev);
 	if (!ev)
 		return -1;
 	if (FAUX_SCHEV_PERIODIC == periodic)
-		faux_ev_periodic(ev, interval, cycles_num);
+		faux_ev_periodic(ev, period, cycles_num);
 
-	node = faux_list_add(schev->list, ev);
-	if (!node) { // Something went wrong
+	if (_schev_schedule_ev(schev, ev) < 0) { // Something went wrong
 		faux_ev_free(ev);
 		return -1;
 	}
@@ -95,8 +105,8 @@ static int _schev_schedule(faux_schev_t *schev, const struct timespec *time,
  *
  * @param [in] sched Allocated and initialized sched object.
  * @param [in] time Absolute time of future event.
- * @param [in] Event ID.
- * @param [in] Pointer to arbitrary data linked to event.
+ * @param [in] ev_id Event ID.
+ * @param [in] data Pointer to arbitrary data linked to event.
  * @return 0 - success, < 0 on error.
  */
 int faux_schev_schedule(
@@ -114,8 +124,8 @@ int faux_schev_schedule(
  *
  * @param [in] sched Allocated and initialized sched object.
  * @param [in] interval Interval (NULL means "now").
- * @param [in] Event ID.
- * @param [in] Pointer to arbitrary data linked to event.
+ * @param [in] ev_id Event ID.
+ * @param [in] data Pointer to arbitrary data linked to event.
  * @return 0 - success, < 0 on error.
  */
 int faux_schev_schedule_interval(faux_schev_t *schev,
@@ -135,3 +145,146 @@ int faux_schev_schedule_interval(faux_schev_t *schev,
 
 	return faux_schev_schedule(schev, &plan, ev_id, data);
 }
+
+
+/** @brief Adds periodic event to sched list using absolute time for first one.
+ *
+ * @param [in] sched Allocated and initialized sched object.
+ * @param [in] time Absolute time of first event.
+ * @param [in] ev_id Event ID.
+ * @param [in] data Pointer to arbitrary data linked to event.
+ * @param [in] period Period of periodic event.
+ * @param [in] cycle_num Number of cycles.
+ * @return 0 - success, < 0 on error.
+ */
+int faux_schev_periodic(
+	faux_schev_t *schev, const struct timespec *time, int ev_id, void *data,
+	const struct timespec *period, int cycle_num)
+{
+	return _schev_schedule(schev, time, ev_id, data,
+		FAUX_SCHEV_ONCE, period, cycle_num);
+}
+
+
+/** @brief Adds periodic event to sched list using period for first one.
+ *
+ * @param [in] sched Allocated and initialized sched object.
+ * @param [in] ev_id Event ID.
+ * @param [in] data Pointer to arbitrary data linked to event.
+ * @param [in] period Period of periodic event.
+ * @param [in] cycle_num Number of cycles.
+ * @return 0 - success, < 0 on error.
+ */
+int faux_schev_periodic_delayed(
+	faux_schev_t *schev, int ev_id, void *data,
+	const struct timespec *period, int cycle_num)
+{
+	struct timespec t = {};
+	struct timespec plan = {};
+
+	assert(schev);
+	assert(period);
+	if (!schev || !period)
+		return -1;
+
+	clock_gettime(FAUX_SCHEV_CLOCK_SOURCE, &t);
+	faux_timespec_sum(&plan, &t, period);
+	return faux_schev_periodic(schev, &plan, ev_id, data,
+		period, cycle_num);
+}
+
+
+/** @brief Returns the interval from current time and next scheduled event.
+ *
+ * If event is in the past then return null interval.
+ * If no events was scheduled then return -1.
+ */
+int faux_schev_next_interval(faux_schev_t *schev, struct timespec *interval)
+{
+	faux_ev_t *ev = NULL;
+	faux_list_node_t *iter = NULL;
+
+	assert(schev);
+	assert(interval);
+	if (!schev || !interval)
+		return -1;
+
+	iter = faux_list_head(schev->list);
+	if (!iter)
+		return -1;
+	ev = (faux_ev_t *)faux_list_data(iter);
+
+	return faux_ev_time_left(ev, interval);
+}
+
+/** @brief Remove all entries from the list.
+ *
+ *
+ */
+void faux_schev_empty(faux_schev_t *schev)
+{
+	assert(schev);
+	if (!schev)
+		return;
+
+	faux_list_empty(schev->list);
+}
+
+/** @brief Pop already coming events from list.
+ *
+ * Pop (get and remove from list) timestamp if it's in the past.
+ * If the timestamp is in the future then do nothing.
+ */
+int faux_schev_pop(faux_schev_t *schev, int *ev_id, void **data)
+{
+	struct timespec now = {};
+	faux_list_node_t *iter = NULL;
+	faux_ev_t *ev = NULL;
+
+	assert(schev);
+	if (!schev)
+		return -1;
+
+	iter = faux_list_head(schev->list);
+	if (!iter)
+		return -1;
+	ev = (faux_ev_t *)faux_list_data(iter);
+	clock_gettime(FAUX_SCHEV_CLOCK_SOURCE, &now);
+	if (faux_timespec_cmp(faux_ev_time(ev), &now) > 0)
+		return -1; // No events for this time
+	faux_list_takeaway(schev->list, iter); // Remove entry from list
+
+	if (ev_id)
+		*ev_id = faux_ev_id(ev);
+	if (data)
+		*data = faux_ev_data(ev);
+
+	if (faux_ev_reschedule_interval(ev) < 0) {
+		faux_ev_free(ev);
+	} else {
+		_schev_schedule_ev(schev, ev);
+	}
+
+	return 0;
+}
+
+#if 0
+/* Remove all timestamps with specified ID from the list. */
+void remove_ev(lub_list_t *list, int id)
+{
+	lub_list_node_t *iter = lub_list__get_head(list);
+	if (!iter)
+		return;
+	while (iter) {
+		lub_list_node_t *node = iter;
+		schev_t *tmp = (schev_t *)lub_list_node__get_data(node);
+		iter = lub_list_iterator_next(node);
+		if (tmp->id == id) {
+			lub_list_del(list, node);
+			lub_list_node_free(node);
+			free(tmp);
+		}
+	}
+}
+
+#endif