As learning XV6's spinlock,I thought a problem and don't find answer in google.
In spinlock, pushcli()
and popcli()
used to insure interrupt handler run currently:
void pushcli(void)
{
int eflags;
eflags = readeflags();
cli();
if (mycpu()->ncli == 0)
mycpu()->intena = eflags & FL_IF;
mycpu()->ncli += 1;
}
void popcli(void)
{
if (readeflags() & FL_IF)
panic("popcli - interruptible");
if (--mycpu()->ncli < 0)
panic("popcli");
if (mycpu()->ncli == 0 && mycpu()->intena)
sti();
}
However, the spinlock is used to dure with threads and func in it like xchg()
should be atomic,but codes in pushcli()
and popcli
like mycpu()->ncli += 1;
are not atomic , which might cause incorrect result of ncli and intena.So why we can use nonatomic operations in pushcli()
?If we shouldn't, what can we do to correct it to safe?