2017-05-23 12:34:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* machinarium.
|
|
|
|
*
|
|
|
|
* cooperative multitasking engine.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <machinarium.h>
|
|
|
|
#include <machinarium_private.h>
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MM_TASK,
|
|
|
|
MM_TASK_EXIT
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
mm_taskmgr_main(void *arg)
|
|
|
|
{
|
2017-05-27 12:37:05 +00:00
|
|
|
mm_condition_t *condition;
|
|
|
|
condition = mm_condition_cache_pop(&mm_self->condition_cache);
|
|
|
|
if (condition == NULL)
|
2017-05-23 12:34:35 +00:00
|
|
|
return;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
mm_msg_t *msg;
|
2017-05-27 12:37:05 +00:00
|
|
|
msg = mm_queue_get(&machinarium.task_mgr.queue, condition, UINT32_MAX);
|
2017-05-23 12:34:35 +00:00
|
|
|
assert(msg != NULL);
|
|
|
|
if (msg->type == MM_TASK_EXIT) {
|
2017-05-24 09:54:24 +00:00
|
|
|
mm_msg_unref(&machinarium.msg_cache, msg);
|
2017-05-23 12:34:35 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
assert(msg->type == MM_TASK);
|
|
|
|
assert(mm_buf_used(&msg->data) == sizeof(mm_task_t));
|
|
|
|
|
|
|
|
mm_task_t *task;
|
|
|
|
task = (mm_task_t*)msg->data.start;
|
|
|
|
task->function(task->arg);
|
|
|
|
|
2017-06-05 15:00:48 +00:00
|
|
|
mm_condition_signal(task->on_complete->fd.fd);
|
2017-05-23 12:34:35 +00:00
|
|
|
}
|
2017-05-27 12:37:05 +00:00
|
|
|
mm_condition_cache_push(&mm_self->condition_cache, condition);
|
2017-05-23 18:47:28 +00:00
|
|
|
(void)arg;
|
2017-05-23 12:34:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mm_taskmgr_init(mm_taskmgr_t *mgr)
|
|
|
|
{
|
|
|
|
mgr->workers_count = 0;
|
|
|
|
mgr->workers = NULL;
|
|
|
|
mm_queue_init(&mgr->queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
int mm_taskmgr_start(mm_taskmgr_t *mgr, int workers_count)
|
|
|
|
{
|
|
|
|
mgr->workers_count = workers_count;
|
|
|
|
mgr->workers = malloc(sizeof(int) * workers_count);
|
|
|
|
if (mgr->workers == NULL)
|
|
|
|
return -1;
|
|
|
|
int i = 0;
|
|
|
|
for (; i < workers_count; i++) {
|
|
|
|
char name[32];
|
|
|
|
snprintf(name, sizeof(name), "mm_worker: %d", i);
|
|
|
|
mgr->workers[i] = machine_create(name, mm_taskmgr_main, NULL);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mm_taskmgr_stop(mm_taskmgr_t *mgr)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < mgr->workers_count; i++) {
|
|
|
|
machine_msg_t msg;
|
|
|
|
msg = machine_msg_create(MM_TASK_EXIT, 0);
|
|
|
|
mm_queue_put(&mgr->queue, msg);
|
|
|
|
}
|
|
|
|
for (i = 0; i < mgr->workers_count; i++) {
|
|
|
|
machine_wait(mgr->workers[i]);
|
|
|
|
}
|
|
|
|
mm_queue_free(&mgr->queue);
|
|
|
|
free(mgr->workers);
|
|
|
|
}
|
|
|
|
|
|
|
|
int mm_taskmgr_new(mm_taskmgr_t *mgr,
|
|
|
|
mm_task_function_t function, void *arg,
|
|
|
|
int time_ms)
|
|
|
|
{
|
2017-05-27 12:37:05 +00:00
|
|
|
mm_condition_t *condition;
|
|
|
|
condition = mm_condition_cache_pop(&mm_self->condition_cache);
|
|
|
|
if (condition == NULL)
|
2017-05-23 12:34:35 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
mm_msg_t *msg;
|
|
|
|
msg = machine_msg_create(MM_TASK, sizeof(mm_task_t));
|
|
|
|
if (msg == NULL) {
|
2017-05-27 12:37:05 +00:00
|
|
|
mm_condition_cache_push(&mm_self->condition_cache, condition);
|
2017-05-23 12:34:35 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
mm_task_t *task;
|
|
|
|
task = (mm_task_t*)msg->data.start;
|
|
|
|
task->function = function;
|
|
|
|
task->arg = arg;
|
2017-05-27 12:37:05 +00:00
|
|
|
task->on_complete = condition;
|
2017-05-23 12:34:35 +00:00
|
|
|
|
|
|
|
/* schedule task */
|
|
|
|
mm_queue_put(&mgr->queue, msg);
|
|
|
|
|
|
|
|
/* wait for completion */
|
2017-05-23 18:47:28 +00:00
|
|
|
time_ms = INT_MAX;
|
2017-05-23 12:34:35 +00:00
|
|
|
|
2017-05-27 12:37:05 +00:00
|
|
|
int status;
|
|
|
|
status = mm_condition_wait(task->on_complete, time_ms);
|
|
|
|
if (status != 0) {
|
2017-05-23 12:34:35 +00:00
|
|
|
/* todo: */
|
2017-05-23 18:47:28 +00:00
|
|
|
abort();
|
2017-05-31 13:37:29 +00:00
|
|
|
return 0;
|
2017-05-23 12:34:35 +00:00
|
|
|
}
|
|
|
|
|
2017-05-27 12:37:05 +00:00
|
|
|
mm_condition_cache_push(&mm_self->condition_cache, condition);
|
2017-05-31 13:37:29 +00:00
|
|
|
mm_msg_unref(&machinarium.msg_cache, msg);
|
2017-05-23 12:34:35 +00:00
|
|
|
return 0;
|
|
|
|
}
|