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
#define LOG_TAG "wifi.proto"
#include <elog.h>
log_e("我是 wifi.proto 日志");
最后决定使用 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;
}