summaryrefslogtreecommitdiff
path: root/demo/atomic.S
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-10-06 07:37:16 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-06 07:37:16 -0600
commit39fd8b8428da1e4bb0a182e1bcc61ec2d54563a4 (patch)
treea4dedd73b8fbfdfbfd1c2ca8c1a4c4a983fd9e26 /demo/atomic.S
parentfac14c8c03592f101d34116cb8ecde908e92c18b (diff)
demo: implement remote cmds
Diffstat (limited to 'demo/atomic.S')
-rw-r--r--demo/atomic.S50
1 files changed, 50 insertions, 0 deletions
diff --git a/demo/atomic.S b/demo/atomic.S
new file mode 100644
index 0000000..991ad5a
--- /dev/null
+++ b/demo/atomic.S
@@ -0,0 +1,50 @@
+.global spin_init
+spin_init:
+ mov r1, #0
+ str r1, [r0]
+ mov pc, lr
+
+.global spin_lock
+spin_lock:
+ mrs r2, cpsr
+ str r2, [r1]
+ orr r2, r2, #0xc0 @ Levanta I, F
+ msr cpsr_c, r2
+ mov r3, #1
+1: ldrex r2, [r0] @ se carga el valor del lock
+ teq r2, #0 @ se revisa si el valor del lock, si es 1, se brinca al jump
+ strexeq r2, r3, [r0] @ trata de guardar r3 en r0, pero solo si el monitor se lo permite
+ teqeq r2, #0 @ revisa si en efecto se hizo el store o no
+ bne 1b @ regresa al inicio
+ mov pc, lr @ retorna de la función
+ @
+ @ la implicación de esto es que si dos
+ @ cores intentan hacer accesar al mismo
+ @ recurso, el monitor solo va a dejar a uno
+ @ de ellos hacerlo
+.global spin_unlock
+spin_unlock:
+ mov r2, #0
+ str r2, [r0]
+ msr cpsr_c, r1
+ mov pc, lr
+
+.global compare_exchange_64
+compare_exchange_64:
+ push {r4, r5, r6, r7, r8}
+ ldr r4, [r1]
+ ldr r5, [r1, #4]
+ add r8, r0, #4
+ ldrex r6, [r0]
+ ldrex r7, [r8]
+ teq r4, r6
+ teqeq r5, r7
+ strexeq r4, r2, [r0]
+ strexeq r4, r3, [r8]
+ teqeq r4, #0
+ moveq r0, #1
+ movne r0, #0
+ strne r6, [r1]
+ strne r7, [r1, #4]
+ pop {r4, r5, r6, r7, r8}
+ mov pc, lr