1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
|