Ich bin neu in den Low-Level-Zeug, so dass ich völlig vergessen bin, welche Art von Problemen Sie dort unten konfrontiert werden und ich bin nicht einmal sicher, ob ich den Begriff "Atom" richtig verstehe. Im Moment versuche ich, einfache atomare Sperren um Speichermanipulation über erweiterte Assembly zu machen. Warum? Aus Neugierde. Ich weiß, dass ich das Rad hier neu erfinde und möglicherweise den ganzen Prozess zu sehr vereinfache.Sperrt Speicher-Manipulation über Inline-Assembly
Die Frage? Hat der Code, den ich hier vorstelle, das Ziel, Speichermanipulation sowohl threadsafe als auch reentrant zu machen?
- Wenn es funktioniert, warum?
- Wenn es nicht funktioniert, warum?
- Nicht gut genug? Soll ich zum Beispiel das Register Stichwort in C verwenden?
Was ich einfach tun wollen ...
- Bevor Speichermanipulation, sperren.
- Nach der Speicherbearbeitung entsperren.
Der Code:
volatile int atomic_gate_memory = 0;
static inline void atomic_open(volatile int *gate)
{
asm volatile (
"wait:\n"
"cmp %[lock], %[gate]\n"
"je wait\n"
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (1)
);
}
static inline void atomic_close(volatile int *gate)
{
asm volatile (
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (0)
);
}
Dann so etwas wie:
void *_malloc(size_t size)
{
atomic_open(&atomic_gate_memory);
void *mem = malloc(size);
atomic_close(&atomic_gate_memory);
return mem;
}
#define malloc(size) _malloc(size)
.. gleiche gilt für calloc, realloc, frei und Gabel (für Linux).
#ifdef _UNISTD_H
int _fork()
{
pid_t pid;
atomic_open(&atomic_gate_memory);
pid = fork();
atomic_close(&atomic_gate_memory);
return pid;
}
#define fork() _fork()
#endif
Nach dem Stapelrahmen für atomic_open Laden objdump erzeugt:
00000000004009a7 <wait>:
4009a7: 39 10 cmp %edx,(%rax)
4009a9: 74 fc je 4009a7 <wait>
4009ab: 89 10 mov %edx,(%rax)
Auch angesichts der oben Demontage; kann ich annehmen, dass ich eine atomare Operation mache, weil es nur eine Anweisung ist?
Nein, es ist nicht threadsicher, da zwei Threads simultan die 'cmp' ausführen könnten und annehmen, dass sie die Sperre übernehmen können. – Jester
@Jester Oh, snap ... Ich hatte irgendwie angenommen, dass die CPU nur einen Satz Befehle gleichzeitig ausführt, wobei sie mit verschiedenen Befehlssätzen verschachtelt wird, wenn sie in mehreren Zeilen enthalten sind ... Das kompliziert die Dinge wirklich ... – user1235831
Interleaving (Multitasking) verursacht auch das gleiche Problem. Nachdem ein Thread den 'cmp' erstellt hat, könnte der nächste Thread die CPU bekommen und auch seinen' cmp'. – Jester