OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 4:31 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Spin lock implementation and interrupts
PostPosted: Sat Jan 09, 2021 7:51 am 
Offline
Member
Member

Joined: Tue Apr 03, 2018 2:44 am
Posts: 402
thewrongchristian wrote:
nexos wrote:
Ethin wrote:
You need to send the EOI in the interrupt routine, not when your loading the LDT/IDT. So you'd send the EOI right after incrementing the tick counter.
Also, just a side note: you may wish to turn that tick counter into an atomic integer, especially once you get to SMP. Better to do it earlier than later though. (That's my Rust background speaking, but its generally good to use mutex/locks/atomics on static mutable variables if possible. You can wait though if you don't know how.)

Using a spinlock on a uniproccesser is one of the worst performace decisions out there. For example, T1 acquires a spinlock and gets preempted by T2 while that holding spinlock. T2 then acquires that same spinlock and sitsin its whole timeslice looping. For the timer counter, it would just be better to have a per CPU timer. I think we just got waay off topic.


If you're pre-empting code that has a spin lock, you're doing it wrong whether you're on UP or MP.

I get nervous about even calling other functions with a spin lock held, and anything protected by a spin lock should be held for the minimal amount of time. I spin lock my scheduler, device driver structures that need to communicate with interrupt handlers, and higher level synchronisation structures like mutexes, which maintain wait lists. Everything else uses the higher primitives built on top of spin locks.

And while you hold the spin lock, you should also disable interrupts, to prevent an interrupt handler also trying to get that spin lock, further reinforcing the notion that spin locks should be help for the minimal amount of time.


I'm making a big presumption on how spin locks should be implemented. Some of that is based on experience, I didn't have a reliable way of synchronising between a driver and its interrupt handlers, as my first spin lock implementation didn't disable interrupts and I'd deadlock when an interrupt handler tried to lock a spin lock already held by the interrupted code.

Looking through the forums, spin locks tend to be advised to be used with interrupts disabled.

But looking at the Spinlock wiki page, no mention is made of interrupts.

Is this a hole in the wiki page?


Top
 Profile  
 
 Post subject: Re: Spin lock implementation and interrupts
PostPosted: Sat Jan 09, 2021 9:53 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3192
thewrongchristian wrote:
I'm making a big presumption on how spin locks should be implemented. Some of that is based on experience, I didn't have a reliable way of synchronising between a driver and its interrupt handlers, as my first spin lock implementation didn't disable interrupts and I'd deadlock when an interrupt handler tried to lock a spin lock already held by the interrupted code.

Looking through the forums, spin locks tend to be advised to be used with interrupts disabled.

But looking at the Spinlock wiki page, no mention is made of interrupts.

Is this a hole in the wiki page?


You don't need to have interrups disabled all the time, but before attempting to take the spinlock you should disable interrupts, do the protected operation and then release the lock and enable interrupts. If taking the spinlock fails, it's ok to enable interrupts, execute a "yield" instruction and try again.

Generally, when programming for single core systems enable/disable interrupts is sufficient to protect & synchronize code with IRQs, but when there are multiple cores involved, every instance of enable/disable intterupts potentially needs to be replaced with spinlocks to be multicore safe.

Example of spinlock implementation for x86:

Code:
InitSpinlock     MACRO spinlock
    mov spinlock.sl_value,0
                        ENDM

RequestSpinlock MACRO spinlock
    local rs_lock
    local rs_get
    local rs_done
    local rs_pause

    push ax
    push cx
;
    xor cx,cx

rs_lock:   
    mov ax,spinlock.sl_value
    or ax,ax
    je rs_get
;
    sti
    add cx,1
    jnc rs_pause
;
    CrashGate

rs_pause:   
    pause
    jmp rs_lock

rs_get:
    cli
    inc ax
    xchg ax,spinlock.sl_value
    or ax,ax
    je rs_done
;
    jmp rs_lock

rs_done:
    pop cx
    pop ax
    ENDM


ReleaseSpinlock MACRO spinlock
    mov spinlock.sl_value,0
    sti
    ENDM


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 24 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group