General

Infrastructure: event loop(epoll or select / poll) + state machine
Language: ANSI-C / C99, GCC-4.9.4-arm(32)

Design
* global state managements: state machine(s) // [HSM](<https://github.com/howard-chan/HSM>), [misje/stateMachine](<https://github.com/misje/stateMachine>)
  * not thread safe
* main thread: epoll loop
  * timeout / timer / cron job: using timer fd  // man: [timerfd_create](<https://linux.die.net/man/2/timerfd_create>)
* main thread <-> other threads communications: use eventfd ([man](<https://man7.org/linux/man-pages/man2/eventfd.2.html>))
* data persistence: [options](<https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats>)
  * JSON: [cJSON](<https://github.com/DaveGamble/cJSON>), // alternatives: [json-c](<https://github.com/json-c/json-c>) (support [schema](<https://github.com/helmut-jacob/jsonschema-c>))
* log: [EasyLogger](<https://github.com/armink/EasyLogger>) // alternatives: [log.c](<https://github.com/rxi/log.c>)

external interfaces (429 / FGPA)
* If provided as standard fd: use epoll to watch directly.
* If provided as a function call (read), depends on the read type
  * blocking: polling // must use standalone thread
  * none-blocking: read + timer // possibly handle in main thread

Log: easylog

Docs

#define LOG_TAG    "wifi.proto"
#include <elog.h>

log_e("我是 wifi.proto 日志");

coroutine

最后决定使用 s_task 这个 C 的协程实现。

Example

/* Copyright xhawk, MIT license */

#include <stdio.h>
#include "s_task.h"

void* g_stack_main[64 * 1024];
void* g_stack0[64 * 1024];
void* g_stack1[64 * 1024];

void sub_task(__async__, void* arg) {
    int i;
    int n = (int)(size_t)arg;
    for (i = 0; i < 5; ++i) {
        printf("task %d, delay seconds = %d, i = %d\\n", n, n, i);
        s_task_msleep(__await__, n * 1000);
        /* s_task_yield(__await__); */
    }
}

void main_task(__async__, void* arg) {
    int i;
    s_task_create(g_stack0, sizeof(g_stack0), sub_task, (void*)1);
    s_task_create(g_stack1, sizeof(g_stack1), sub_task, (void*)2);

    for (i = 0; i < 4; ++i) {
        printf("task_main arg = %p, i = %d\\n", arg, i);
        s_task_yield(__await__);
    }

    s_task_join(__await__, g_stack0);
    s_task_join(__await__, g_stack1);
}

int main(int argc, char *argv[]) {
    s_task_init_system();
    s_task_create(g_stack_main, sizeof(g_stack_main), main_task, (void*)(size_t)argc);
    s_task_join(__await__, g_stack_main);

    printf("all task is over\\n");
    return 0;
}

C++