我想在汇编中使用"TSL“指令,但它对理解.in没有参考,有些文章介绍这个指令是为了解决互斥问题,但它没有参考或完整的例子来完全理解。
发布于 2014-03-15 21:30:21
TSL (Test and Set Lock,测试和设置锁)是通常在处理互斥问题时经常出现的操作,但这并不意味着这样的指令实际上存在于您正在使用的任何体系结构中;或者,即使它确实存在,它也被称为TSL。
例如,在x86上,您可以使用XCHG指令来执行TSL。
发布于 2014-03-16 01:10:50
XCNG不是有条件的,它只是交换一个寄存器和一个内存位置。您需要的是带有LOCK前缀的CMPXCHG。后者将使其在多核机器上成为原子。
此外,还可以使用锁XADD实现原子比较和设置,但这需要一个循环。
参考:http://en.wikipedia.org/wiki/Compare-and-swap
发布于 2015-01-15 22:07:37
我认为@Jester和@Seva已经很好地回答了这个问题,但这里有一个在x86 Ubuntu机器上使用pthread使用内联汇编的简单的C实现。
在下面的示例中,有两个长时间运行的线程。这两个线程都有一个临界区和一个非临界区,分别是critical_region()和noncritical_region。它们都必须调用enter_region()才能获得锁。一旦线程获得了锁,它就可以开始运行它的临界区。另一个线程会被阻塞,直到拥有该锁的线程调用leave_region().
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
void enter_region() {
asm(
".data\n\t"
"lock:\n\t"
".byte 0\n\t"
".text\n\t"
"_enter_region:\n\t"
"movb $1, %al\n\t" /* move 1 to AL */
"xchgb (lock),%al\n\t"
"cmp $0, %al\n\t"
"jne _enter_region\n\t"
);
}
void leave_region() {
asm("movb $0, (lock)");
}
void critical_region() {
}
void noncritical_region() {
}
static void* f1(void* p) {
while(1) {
puts("wait for f2");
enter_region();
printf("f1 can start its critical section\n");
critical_region();
leave_region();
noncritical_region();
}
return NULL;
}
static void* f2(void* p) {
while(1) {
puts("wait for f1");
enter_region();
printf("f2 can start its critical section\n");
critical_region();
leave_region();
/* if you call sleep, you can see that the non-critical section of this thread won't
* block the other thread from running its critical section as many times as it wants
*/
// sleep(1);
noncritical_region();
}
return NULL;
}
int main() {
int rc;
pthread_t t1, t2;
rc = pthread_create(&t1, NULL, f1, NULL);
if(rc != 0) {
fprintf(stderr, "pthread f1 failed\n");
return EXIT_FAILURE;
}
rc = pthread_create(&t2, NULL, f2, NULL);
if(rc != 0) {
fprintf(stderr, "pthread f2 failed\n");
return EXIT_FAILURE;
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
puts("All threads finished.");
return 0;
}https://stackoverflow.com/questions/22424209
复制相似问题