You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// wait till the value is defined. We have to make one last check inside the lock to make sure the value is still unresolved
226
226
// The wait may time out because another thread is requesting a system lock. If so, we accept it now
227
227
if(unlikely(adbreak>>8)!=0){jtsystemlockaccept(jt,LOCKPRISYM+LOCKPRIPATH+LOCKPRIDEBUG); continue;} // process lock and keep waiting
228
-
// or, the user may be requesting a BREAK interrupt for deadlock or other slow execution. In that case fail the pyx. It will not be deleted until the value has been stored
229
-
if(unlikely(adbreak&0xff))ASSERT(0,adbreak&0xff); // JBREAK: fail the pyx and exit
//is there EINTR on windows? Does it manifest as a spurious wake with no error?
113
+
REVFACE;}
114
+
#endif
30
115
31
116
#if defined(__APPLE__) || defined(__linux__)
32
117
enum{FREE=0,LOCK=1,WAIT=2};//values for mutex->v
@@ -45,17 +130,14 @@ C jtpthread_mutex_lock(J jt,jtpthread_mutex_t *m,I self){
45
130
UI4e;if(likely((!(e=lda(&m->v)))&&((e=FREE),casa(&m->v,&e,LOCK))))goto success; //fast path. test-and-test-and-set is from glibc, mildly optimises the case when many threads swarm a locked mutex. Not sure if this is for the best, but after waffling for a bit I think it is
46
131
if(e!=WAIT)e=xchga(&m->v,WAIT); //penalise the multi-waiters case, since it's slower anyway
47
132
while(e!=FREE){
133
+
if(JT(jt,adbreakr)[0])REVATTN;
48
134
#if__linux__
49
-
Ii=_jfutex_waitn(&m->v,WAIT,(UI)-1);
135
+
Ii=jfutex_waitn(&m->v,WAIT,(UI)-1);
50
136
//bug? futex wait doesn't get interrupted by signals on linux if timeout is null
51
137
#else
52
138
Ii=jfutex_wait(&m->v,WAIT);
53
139
#endif
54
-
if(uncommon(i<0)){
55
-
if(i==-EINTR){if(JT(jt,adbreakr)[0])REVATTN;}
56
-
elseif(i==-EOWNERDEAD)REVCONCURRENCY;
57
-
elseif(i==-ENOMEM)REVWSFULL;//lol
58
-
elseREVFACE;}
140
+
if(i>0)Ri;
59
141
e=xchga(&m->v,WAIT);} //exit when e==FREE; i.e., _we_ successfully installed WAIT in place of FREE
Copy file name to clipboardExpand all lines: jsrc/mt.h
+6-54Lines changed: 6 additions & 54 deletions
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,11 @@ struct jtimespec jtmtil(UI ns); //returns a time ns ns in the future
6
6
Ijtmdif(structjtimespecwhen); //returns the time in ns between now and when. If when is not in the future, the result will be -1
7
7
//both of these are implemented in terms of mtclk and use its clock
8
8
9
+
__attribute__((cold)) Cjfutex_wait(UI4*p,UI4v); //atomically, compare v to *p and go to sleep if they are equal. Return error code
10
+
__attribute__((cold)) Ijfutex_waitn(UI4*p,UI4v,UIns); //ditto, but wake up after at most ns ns. Result -1 means timeout definitely exceeded; other result is an error code
11
+
__attribute__((cold)) voidjfutex_wake1(UI4*p); //wake 1 thread waiting on p
12
+
__attribute__((cold)) voidjfutex_wakea(UI4*p); //wake all threads waiting on p
13
+
9
14
#if !defined(__APPLE__) && !defined(__linux__)
10
15
#include<pthread.h>
11
16
typedefpthread_mutex_tjtpthread_mutex_t;
@@ -65,36 +70,6 @@ C jtpthread_mutex_unlock(jtpthread_mutex_t*,I self); //0 or error code
65
70
#if defined(__linux__)
66
71
#include<linux/futex.h>
67
72
#include<sys/syscall.h>
68
-
//glibc 'syscall': stupid errno
69
-
staticinlinevoidjfutex_wake1(UI4*p){
70
-
__asm__ volatile("syscall" :: "a" (SYS_futex), //eax: syscall#
71
-
"D" (p), //rdi: ptr
72
-
"S" (FUTEX_WAKE), //rsi: op
73
-
"d" (1));} //rdx: count
74
-
staticinlinevoidjfutex_wakea(UI4*p){
75
-
__asm__ volatile("syscall" :: "a" (SYS_futex), //eax: syscall#
76
-
"D" (p), //rdi: ptr
77
-
"S" (FUTEX_WAKE), //rsi: op
78
-
"d" (0xffffffff));} //rdx: count
79
-
staticinlineintjfutex_wait(UI4*p,UI4v){
80
-
register structtimespec*pts asm("r10") =0;
81
-
intr;__asm__ volatile("syscall" : "=a"(r) //result in rax
0 commit comments