Code: Select all
static mutex_t *test_mutex = NULL;
static void mutex_test(void *data, uint32 length) {
if (test_mutex == NULL)
test_mutex = mutex_create();
while (true) {
mutex_lock(test_mutex);
printk("locked mutex in pid %d @ %u\n", getpid(), gettickcount());
sleep(500); // milliseconds
mutex_unlock(test_mutex);
printk("unlocked mutex in pid %d @ %u\n", getpid(), gettickcount());
}
}
Code: Select all
void mutex_lock(mutex_t *mutex) {
assert(mutex != NULL);
uint8 success = 0;
while (success == 0) {
asm volatile("LOCK BTSL $0, %[mutex];"
"SETNCB %[success];" // sets success to 1 if the mutex was locked; 0 otherwise
:
[mutex]"=m"(mutex->mutex),
[success]"=m"(success)
: : "cc", "memory");
if (success) {
mutex->owner = (task_t *)current_task;
}
else {
if (task_switching)
asm volatile("int $0x7e"); // yield this time slice
}
}
}
void mutex_unlock(mutex_t *mutex) {
assert(mutex != NULL);
assert(mutex->mutex != 0); // mutex is locked
assert(mutex->owner == current_task);
mutex->mutex = 0;
mutex->owner = NULL;
}
When a second task does manage to grab the mutex, clearly, THAT task starts hogging it instead.
Is this something to be expected, or should a good OS solve this? And, more importantly, how?
Also, if I'm doing something else wrong, please point that out.