我正在使用一个使用用户级上下文切换的运行时库(使用Boost :: Context),并且在使用thread_level变量时遇到了麻烦.考虑以下(简化)代码:
thread_local int* volatile tli;
int main()
{
tli = new int(1); // part 1, done by thread 1
UserLevelContextSwitch();
int li = *tli; // part 2, done by thread 2
cout << li;
}
Run Code Online (Sandbox Code Playgroud)
由于对thread_local变量有两次访问,因此编译器将main函数转换为沿着这些行的某些东西(与汇编相反):
register int** ptli = &tli; // cache address of thread_local variable
*ptli = new int(1);
UserLevelContextSwitch();
int li = **ptli;
cout << li;
Run Code Online (Sandbox Code Playgroud)
这似乎是一种合法的优化,因为volatile 的值tli不会缓存在寄存器中.但是, volatile 的地址tli实际上是缓存的,而不是从第2部分的内存中读取的.
这就是问题:在用户级上下文切换之后,执行第1部分的线程会转到其他位置.然后,第2部分由其他线程获取,该线程获得先前的堆栈和寄存器状态.但是现在正在执行第2部分的线程读取tli属于线程1的值.
我试图找出一种方法来阻止编译器缓存线程局部变量的地址,并且 …
我正在研究一种类似 c++ 的小型语言,我将把它编译成 LLVM。我想要实现的一件事是协作式多任务处理;将有一个“yield”运算符,它有望将堆栈指针和程序计数器切换到我程序中的下一个“线程”。
是否可以在 llvm 中执行此操作?我可以设置堆栈指针寄存器吗?如果没有,我还能做其他类似的事情吗?
编辑:LLVM 协程(http://llvm.org/docs/Coroutines.html)听起来很有希望,尽管https://internals.rust-lang.org/t/llvm-coroutines-to-bring-awarness/3708/12提出了一些关于有栈或无栈协程的问题。我想知道,它们可以用来实现一个通用的类似产量的运算符吗?
编辑 2:在 C++ 中,boost 有一个叫做“上下文”的东西,它可以实现堆栈协程。仍然试图弄清楚他们是如何做到的。有人知道吗?
我发现boost有一个叫做context的类,用于上下文切换,对吧?
我尝试谷歌它但没有找到任何文件或例子.我只是想知道是否有人可以提供一些信息.