diff --git a/23-rseq/rseq-asm.S b/23-rseq/rseq-asm.S
index 6a15529..1d3fd9d 100644
--- a/23-rseq/rseq-asm.S
+++ b/23-rseq/rseq-asm.S
@@ -16,14 +16,16 @@ operation_rseq:
// to the kernel-registered rseq object.
// After an abort, we also jump to this label (restart_ip)
.restart_ip:
- // FIXME: Update rseq->rseq_cs
+ lea operation_rseq_cs(%rip), %rcx // %rcx = &operation_rseq_cs
+ mov %rcx, 8(%rdi) // rseq->rseq_cs = %rcx
// The restartable sequence
// Implements: [rseq->cpu_id].counter ++;
.start_ip: // Start of restartable sequence
- // HINT: Structure of rseq is documented in /usr/include/linux/rseq.h
- // HINT: rseq->cpu_id == 4(%rdi)
- // HINT: Each counter-cache-line is 64 bytes lon
+ mov 4(%rdi), %ecx // %rcx = rseq->cpu_id
+ sal $6, %rcx // %rcx = %rcx * 64
+ add %rsi, %rcx // %rcx = counters + %rcx
+ addq $1, (%rcx) // *%rcx = *rcx + 1
.end_ip: // End of restartable sequence
ret
@@ -36,7 +38,7 @@ operation_rseq:
.byte 0x0f, 0xb9, 0x3d
.long 0x53053053 // RSEQ_SIG
.abort_ip: // On abort, the kernel will jump here
- // FIXME: count aborts in %eax
+ add $1, %eax // %eax += 1
jmp .restart_ip
// } End of operation_rseq()
diff --git a/23-rseq/rseq.c b/23-rseq/rseq.c
index 18ab560..c58a787 100644
--- a/23-rseq/rseq.c
+++ b/23-rseq/rseq.c
@@ -102,7 +102,9 @@ int operation_lock(struct rseq*_, struct cacheline *counters) {
// Variant that uses getcpu() + atomic_fetch_add
int operation_atomic(struct rseq* _, struct cacheline *counters) {
- // FIXME: Implement variant
+ unsigned int cpu_id;
+ getcpu(&cpu_id, NULL);
+ atomic_fetch_add(&counters[cpu_id].counter, 1);
return 0;
}
@@ -111,7 +113,8 @@ int operation_atomic(struct rseq* _, struct cacheline *counters) {
// restartable sequence to retrieve the cpu id.
// Please look at /usr/include/linux/rseq.h for the documentation of struct rseq
int operation_rseq_atomic(struct rseq* rs, struct cacheline *counters) {
- // FIXME: Implement variant
+ unsigned int cpu_id = rs->cpu_id;
+ atomic_fetch_add(&counters[cpu_id].counter, 1);
return 0;
}
@@ -120,7 +123,6 @@ int operation_rseq_atomic(struct rseq* rs, struct cacheline *counters) {
// Variant that uses no atomic operations and fully relies on rseq
// This variant is implemented in assembler (see rseq.S)
extern int operation_rseq(struct rseq *, struct cacheline*);
-// FIXME: Implement counter_rseq in rseq.S
////////////////////////////////////////////////////////////////