- add a simple implementation of a mailbox

git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@20 315a16e6-25f9-4109-90ae-ca3045a26c18
This commit is contained in:
stefan 2010-08-03 07:13:12 +00:00
parent 4b3c070275
commit c147a6a095
2 changed files with 133 additions and 17 deletions

View file

@ -0,0 +1,97 @@
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#ifndef __MAILBOX_H__
#define __MAILBOX_H__
#include <metalsvm/string.h>
#include <metalsvm/tasks.h>
#include <metalsvm/semaphore.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void* mail;
sem_t consume, produce;
} mailbox_t;
inline static int mailbox_init(mailbox_t* m) {
if (BUILTIN_EXPECT(!m, 0))
return -1;
m->mail = NULL;
sem_init(&m->consume, 0);
sem_init(&m->produce, 1);
return 0;
}
inline static int mailbox_destroy(mailbox_t* m) {
if (BUILTIN_EXPECT(!m, 0))
return -1;
sem_destroy(&m->consume);
sem_destroy(&m->produce);
return 0;
}
inline static int mailbox_post(mailbox_t* m, void* mail) {
if (BUILTIN_EXPECT(!m, 0))
return -1;
sem_wait(&m->produce);
m->mail = mail;
sem_post(&m->consume);
return 0;
}
inline static int mailbox_fetch(mailbox_t* m, void** mail) {
if (BUILTIN_EXPECT(!m || !mail, 0))
return -1;
sem_wait(&m->consume);
*mail = m->mail;
m->mail = NULL;
sem_post(&m->produce);
return 0;
}
inline static int mailbox_tryfetch(mailbox_t* m, void** mail) {
if (BUILTIN_EXPECT(!m || !mail, 0))
return -1;
if (sem_trywait(&m->consume) != 0)
return -1;
*mail = m->mail;
m->mail = NULL;
sem_post(&m->produce);
return 0;
}
#ifdef __cplusplus
}
#endif
#endif

View file

@ -26,14 +26,40 @@
#include <metalsvm/tasks.h>
#include <metalsvm/processor.h>
#include <metalsvm/semaphore.h>
#include <metalsvm/mailbox.h>
#include <asm/kb.h>
static sem_t consuming, producing;
static int val = 0;
static sem_t consuming, producing;
static mailbox_t mbox;
static int val = 0;
void* STDCALL consumer(void* arg)
{
int i;
int* m = NULL;
for(i=0; i<5; i++) {
sem_wait(&consuming);
kprintf("Consumer got %d\n", val);
val = 0;
sem_post(&producing);
}
for(i=0; i<5; i++) {
mailbox_fetch(&mbox, (void**) &m);
kprintf("Got mail %d\n", *m);
}
return NULL;
}
void* STDCALL producer(void* arg)
{
int i;
int i;
int mail[5] = {1, 2, 3, 4, 5};
tid_t id;
create_kernel_task(&id, consumer, NULL, 0);
for(i=0; i<5; i++) {
sem_wait(&producing);
@ -42,19 +68,12 @@ void* STDCALL producer(void* arg)
sem_post(&consuming);
}
return NULL;
}
void* STDCALL consumer(void* arg)
{
int i;
for(i=0; i<5; i++) {
sem_wait(&consuming);
kprintf("Consumer got %d\n", val);
val = 0;
sem_post(&producing);
}
kprintf("Send mail %d\n", mail[i]);
mailbox_post(&mbox, mail+i);
}
join_kernel_task(id);
return NULL;
}
@ -89,7 +108,7 @@ void* STDCALL join_test(void* arg)
int main(void)
{
tid_t id1, id2, id3, id4;
tid_t id1, id2, id3;
system_init();
irq_init();
@ -115,11 +134,11 @@ int main(void)
sem_init(&producing, 1);
sem_init(&consuming, 0);
mailbox_init(&mbox);
create_kernel_task(&id1, foo, "Hello from foo1\n", 8192);
create_kernel_task(&id2, join_test, NULL, 0);
create_kernel_task(&id3, producer, NULL, 0);
create_kernel_task(&id4, consumer, NULL, 0);
current_task->idle = 1;
schedule();