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, misje/stateMachine * not thread safe * main thread: epoll loop * timeout / timer / cron job: using timer fd // man: timerfd_create * main thread <-> other threads communications: use eventfd (man) * data persistence: options * JSON: cJSON, // alternatives: json-c (support schema) * log: EasyLogger // alternatives: 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
#define LOG_TAG "wifi.proto" #include <elog.h> log_e("我是 wifi.proto 日志");
coroutine
- Libco (C/C++) 不支持 ARM
- libgo (C++11)
- tonbit/coroutine (C++11)
最后决定使用 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; }