Please keep in mind, I am looking for opinions on it, not code correctness.
Basically I have a Double linked list. Each Item in the linked list coresponds to a Resource type, mostlikely a constant definition. Then each resource would have a linked list of guys wanting to use it... FiFo.
ie:
Code: Select all
void printf(...)
{
MUTEX_LOCK(MUTEX_CONSOLEOUT);
...
...
...
MUTEX_UNLOCK(MUTEX_CONSOLEOUT);
}
Code: Select all
struct mutex_item {
mutex_item * next;
mutex_item * last;
long thread_id;
}
struct mutex_type {
mutex_type * next;
mutex_type * last;
long mutex_id;
mutex_item * head;
}
void MUTEX_LOCK(long pMUTEXT_ID)
{
mutex_type *my_mutex_type;
mutex_item *my_mutex_item;
//STOP INTs
disable()
//Go through all of the mutex types in the primary linked list
for each mutex_type in the mutex_type linked list
if the mutex_type.mutex_id = pMUTEXT_ID then
my_mutex_type = this mutex_type
break the loop
//If this mutex does not yet have an entry, create one.
if my_mutex_type is empty then
my_mutex_type = kmalloc(sizeof(mutex_type))
add my_mutex_type to the end of the mutex_type linked list
//By now we should have a valid my_mutex_type
//If the mutex is free (head = 0) means nothing is in queue
if my_mutex_type.head == 0 then
//Create a new item for the mutex queue and load it in there
my_mutex_item = kmalloc(sizeof(mutex_item))
my_mutex_item.thread_id = GetCurrentThreadID()
my_mutex_item.next = 0
my_mutex_item.last = 0
my_mutex_type.head = my_mutex_item
//START INTs
enable()
return
else
//So there is already a line for this mutex
//Lets find the end of the line
for each mutex_item in my_mutex_type.head linked list
if the mutex_item.next = 0 then
//Now lets add the entry for this thread
my_mutex_item = kmalloc(sizeof(mutex_item))
my_mutex_item.thread_id = GetCurrentThreadID()
my_mutex_item.next = 0
my_mutex_item.last = the last mutex_item in the linked list
my_mutex_type.head = my_mutex_item
//So now we wait until our time has come.
MOVE_TO_WAIT(my_mutex_item.thread_id)
//START INTs
enable()
}
void MUTEX_UNLOCK(long pMUTEXT_ID)
{
mutex_type *my_mutex_type;
mutex_item *my_mutex_item;
//STOP INTs
disable()
//Go through all of the mutex types in the primary linked list
for each mutex_type in the mutex_type linked list
if the mutex_type.mutex_id = pMUTEXT_ID then
my_mutex_type = this mutex_type
break the loop
//Sanity check
if my_mutex_type.head <> 0 then
my_mutex_item = my_mutex_type.head
//Sanity check again
if my_mutex_item.thread_id <> GetCurrentThreadID() then
PANIC("OHHH CRUDE!!!")
//Remove me from the queue
my_mutex_type.head = my_mutex_item.next
my_mutex_item = my_mutex_type.head
//The next call places it at the HEAD of the ready queue to ensure that it will be the next go to access this resource
JUMP_TO_READY(my_mutex_item.thread_id)
//START INTs
enable()
}
Rich