summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/aarch64/clone.s3
-rw-r--r--src/thread/arm/clone.s3
-rw-r--r--src/thread/loongarch64/__set_thread_area.s7
-rw-r--r--src/thread/loongarch64/__unmapself.s7
-rw-r--r--src/thread/loongarch64/clone.s30
-rw-r--r--src/thread/loongarch64/syscall_cp.s29
-rw-r--r--src/thread/m68k/clone.s3
-rw-r--r--src/thread/microblaze/clone.s3
-rw-r--r--src/thread/mips/clone.s3
-rw-r--r--src/thread/mips64/clone.s3
-rw-r--r--src/thread/mipsn32/clone.s3
-rw-r--r--src/thread/or1k/clone.s5
-rw-r--r--src/thread/riscv32/__set_thread_area.s6
-rw-r--r--src/thread/riscv32/__unmapself.s7
-rw-r--r--src/thread/riscv32/clone.s35
-rw-r--r--src/thread/riscv32/syscall_cp.s29
-rw-r--r--src/thread/riscv64/clone.s1
-rw-r--r--src/thread/s390x/__tls_get_offset.s20
-rw-r--r--src/thread/sem_post.c2
-rw-r--r--src/thread/synccall.c8
20 files changed, 185 insertions, 22 deletions
diff --git a/src/thread/aarch64/clone.s b/src/thread/aarch64/clone.s
index e3c83395..9ac272bd 100644
--- a/src/thread/aarch64/clone.s
+++ b/src/thread/aarch64/clone.s
@@ -24,7 +24,8 @@ __clone:
// parent
ret
// child
-1: ldp x1,x0,[sp],#16
+1: mov fp, 0
+ ldp x1,x0,[sp],#16
blr x1
mov x8,#93 // SYS_exit
svc #0
diff --git a/src/thread/arm/clone.s b/src/thread/arm/clone.s
index bb0965da..4ff0c0e8 100644
--- a/src/thread/arm/clone.s
+++ b/src/thread/arm/clone.s
@@ -19,7 +19,8 @@ __clone:
ldmfd sp!,{r4,r5,r6,r7}
bx lr
-1: mov r0,r6
+1: mov fp,#0
+ mov r0,r6
bl 3f
2: mov r7,#1
svc 0
diff --git a/src/thread/loongarch64/__set_thread_area.s b/src/thread/loongarch64/__set_thread_area.s
new file mode 100644
index 00000000..021307fc
--- /dev/null
+++ b/src/thread/loongarch64/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.hidden __set_thread_area
+.type __set_thread_area,@function
+__set_thread_area:
+ move $tp, $a0
+ move $a0, $zero
+ jr $ra
diff --git a/src/thread/loongarch64/__unmapself.s b/src/thread/loongarch64/__unmapself.s
new file mode 100644
index 00000000..719ad056
--- /dev/null
+++ b/src/thread/loongarch64/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, @function
+__unmapself:
+ li.d $a7, 215 # call munmap
+ syscall 0
+ li.d $a7, 93 # call exit
+ syscall 0
diff --git a/src/thread/loongarch64/clone.s b/src/thread/loongarch64/clone.s
new file mode 100644
index 00000000..cb4aacfc
--- /dev/null
+++ b/src/thread/loongarch64/clone.s
@@ -0,0 +1,30 @@
+#__clone(func, stack, flags, arg, ptid, tls, ctid)
+# a0, a1, a2, a3, a4, a5, a6
+# sys_clone(flags, stack, ptid, ctid, tls)
+# a0, a1, a2, a3, a4
+
+.global __clone
+.hidden __clone
+.type __clone,@function
+__clone:
+ bstrins.d $a1, $zero, 3, 0 #stack to 16 align
+ # Save function pointer and argument pointer on new thread stack
+ addi.d $a1, $a1, -16
+ st.d $a0, $a1, 0 # save function pointer
+ st.d $a3, $a1, 8 # save argument pointer
+ or $a0, $a2, $zero
+ or $a2, $a4, $zero
+ or $a3, $a6, $zero
+ or $a4, $a5, $zero
+ ori $a7, $zero, 220
+ syscall 0 # call clone
+
+ beqz $a0, 1f # whether child process
+ jirl $zero, $ra, 0 # parent process return
+1:
+ move $fp, $zero
+ ld.d $t8, $sp, 0 # function pointer
+ ld.d $a0, $sp, 8 # argument pointer
+ jirl $ra, $t8, 0 # call the user's function
+ ori $a7, $zero, 93
+ syscall 0 # child process exit
diff --git a/src/thread/loongarch64/syscall_cp.s b/src/thread/loongarch64/syscall_cp.s
new file mode 100644
index 00000000..c057a97b
--- /dev/null
+++ b/src/thread/loongarch64/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm,@function
+
+__syscall_cp_asm:
+__cp_begin:
+ ld.w $a0, $a0, 0
+ bnez $a0, __cp_cancel
+ move $t8, $a1 # reserve system call number
+ move $a0, $a2
+ move $a1, $a3
+ move $a2, $a4
+ move $a3, $a5
+ move $a4, $a6
+ move $a5, $a7
+ move $a7, $t8
+ syscall 0
+__cp_end:
+ jr $ra
+__cp_cancel:
+ la.local $t8, __cancel
+ jr $t8
diff --git a/src/thread/m68k/clone.s b/src/thread/m68k/clone.s
index f6dfa06f..0134cf4e 100644
--- a/src/thread/m68k/clone.s
+++ b/src/thread/m68k/clone.s
@@ -18,7 +18,8 @@ __clone:
beq 1f
movem.l (%sp)+,%d2-%d5
rts
-1: move.l %a1,-(%sp)
+1: suba.l %fp,%fp
+ move.l %a1,-(%sp)
jsr (%a0)
move.l #1,%d0
trap #0
diff --git a/src/thread/microblaze/clone.s b/src/thread/microblaze/clone.s
index b68cc5fc..64e3f074 100644
--- a/src/thread/microblaze/clone.s
+++ b/src/thread/microblaze/clone.s
@@ -22,7 +22,8 @@ __clone:
rtsd r15, 8
nop
-1: lwi r3, r1, 0
+1: add r19, r0, r0
+ lwi r3, r1, 0
lwi r5, r1, 4
brald r15, r3
nop
diff --git a/src/thread/mips/clone.s b/src/thread/mips/clone.s
index 04463385..229b987e 100644
--- a/src/thread/mips/clone.s
+++ b/src/thread/mips/clone.s
@@ -27,7 +27,8 @@ __clone:
addu $sp, $sp, 16
jr $ra
nop
-1: lw $25, 0($sp)
+1: move $fp, $0
+ lw $25, 0($sp)
lw $4, 4($sp)
jalr $25
nop
diff --git a/src/thread/mips64/clone.s b/src/thread/mips64/clone.s
index 2d86899a..8de3db6c 100644
--- a/src/thread/mips64/clone.s
+++ b/src/thread/mips64/clone.s
@@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
-1: ld $25, 0($sp) # function pointer
+1: move $fp, $0
+ ld $25, 0($sp) # function pointer
ld $4, 8($sp) # argument pointer
jalr $25 # call the user's function
nop
diff --git a/src/thread/mipsn32/clone.s b/src/thread/mipsn32/clone.s
index 4d3c8c7a..9571231a 100644
--- a/src/thread/mipsn32/clone.s
+++ b/src/thread/mipsn32/clone.s
@@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
-1: lw $25, 0($sp) # function pointer
+1: move $fp, $0
+ lw $25, 0($sp) # function pointer
lw $4, 4($sp) # argument pointer
jalr $25 # call the user's function
nop
diff --git a/src/thread/or1k/clone.s b/src/thread/or1k/clone.s
index 2473ac20..b41488a2 100644
--- a/src/thread/or1k/clone.s
+++ b/src/thread/or1k/clone.s
@@ -6,6 +6,8 @@
.hidden __clone
.type __clone,@function
__clone:
+ l.xori r11, r0, -4
+ l.and r4, r4, r11
l.addi r4, r4, -8
l.sw 0(r4), r3
l.sw 4(r4), r6
@@ -23,7 +25,8 @@ __clone:
l.jr r9
l.nop
-1: l.lwz r11, 0(r1)
+1: l.ori r2, r0, 0
+ l.lwz r11, 0(r1)
l.jalr r11
l.lwz r3, 4(r1)
diff --git a/src/thread/riscv32/__set_thread_area.s b/src/thread/riscv32/__set_thread_area.s
new file mode 100644
index 00000000..828154d2
--- /dev/null
+++ b/src/thread/riscv32/__set_thread_area.s
@@ -0,0 +1,6 @@
+.global __set_thread_area
+.type __set_thread_area, %function
+__set_thread_area:
+ mv tp, a0
+ li a0, 0
+ ret
diff --git a/src/thread/riscv32/__unmapself.s b/src/thread/riscv32/__unmapself.s
new file mode 100644
index 00000000..2849119c
--- /dev/null
+++ b/src/thread/riscv32/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, %function
+__unmapself:
+ li a7, 215 # SYS_munmap
+ ecall
+ li a7, 93 # SYS_exit
+ ecall
diff --git a/src/thread/riscv32/clone.s b/src/thread/riscv32/clone.s
new file mode 100644
index 00000000..e2116e33
--- /dev/null
+++ b/src/thread/riscv32/clone.s
@@ -0,0 +1,35 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+# a0, a1, a2, a3, a4, a5, a6
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+# a7 a0, a1, a2, a3, a4
+
+.global __clone
+.type __clone, %function
+__clone:
+ # Save func and arg to stack
+ andi a1, a1, -16
+ addi a1, a1, -16
+ sw a0, 0(a1)
+ sw a3, 4(a1)
+
+ # Call SYS_clone
+ mv a0, a2
+ mv a2, a4
+ mv a3, a5
+ mv a4, a6
+ li a7, 220 # SYS_clone
+ ecall
+
+ beqz a0, 1f
+ # Parent
+ ret
+
+ # Child
+1: lw a1, 0(sp)
+ lw a0, 4(sp)
+ jalr a1
+
+ # Exit
+ li a7, 93 # SYS_exit
+ ecall
diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscall_cp.s
new file mode 100644
index 00000000..079d1ba0
--- /dev/null
+++ b/src/thread/riscv32/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm, %function
+__syscall_cp_asm:
+__cp_begin:
+ lw t0, 0(a0)
+ bnez t0, __cp_cancel
+
+ mv t0, a1
+ mv a0, a2
+ mv a1, a3
+ mv a2, a4
+ mv a3, a5
+ mv a4, a6
+ mv a5, a7
+ lw a6, 0(sp)
+ mv a7, t0
+ ecall
+__cp_end:
+ ret
+__cp_cancel:
+ tail __cancel
diff --git a/src/thread/riscv64/clone.s b/src/thread/riscv64/clone.s
index db908248..0e6f41a8 100644
--- a/src/thread/riscv64/clone.s
+++ b/src/thread/riscv64/clone.s
@@ -8,6 +8,7 @@
.type __clone, %function
__clone:
# Save func and arg to stack
+ andi a1, a1, -16
addi a1, a1, -16
sd a0, 0(a1)
sd a3, 8(a1)
diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s
index 8ee92de8..405f118b 100644
--- a/src/thread/s390x/__tls_get_offset.s
+++ b/src/thread/s390x/__tls_get_offset.s
@@ -1,17 +1,17 @@
.global __tls_get_offset
.type __tls_get_offset,%function
__tls_get_offset:
- stmg %r14, %r15, 112(%r15)
- aghi %r15, -160
+ ear %r0, %a0
+ sllg %r0, %r0, 32
+ ear %r0, %a1
- la %r2, 0(%r2, %r12)
- brasl %r14, __tls_get_addr
+ la %r1, 0(%r2, %r12)
- ear %r1, %a0
- sllg %r1, %r1, 32
- ear %r1, %a1
+ lg %r3, 0(%r1)
+ sllg %r4, %r3, 3
+ lg %r5, 8(%r0)
+ lg %r2, 0(%r4, %r5)
+ ag %r2, 8(%r1)
+ sgr %r2, %r0
- sgr %r2, %r1
-
- lmg %r14, %r15, 272(%r15)
br %r14
diff --git a/src/thread/sem_post.c b/src/thread/sem_post.c
index 5c2517f2..1c8f763c 100644
--- a/src/thread/sem_post.c
+++ b/src/thread/sem_post.c
@@ -16,6 +16,6 @@ int sem_post(sem_t *sem)
if (waiters <= 1)
new &= ~0x80000000;
} while (a_cas(sem->__val, val, new) != val);
- if (val<0) __wake(sem->__val, waiters>1 ? 1 : -1, priv);
+ if (val<0 || waiters) __wake(sem->__val, waiters>1 ? 1 : -1, priv);
return 0;
}
diff --git a/src/thread/synccall.c b/src/thread/synccall.c
index a6b177c0..38597254 100644
--- a/src/thread/synccall.c
+++ b/src/thread/synccall.c
@@ -11,7 +11,7 @@ weak_alias(dummy_0, __tl_unlock);
static int target_tid;
static void (*callback)(void *), *context;
-static sem_t target_sem, caller_sem;
+static sem_t target_sem, caller_sem, exit_sem;
static void dummy(void *p)
{
@@ -33,7 +33,7 @@ static void handler(int sig)
/* Inform caller we've complered the callback and wait
* for the caller to release us to return. */
sem_post(&caller_sem);
- sem_wait(&target_sem);
+ sem_wait(&exit_sem);
/* Inform caller we are returning and state is destroyable. */
sem_post(&caller_sem);
@@ -62,6 +62,7 @@ void __synccall(void (*func)(void *), void *ctx)
sem_init(&target_sem, 0, 0);
sem_init(&caller_sem, 0, 0);
+ sem_init(&exit_sem, 0, 0);
if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)
goto single_threaded;
@@ -107,12 +108,13 @@ single_threaded:
/* Only release the caught threads once all threads, including the
* caller, have returned from the callback function. */
for (i=0; i<count; i++)
- sem_post(&target_sem);
+ sem_post(&exit_sem);
for (i=0; i<count; i++)
sem_wait(&caller_sem);
sem_destroy(&caller_sem);
sem_destroy(&target_sem);
+ sem_destroy(&exit_sem);
pthread_setcancelstate(cs, 0);
__tl_unlock();