Mutex implementation almost working.

- Fixed a wrong instruction in mutex.S user library
- Added support for blocking lock/unlock
- Divided waiting into wait_on_prepare and wait_on_prepared_wait
  so that mutex_control lock is released after getting in the waitqueue.
- Declaring waitqueue on the stack should be done outside wait_on_prepare

Issues:
- Tests can be simplified for atomic data access instead of producer/consumer.
- kmalloc variable sized memory caches are not freed properly. Currently only the
  last slot can be freed, occupied correctly. it should be done in any slot, i.e.
  1, 2, 3, 4 instead of just 5.
- Need to add a mutex to kmalloc.
This commit is contained in:
Bahadir Balban
2009-06-01 14:11:40 +03:00
parent 2bd26ce684
commit 33200c92df
8 changed files with 172 additions and 38 deletions

View File

@@ -56,7 +56,7 @@ BEGIN_PROC(__l4_mutex_unlock)
swp r2, r3, [r0]
cmp r2, r1 @ Check lock had original tid value
movne r0, #L4_MUTEX_CONTENDED @ Indicate contention
movne r0, #L4_MUTEX_SUCCESS @ Indicate no contention
moveq r0, #L4_MUTEX_SUCCESS @ Indicate no contention
cmp r2, #L4_MUTEX_UNLOCKED @ Or - was it already unlocked?
1:
beq 1b @ If so busy-spin to indicate bug.

View File

@@ -50,18 +50,28 @@ void l4_mutex_init(struct l4_mutex *m)
int l4_mutex_lock(struct l4_mutex *m)
{
l4id_t tid = self_tid();
int err;
while(__l4_mutex_lock(m, tid) == L4_MUTEX_CONTENDED)
l4_mutex_control(&m->lock, L4_MUTEX_LOCK);
while(__l4_mutex_lock(m, tid) == L4_MUTEX_CONTENDED) {
if ((err = l4_mutex_control(&m->lock, L4_MUTEX_LOCK)) < 0) {
printf("%s: Error: %d\n", __FUNCTION__, err);
return err;
}
}
return 0;
}
int l4_mutex_unlock(struct l4_mutex *m)
{
l4id_t tid = self_tid();
int err;
if (__l4_mutex_unlock(m, tid) == L4_MUTEX_CONTENDED)
l4_mutex_control(&m->lock, L4_MUTEX_UNLOCK);
if (__l4_mutex_unlock(m, tid) == L4_MUTEX_CONTENDED) {
if ((err = l4_mutex_control(&m->lock, L4_MUTEX_UNLOCK)) < 0) {
printf("%s: Error: %d\n", __FUNCTION__, err);
return err;
}
}
return 0;
}

View File

@@ -52,9 +52,9 @@ void main(void)
ipc_full_test();
ipc_extended_test();
}
// if (parent_of_all == getpid()) {
// user_mutex_test();
// }
if (parent_of_all == getpid()) {
user_mutex_test();
}
exectest();
while (1)

View File

@@ -68,11 +68,10 @@ int user_mutex_test(void)
/* Initialize buffer with unique child value */
printf("Initializing shared page with child values.\n");
BUG();
shared_page->child_has_run = 0;
shared_page->parent_has_run = 0;
for (int i = 0; i < buf_size; i++)
shared_page->page_rest[i] = 'c';
shared_page->page_rest[i] = 0;
/* Fork the current task */
if ((child = fork()) < 0) {
@@ -88,17 +87,20 @@ int user_mutex_test(void)
/* Child locks and produces */
if (child == 0) {
for (int i = 0; i < 5; i++) {
for (int x = 0; x < 255; x++) {
/* Lock */
printf("Child locking page.\n");
l4_mutex_lock(&shared_page->mutex);
printf("Child locked page.\n");
l4_thread_switch(0);
/* Get sample value */
char val = shared_page->page_rest[0];
//char val = shared_page->page_rest[0];
/* Write a unique child value to whole buffer */
for (int i = 0; i < buf_size; i++) {
#if 0
/* Check sample is same in all */
if (shared_page->page_rest[i] != val) {
printf("Sample values dont match. "
@@ -107,22 +109,26 @@ int user_mutex_test(void)
shared_page->page_rest[i], val);
goto out_err;
}
shared_page->page_rest[i] = 'c';
#endif
shared_page->page_rest[i]--;
}
printf("Child produced.\n");
printf("Child produced. Unlocking...\n");
/* Unlock */
l4_mutex_unlock(&shared_page->mutex);
printf("Child unlocked page.\n");
}
/* Sync with the parent */
l4_send(parent, L4_IPC_TAG_SYNC);
/* Parent locks and consumes */
} else {
for (int i = 0; i < 5; i++) {
for (int x = 0; x < 255; x++) {
printf("Parent locking page.\n");
/* Lock the page */
l4_mutex_lock(&shared_page->mutex);
printf("Parent locked page.\n");
l4_thread_switch(0);
// printf("Parent reading:\n");
@@ -130,6 +136,7 @@ int user_mutex_test(void)
for (int i = 0; i < buf_size; i++) {
// printf("%c", shared_page->page_rest[i]);
/* Test that child has produced */
#if 0
if (shared_page->page_rest[i] != 'c') {
printf("Child not produced. "
"page_rest[%d] = %c, "
@@ -138,14 +145,22 @@ int user_mutex_test(void)
BUG();
goto out_err;
}
#endif
/* Consume the page */
shared_page->page_rest[i] = 'P';
shared_page->page_rest[i]++;
}
// printf("\n\n");
printf("Parent consumed.\n");
printf("Parent consumed. Unlocking...\n");
l4_mutex_unlock(&shared_page->mutex);
printf("Parent unlocked page.\n");
}
/* Sync with the child */
l4_receive(child);
printf("Parent checking validity of values.\n");
for (int i = 0; i < 255; i++)
if (shared_page->page_rest[i] != 0)
goto out_err;
printf("USER MUTEX TEST: -- PASSED --\n");
}