Mutex Implementation.

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.
User avatar
astrocrep
Member
Member
Posts: 127
Joined: Sat Apr 21, 2007 7:21 pm

Post by astrocrep »

Combuster:

Thank you soo much. You have given me enough a ton of excellent information! Ill be busy for weeks!

Thanks again,
Rich
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

astrocrep wrote:Thank you soo much. You have given me enough a ton of excellent information! Ill be busy for weeks!
You're welcome. :D
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
astrocrep
Member
Member
Posts: 127
Joined: Sat Apr 21, 2007 7:21 pm

Post by astrocrep »

My fetch and increment:

Code: Select all

unsigned long fetch_and_increment(volatile unsigned long *mem)
{
	unsigned long val = 1;
    asm volatile ("lock; xadd %1, (%2)"                              
		: "=r"(val)          
        : "r"(val), "r"(mem) 
        : "%1","memory");    
    return val;
}
Looks ok right?

It seems to be working.

If I do:

Code: Select all

int a =0;
fetch_and_increment(&a); // Returns 0
fetch_and_increment(&a); // Returns 1
fetch_and_increment(&a); // Returns 2
Thanks,
Rich
User avatar
astrocrep
Member
Member
Posts: 127
Joined: Sat Apr 21, 2007 7:21 pm

Post by astrocrep »

So... no... there not working...

At first I tried to use a struct per mutex... and failed miserably...

Now I am try something much simpler:

Code: Select all

unsigned long fetch_and_increment(volatile unsigned long *mem)
{
   unsigned long val = 1;
    asm volatile ("lock; xadd %1, (%2)"                             
      : "=r"(val)         
        : "r"(val), "r"(mem)
        : "%1","memory");   
    return val;
} 


int entries = 0;
int exits = 0;

void mutex_lock(volatile mutex_t mt)
{
     int ticket = fetch_and_increment(&entries);
     kprintf("GOT TICKET: %d\n",ticket);
     while (ticket != exits)
     {
          //schedule(); // or anything else you can do while waiting for your turn
     }
}

void mutex_unlock(volatile mutex_t mt)
{
     exits = exits + 1;
     kprintf("MADE EXIT: %d\n",exits);
} 
It runs for a brief while giving and closing tickets... but it usually locks up pretty quick...

After about 10 - 100 tickets...
However, I actually think that the tickets are all on the same thread and after the switch the switch it blows up. Ignore the function headers the volatile mutex_t mt was for something else I was testing and failed... Also if I turn entries and exits volatile, I get two grabs for ticket 1 and no exits...

If you think it matters, I post my scheduler code... but I am attaching screen shots of the output.

Thanks,
Rich
Attachments
Tickets with out volatile.
Tickets with out volatile.
crazy tickets.jpg (47.36 KiB) Viewed 4707 times
Tickets WITH volatile.
Tickets WITH volatile.
volatile tickets.jpg (69.93 KiB) Viewed 4706 times
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Have you made sure that 'entries' and 'exits' are shared among all threads?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
astrocrep
Member
Member
Posts: 127
Joined: Sat Apr 21, 2007 7:21 pm

Post by astrocrep »

No... each thread has its own esp0 stack allocated at run time.

However, I was assuming since these values would accessing the same physical address it shouldn't matter... I was wrong.

So do I need to do a context switch when I want to access a mutex?

Thanks,
Rich
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

no, just shared memory (kernel?)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
astrocrep
Member
Member
Posts: 127
Joined: Sat Apr 21, 2007 7:21 pm

Post by astrocrep »

Yeah... the first 4mb is identity mapped and the kernel starts at 1mb. Those declarations for entries and exits where with in the kernel code.

EDIT: I think I got it working!!

Thanks!!!

Thanks,
Rich
Post Reply