我试图实现一个新的用户线程pipe理库类似于原来的pthread,但只有在C.只有上下文切换应该是汇编。
看起来我从根本上失去了一些东西。 我有以下结构的上下文执行:
enter code here struct exec_ctx { uint64_t rbp; uint64_t r15; uint64_t r14; uint64_t r13; uint64_t r12; uint64_t r11; uint64_t r10; uint64_t r9; uint64_t r8; uint64_t rsi; uint64_t rdi; uint64_t rdx; uint64_t rcx; uint64_t rbx; uint64_t rip; }__attribute__((packed));
我创build了新的线程结构,我应该把这些寄存器放到所提到的variables中,作为上下文执行结构的一部分。 我该怎么做C? 到处都只讲setcontext,getcontext,但是这里不是这种情况。
另外,我收到的唯一提示是我需要有一些转储堆栈函数到创build函数….不知道该怎么做。 请告诉我在哪里可以阅读更多/怎么做。
提前致谢!
我开始:
char *stack; stack = malloc(StackSize); if (!stack) return -1; *(uint64_t *)&stack[StackSize - 8] = (uint64_t)stop; *(uint64_t *)&stack[StackSize - 16] = (uint64_t)f; pet_thread->ctx.rip = (uint64_t)&stack[StackSize - 16]; pet_thread->thread_state = Ready;
这就是我如何把一个指向堆栈顶部的线程函数的指针,以便更容易地调用线程。
首先,你不需要保存所有的寄存器。 由于您的上下文切换是作为一个函数实现的,所以ABI定义为“调用者保存”或“破坏”的任何寄存器都可以安全地离开。 C编译器生成的代码将假定它可能会改变。
由于这是一个学校的任务,我不会给你这样做的代码。 我会给大纲。
您的函数需要将寄存器保存到传出微线程的结构中, 并为传入的微线程加载寄存器。 原因是你在逻辑上总是有一个寄存器设置“有效”。 所以你的函数需要两个参数,即传出微线程的结构和传入的结构。
这两个参数存储在两个寄存器中。 这两个你不需要保存。 所以你的代码应该有如下结构(假设你的结构,正如我所说的那样,结构太完整了):
# save context mov [rdi], rbp add 8, rdi ... #load context mov rbp, [rsi] add 8, rsi ...
如果你把它放在一个单独的.S文件中,你将确保C编译器不会添加任何东西或优化任何东西。
这不是最干净或最有效的解决方案,但它是最简单的。