0

I am currently learning about operating systems and was wondering, using these definitions, would this be working as expected or am I missing some atomic operations?

int locked = 0;

void lsLock(){
  while(1) {
    if (locked){
      continue;
    } else {
      locked = 1;
      break;
    }
  } 
}

void lsUnlock(){
  locked = 0;
}

Thanks in advance!

Flowmotion
  • 143
  • 1
  • 1
  • 6
  • 2
    No. Spinlock implementation requires locking instructions which are not standard. You need to use compiler-specific code to implement it. You can start by looking here https://stackoverflow.com/questions/1383363/is-my-spin-lock-implementation-correct-and-optimal – Robert Jul 15 '21 at 06:42
  • 3
    Imagine two threads running the `lsLock` function, both of them start execution with `locked == 0` - both of them check `if (locked)` - both of them see that it's zero - both of them lock it. – Daniel Kleinstein Jul 15 '21 at 07:01
  • @4386427 I forgot the break in the else block. But even with it, it won't work, right? – Flowmotion Jul 15 '21 at 07:10
  • @Flowmotion No, it won't work. For several reasons. – Support Ukraine Jul 15 '21 at 07:54

1 Answers1

2

The first problem is that the compiler assumes that nothing will be altered by anything "external" (unless it's marked volatile); which means that the compiler is able to optimize this:

int locked = 0;

void lsLock(){
  while(1) {
    if (locked){
      continue;
    } else {
      locked = 1;
      break;
    }
  } 
}

..into this:

int locked = 0;

void lsLock(){
  if (locked){
    while(1) { }
  }
  locked = 1;
}

Obviously that won't work if something else modifies locked - once the while(1) {} starts it won't stop. To fix that, you could use volatile int locked = 0;.

This only prevents the compiler from assuming locked didn't change. Nothing prevents a theoretical CPU from playing similar tricks (e.g. even if volatile is used, a non-cache coherent CPU could not realize a different CPU altered locked). For a guarantee you need to use atomics or something else (e.g. memory barriers).

However; with volatile int locked it may work, especially for common 80x86 CPUs. Please note that "works" can be considered the worst possibility - it leads to assuming that the code is fine and then having a spectacular (and nearly impossible to debug due to timing issues) disaster when you compile the same code for a different CPU.

Brendan
  • 35,656
  • 2
  • 39
  • 66