xhawk18 / s_task Goto Github PK
View Code? Open in Web Editor NEWawaitable coroutine library for C
License: Other
awaitable coroutine library for C
License: Other
gcc -I s_task/include/ -I s_task/libuv/include/ main.c -o main libs_task.a -lpthread -ldl -lrt
直接链接libs_task.a文件, 运行main出错: Segmentation fault (core dumped)
gdb main, 提示:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004069a1 in uv_timer_init ()
用linux下的build.sh文件编译运行没有问题...
协程外部调用s_event_set会报错。
有什么方法可以实现协程外的线程逻辑同步?
it would be good to have a possibility to try to acquire a mutex with a timeout (as is possible for an event).
源码 : #define s_chan_declare(name,TYPE,count)
s_chan_t name[1 + ((count)*sizeof(TYPE) + sizeof(s_chan_t) - 1) / sizeof(sizeof(s_chan_t))]
不懂为什么是除以sizeof(sizeof(s_chan_t)), 而不是除以sizeof(s_chan_t)
I initialize an event, and then wait on it in a task, using
s_event_wait_sec(await, &ev, 1);
This works (execution proceeds when a timeout occurs or the event is set). However, I thought that a timeout would be indicated in the return value. However, it is zero in both cases (timeout or event received). I also do not see where in the code this would be handled.
直接在 build
目录里 make 会生成不需要的中间文件。
建议在里面新建下一级目录编译:
cd s_task/build
mkdir build && cd build
cmake -G Ninja ..
ninja
这样的话,build/build
这个目录可以随时删掉,这样一来 s_task/build
这个目录名字就不太合适,容易混淆。
三个opreator:co_await, co_yield, co_return
在 void on_connection(uv_stream_t *stream, int status) 中已经对client对象初始化了:
s_list_init(&client->list_node);
s_list_attach(&server->running_clients, &client->list_node);
在 static void run_client(async, void *arg) 中再次初始化:
s_list_init(&client->list_node);
s_list_attach(&client->server->running_clients, &client->list_node);
重复初始化存在问题.
你好!
请问这个工程项目对比libuv有哪些优势?
我想找到一个比libuv性能更好,支持多核cpu的库。主要应用是python的uvloop,一个libuv的包装,单核性能还可以,希望可以充分利用多核,性能再好些更好了。
谢谢
hawk 你好,
最近试用了一下s_task, 感觉很不错, 不过因为对代码的理解有限,还希望能请教几个问题。
char g_stack0[384]; // 64 * 6
char g_stack1[384];
我测试了一下, 64*5
的stack, 也可以运行, 但64*4
就出现了报错 fprintf(stderr, "stack overflow in lower bits");
if(((int *)real_stack)[0] != S_TASK_STACK_MAGIC) {
#ifndef NDEBUG
fprintf(stderr, "stack overflow in lower bits");
#endif
while(1); /* dead */
}
这里的 S_TASK_STACK_MAGIC ((int)0x5AA55AA5), 没有看到什么文档, 请问具体是什么含义。
另外,swapcontext 两个注释掉的指令, 请问被注释的原因是什么。
static void swapcontext(ucontext_t *old_tcb, const ucontext_t *new_tcb) {
__asm__ __volatile__(
"PUSH {r4-r12,lr}\n"
"STR sp, [r0]\n"
//"LDR r2, [r1]\n"
//"MOV sp, r2\n"
"LDR sp, [r1]\n"
"POP {r4-r12,lr}\n"
"BX lr\n"
);
}
最后, 如果关于create_context, 的-1 和 -10 两个常数有相关说明就非常好了。
static void create_context(ucontext_t *oucp, void *stack, size_t stack_size) {
uint32_t *top_sp;
uint32_t int_sp;
int_sp = (int )((char *)stack + stack_size);
int_sp = int_sp / 4 * 4; //alignment
top_sp = (uint32_t *)int_sp;
top_sp[-1] = (int)&s_task_context_entry;
oucp->sp = (int)&top_sp[-10];
}
现象为多个send_task发送消息到recv_task,由于chan空间设置太小,导致部分send_task进入等待态,而recv_task在收到第一个消息时正常退出并设置全局变量控制所有send_task退出。此时,剩余send_task不在全局变量的active_task上且由于没有定时器、没有uv的handles和req,uv正常结束流程,导致剩余等待状态的send_task没有正常退出。
不知道这是个bug还是正常使用不会出现这种情况?
针对 void s_task_create(void* stack, size_t stack_size, s_task_fn_t task_entry, void* task_arg)
提出的小建议
可以把 前两个参数稍微封装一下,抽象成 TaskID (实际上就是一个创建的栈指针),大小不用一次性初始化写死,也可以借鉴 java ArrayList 的动态大小分配动态扩容 stack,至于扩容操作可能导致栈指针的变化
可以使用二级指针来解决问题
typedef void** Task;
或者是:
typedef struct
{
int ID;
void* statck;
size_t stack_size;
} TaskID;
再或者使用 map<int,void*> TaskID
看起来简洁一些,让暴露出来的API变成
void s_task_create(TaskID* taskID, s_task_fn_t task_entry, void* task_arg)
后面的 join 等api 对应使用过方式也都由 taskid 接管
我有一个这样的想法
背景大概是安卓ndk编程中,jni_onload这里的这个线程往往是可以直接使用env去做一些java的操作,如果新创建的线程就需要先 AttachCurrentThread 一下才能正常使用 env
如果能在 jni_onload 函数中注册一个协程任务,然后让协程任务本身为一个死循环,同时处于互斥锁卡住的状态,在ndk编程中的其他线程去处理这个互斥锁,同时携带上需要调用的函数地址,这样实现一个在任意线程中都可以通过消息来实现任何函数的调用都在 jni_onload 这个线程中
以上只是一个举例,这里的应用场景还有比如在逆向 il2cpp unity 中,注册在ui线程,跨线程从其他线程都能修改ui
目前看起来的话 s_task 只是在指定的一个位置创建了协程并卡住当前线程,只有等到所有join的协程都执行完了才能继续当前线程,且互斥量尽在协程之间使用有效,外部创建的线程修改互斥量好像并不能继续协程的执行
问题落到了:如何在协程处于阻塞状态的时候从其他线程唤醒协程
LOGD("JNI_OnLoad -- Start -- ");
s_task_init_system();
s_mutex_init(&sMutex);
s_mutex_lock(__await__, &sMutex);
s_task_create(g_stack_main,sizeof (g_stack_main),*[](__async__, void *arg)->auto{
LOGD("s_mutex_lock %p %d",&sMutex,sMutex.locked);
while(true){
s_mutex_lock(__await__, &sMutex);
LOGD("s_task_create run");
}
}, nullptr);
s_task_join(__await__,g_stack_main);
LOGD("JNI_OnLoad -- End -- ");
// 过了一段时间后,其他线程调用
s_mutex_unlock(&sMutex);
并不会继续协程的执行
在linux下编译时遇到了这个问题:cross_build_arm64.sh: 5: cross_build_arm64.sh: Syntax error: "(" unexpected
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.