#include <sys/syscall.h>
#define STDOUT_FILENO 1
#define MUTEX_LOCKED 0x01
#define MUTEX_UNLOCKED 0x00
#define STACK_SIZE 4096
#define TLS_SIZE 4096
.text
.file "swp_test.S"
.syntax unified
.globl main
.p2align 2
.type main,%function
.code 32
main:
sub sp, sp, #12
movw r0, :lower16:.L.mainmsg
movt r0, :upper16:.L.mainmsg
ldr r1, =(.L.mainmsgEnd - .L.mainmsg - 1)
bl print
mov r0, #1
str r0, [sp, #4]
movw r0, :lower16:secondary_thread
movt r0, :upper16:secondary_thread
mov r1, sp
movw r2, :lower16:stack1
movt r2, :upper16:stack1
movw r3, :lower16:tls1
movt r3, :upper16:tls1
bl create_thr
1:
ldr r0, [sp, #4]
cmp r0, #1
bne 2f
ldr r7, =SYS_sched_yield
swi 0
b 1b
2:
movw r0, :lower16:secondary_thread
movt r0, :upper16:secondary_thread
mov r1, sp
movw r2, :lower16:stack2
movt r2, :upper16:stack2
movw r3, :lower16:tls2
movt r3, :upper16:tls2
bl create_thr
3:
ldr r0, [sp, #4]
cmp r0, #2
bne 4f
ldr r7, =SYS_sched_yield
swi 0
b 3b
4:
mov r0, sp
mov r1, #0
add r2, sp, #8
bl thread_loop
b 4b
mov r0, #0
ldr r7, =SYS_exit
swi 0
.p2align 2
.type secondary_thread,%function
.code 32
secondary_thread:
mov r4, r0
ldr r5, [r0, #4]
movw r0, :lower16:.L.secondarymsg
movt r0, :upper16:.L.secondarymsg
ldr r1, =(.L.secondarymsgEnd - .L.secondarymsg - 1)
bl print
add r0, r5, #1
str r0, [r4, #4]
1:
mov r0, r4
mov r1, r5
add r2, r4, #8
bl thread_loop
b 1b
.p2align 2
.type thread_loop,%function
.code 32
thread_loop:
push {r4, r5, r6, r7, r8, lr}
mov r4, r0
mov r5, r1
mov r6, r2
bl lock_mutex_swp
str r5, [r6]
bl random_cycles
mov r8, r0
mov r0, r5
mov r1, #0
bl printnum
movw r0, :lower16:.L.idsep
movt r0, :upper16:.L.idsep
ldr r1, =(.L.idsepEnd - .L.idsep - 1)
bl print
mov r0, r8
mov r1, #1
bl printnum
1:
ldr r0, [r6]
cmp r0, r5
bne 2f
str r5, [r6]
cmp r8, #0
beq 3f
sub r8, r8, #1
b 1b
2:
mov r0, #1
ldr r7, =SYS_exit
swi 0
3:
mov r0, r4
bl unlock_mutex_swp
ldr r7, =SYS_sched_yield
swi 0
pop {r4, r5, r6, r7, r8, lr}
bx lr
.p2align 2
.type random_cycles,%function
.code 32
random_cycles:
sub sp, sp, #4
mov r0, sp
mov r1, #4
mov r2, #0
ldr r7, =SYS_getrandom
swi 0
ldr r0, [sp]
mov r1, #0xfff
and r0, r0, r1
add sp, sp, #4
bx lr
.p2align 2
.type lock_mutex_swp,%function
.code 32
lock_mutex_swp:
mov r2, #MUTEX_LOCKED
swp r1, r2, [r0]
cmp r1, r2
beq lock_mutex_swp
bx lr
.p2align 2
.type unlock_mutex_swp,%function
.code 32
unlock_mutex_swp:
mov r1, #MUTEX_UNLOCKED
str r1, [r0]
bx lr
.p2align 2
.type create_thr,%function
.code 32
create_thr:
sub sp, sp, #56
str r0, [sp, #4]
str r1, [sp, #8]
str r2, [sp, #12]
mov r0, #STACK_SIZE
str r0, [sp, #16]
str r3, [sp, #20]
mov r0, #TLS_SIZE
str r0, [sp, #24]
mov r0, #0
str r0, [sp, #28]
str r0, [sp, #32]
str r0, [sp, #36]
str r0, [sp, #40]
add r0, sp, #4
mov r1, #52
ldr r7, =SYS_thr_new
swi 0
add sp, sp, #56
bx lr
.p2align 2
.type printnum,%function
.code 32
printnum:
push {r4, r5, r6, r7, r8, r10, lr}
sub sp, #4
movw r6, #0xca00
movt r6, #0x3b9a
udiv r5, r0, r6
cmp r5, #9
bhi abort
mov r4, r0
mov r5, #0
mov r10, r1
1:
cmp r6, #0
beq 4f
udiv r0, r4, r6
cmp r5, #0
bne 2f
cmp r6, #1
beq 2f
cmp r0, #0
bne 2f
b 3f
2:
mov r5, #1
mov r8, r0
add r0, r0, #0x30
str r0, [sp]
mov r0, sp
mov r1, #1
bl print
mul r0, r8, r6
sub r4, r4, r0
3:
mov r3, #10
udiv r6, r6, r3
b 1b
4:
cmp r10, #0
beq 5f
mov r0, #0x0a
str r0, [sp]
mov r0, sp
mov r1, #1
bl print
5:
add sp, sp, #4
pop {r4, r5, r6, r7, r8, r10, lr}
bx lr
abort:
movw r0, :lower16:.L.badnum
movt r0, :upper16:.L.badnum
ldr r1, =(.L.badnumEnd - .L.badnum - 1)
bl print
mov r0, #1
ldr r7, =SYS_exit
swi 0
.p2align 2
.type print,%function
.code 32
print:
mov r2, r1
mov r1, r0
ldr r0, =STDOUT_FILENO
ldr r7, =SYS_write
swi 0
bx lr
.L.mainmsg:
.asciz "Main thread\n"
.L.mainmsgEnd:
.size .L.mainmsg, .L.mainmsgEnd - .L.mainmsg
.L.secondarymsg:
.asciz "Secondary thread\n"
.L.secondarymsgEnd:
.size .L.secondarymsg, .L.secondarymsgEnd - .L.secondarymsg
.L.badnum:
.asciz "Bad number\n"
.L.badnumEnd:
.size .L.badnum, .L.badnumEnd - .L.badnum
.L.idsep:
.asciz " - cycles "
.L.idsepEnd:
.size .L.idsep, .L.idsepEnd - .L.idsep
.type stack1,%object
.local stack1
.comm stack1,STACK_SIZE,1
.type tls1,%object
.local tls1
.comm tls1,TLS_SIZE,1
.type stack2,%object
.local stack2
.comm stack2,STACK_SIZE,1
.type tls2,%object
.local tls2
.comm tls2,TLS_SIZE,1