+static void unlink_and_free_task(struct task *t)
+{
+ PARA_INFO_LOG("freeing task %s (%s)\n", t->name, t->status < 0?
+ para_strerror(-t->status) :
+ (t->status == TS_DEAD? "[dead]" : "[running]"));
+
+ list_del(&t->node);
+ free(t->name);
+ free(t);
+}
+
+//#define SCHED_DEBUG 1
+static inline void call_post_select(struct sched *s, struct task *t)
+{
+ int ret;
+
+#ifndef SCHED_DEBUG
+ ret = t->info.post_select(s, t->info.context);
+#else
+ struct timeval t1, t2, diff;
+ unsigned long pst;
+
+ clock_get_realtime(&t1);
+ ret = t->info.post_select(s, t->info.context);
+ clock_get_realtime(&t2);
+ tv_diff(&t1, &t2, &diff);
+ pst = tv2ms(&diff);
+ if (pst > 50)
+ PARA_WARNING_LOG("%s: post_select time: %lums\n",
+ t->name, pst);
+#endif
+ t->status = ret < 0? ret : TS_RUNNING;
+}
+
+static unsigned sched_post_select(struct sched *s)