Basic questions about theLOCK, it doesn't work as I thought.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
nicesj
Member
Member
Posts: 27
Joined: Fri May 06, 2005 11:00 pm
Location: South Korea
Contact:

Basic questions about theLOCK, it doesn't work as I thought.

Post by nicesj »

Hello,.

Currently I'm implementing some synchronization methods such as spinlock, semaphore, mutex, ...

But those are not working correctly,. so I paste some codes from my kernel to here.
Would you let me know what I've missed?
Thank you..

Code: Select all

void spinlock_lock(spin_lock_t *handle)
{
//      while (handle->lock) DbgPrint("a %p\n", kthread_get_current());
//      handle->lock = 1;
//      return;
//      cursor_set_pos(0, 0);
//      DbgPrint("===== [Task %p] =====\n", kthread_get_current());

        asm __volatile__ (
//              "cli\n"
                "clc\n"
                "1:\n"
                "lock; btsl $0, %0\n"
//              "sti\n"
//              "nop; nop; nop; nop\n"
//              "nop; nop; nop; nop\n"
//              "cli\n"
                "jc 1b\n"
//              "sti\n"
                :
                : "m"(handle->lock)
                : "memory"
        );

//      PANIC("Locked %d\n", handle->lock);
//      if (handle->lock > 1) PANIC("Error\n");
}
When I enable the "nop" instruction, only one thread works, (there are 3 threads are exists)
but if I disable "nop" instruction, no threads are woking,. and the kernel starting to busy-waiting. :(
http://nicesj.com
With the software, What You Think Is What You Get.(WYTIWYG)
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Basic questions about theLOCK, it doesn't work as I thought.

Post by JamesM »

Hi,

The LOCK prefix just locks the bus; you say three "threads" are running, are those on different cores? If they're on the same core just timesliced, the LOCK prefix will have absolutely no effect.

For mutexes and semaphores, the instruction you want to look at is "lock cmpxchg". Or you could do what I do and use the GCC builtins.
User avatar
nicesj
Member
Member
Posts: 27
Joined: Fri May 06, 2005 11:00 pm
Location: South Korea
Contact:

Re: Basic questions about theLOCK, it doesn't work as I thought.

Post by nicesj »

only you have interested on me. Thank you James,M

I found the timing problem,. timer interrupt does not occurs between release spin-lock, and re-acquire spin-lock.
even if A thread releases the spin-lock, timer interrupt does not occurs before acquiring spinlock again.
so the only one thread can get the lock, there is no time to get the lock by other thread.

To solve this problem, I have added a trap, which is invoke the scheduler forcely.

here is the code of my spinlock implementation.
(I have changed the asm code from using btsl/btrl to using xchg, there is no differences to implement the spinlock, but many people uses xchg instead of btsl/btrl, so I decide to follow them,. there is no other intension or problem..:)


// Unlock

Code: Select all

        asm __volatile__ (
                "movl $0, %%eax;\n"
                "xchgl %0, %%eax;\n"
                "int $0x30\n"   // yield
                : "=m"(handle->lock)
                : "m"(handle->lock)
                : "memory", "%eax"
        );
// Lock

Code: Select all

 
       asm __volatile__ (
                "movl $1, %%eax\n"
                "1:\n"
                "xchgl %0, %%eax;\n"
                "testl %%eax, %%eax;\n"
                "jnz 1b\n"
                : "=m"(handle->lock)
                : "m"(handle->lock)
                : "memory", "%eax"
        );      

If I have missed something, or anybody knows more better way to solve this timing problem, would you let me know it?
Thank you.

and I will use builtin functions to handes atomic variables in the near future. Thanks James,M.
http://nicesj.com
With the software, What You Think Is What You Get.(WYTIWYG)
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Basic questions about theLOCK, it doesn't work as I thought.

Post by JamesM »

nicesj wrote:only you have interested on me. Thank you James,M

I found the timing problem,. timer interrupt does not occurs between release spin-lock, and re-acquire spin-lock.
even if A thread releases the spin-lock, timer interrupt does not occurs before acquiring spinlock again.
so the only one thread can get the lock, there is no time to get the lock by other thread.

To solve this problem, I have added a trap, which is invoke the scheduler forcely.

here is the code of my spinlock implementation.
(I have changed the asm code from using btsl/btrl to using xchg, there is no differences to implement the spinlock, but many people uses xchg instead of btsl/btrl, so I decide to follow them,. there is no other intension or problem..:)


// Unlock

Code: Select all

        asm __volatile__ (
                "movl $0, %%eax;\n"
                "xchgl %0, %%eax;\n"
                "int $0x30\n"   // yield
                : "=m"(handle->lock)
                : "m"(handle->lock)
                : "memory", "%eax"
        );
// Lock

Code: Select all

 
       asm __volatile__ (
                "movl $1, %%eax\n"
                "1:\n"
                "xchgl %0, %%eax;\n"
                "testl %%eax, %%eax;\n"
                "jnz 1b\n"
                : "=m"(handle->lock)
                : "m"(handle->lock)
                : "memory", "%eax"
        );      

If I have missed something, or anybody knows more better way to solve this timing problem, would you let me know it?
Thank you.

and I will use builtin functions to handes atomic variables in the near future. Thanks James,M.

Hi, you don't appear to be changing interrupts anywhere - have you actually "sti"'d? Are you sure interrupts are enabled?

The PIC queues up pending interrupts, and when you set the "IF" flag in EFLAGS, the PIC immediately dispatches an interrupt. So you see it is impossible for the lock to be released then locked again before a queued interrupt is serviced.

It sounds like you have a stray "cli" somewhere.
Post Reply