📄 evtqueue.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* Event Queue -- impedence matcher for event passing. */#include <eros/target.h>#include <eros/Invoke.h>#include <eros/ReturnerKey.h>#include <eros/ProcessKey.h>#include <eros/NodeKey.h>#include <memory.h>#include <domain/domdbg.h>#include <domain/EventQueueKey.h>#include <domain/ProtoSpace.h>#include "constituents.h"#define KR_DOMCRE 3#define KR_SCHED 5#define KR_CLIENT 6#if EROS_NODE_SIZE != 32#error "wrong node size!"#endif#define KR_OSTREAM 28#define KR_RETURNER 29#define KR_SCRATCH 30#define KR_RESUME 31#define KI_MASTER 128 /* key info of master start key */#define NEVENT 64typedef struct evt_s { uint32_t w0; uint32_t w1; uint32_t w2;} evt_s;evt_s events[NEVENT];int firstEvent = 0;int nextEvent = 0;int count = 0; /* number of events in list */int waiting = 0; /* client is waiting */uint32_tPostEvent(Message *msg){ if (count == NEVENT) return RC_EvtQ_Full; events[nextEvent].w0 = msg->rcv_w1; events[nextEvent].w1 = msg->rcv_w2; events[nextEvent].w2 = msg->rcv_w3; nextEvent++; if (nextEvent == NEVENT) nextEvent = 0; count++; if (waiting) { Message wakemsg; bzero(&wakemsg, sizeof(wakemsg)); /* kprintf(KR_OSTREAM, "Waking sleeper\n"); */ wakemsg.snd_invKey = KR_CLIENT; wakemsg.snd_code = RC_OK; wakemsg.snd_w1 = events[firstEvent].w0; wakemsg.snd_w2 = events[firstEvent].w1; wakemsg.snd_w3 = events[firstEvent].w2; SEND(&wakemsg); kprintf(KR_OSTREAM, "Now awake\n"); waiting = 0; if (firstEvent == NEVENT) firstEvent = 0; else firstEvent++; count--; } return RC_OK;}uint32_tPollEvent(Message *msg, int shouldWait){ /* Special case if evt Q is full to pull the first item. Otherwise we can use the simple logic. */ if (count == 0) { if (shouldWait) { msg->snd_invKey = KR_VOID; waiting = 1; } return RC_EvtQ_Empty; } msg->snd_w1 = events[firstEvent].w0; msg->snd_w2 = events[firstEvent].w1; msg->snd_w3 = events[firstEvent].w2; firstEvent++; if (firstEvent == NEVENT) firstEvent = 0; count--; return RC_OK;}volatile voidteardown(){ /* get the protospace */ node_copy(KR_CONSTIT, KC_PROTOSPC, KR_SCRATCH); /* destroy as small space. */ protospace_destroy(KR_RETURNER, KR_SCRATCH, KR_SELF, KR_DOMCRE, KR_BANK, 1); /* NOTREACHED */}intProcessRequest(Message *msg){ uint32_t result = RC_OK; uint32_t code = msg->rcv_code; msg->snd_w1 = 0; msg->snd_key0 = KR_VOID; switch(code) { case OC_EvtQ_Post: result = PostEvent(msg); break; case OC_EvtQ_Poll: result = PollEvent(msg, 0); break; case OC_EvtQ_Wait: result = PollEvent(msg, 1); break; case OC_Destroy: teardown(); break; default: result = RC_UnknownRequest; break; } msg->snd_code = result; msg->rcv_key3 = waiting ? KR_RESUME : KR_CLIENT; return 1;}intmain(void){ uint32_t result; Message msg; msg.snd_invKey = KR_VOID; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_data = 0; msg.snd_len = 0; msg.snd_code = 0; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_RESUME; msg.rcv_len = 0; msg.rcv_data = 0; msg.rcv_code = 0; msg.rcv_w1 = 0; msg.rcv_w2 = 0; msg.rcv_w3 = 0; node_copy(KR_CONSTIT, KC_RETURNER, KR_RETURNER); node_copy(KR_CONSTIT, KC_OSTREAM, KR_OSTREAM); /* Fabricate the master start key and arrange to return that: */ result = process_make_start_key(KR_SELF, 0, KR_SCRATCH); if (result != RC_OK) kdprintf(KR_OSTREAM, "Result from evtq cre strt key: 0x%x\n", result); msg.snd_key0 = KR_SCRATCH;#ifdef USE_RETURNER msg.snd_invKey = KR_RETURNER; msg.snd_key3 = KR_RESUME;#else msg.snd_invKey = KR_RESUME;#endif msg.rcv_key3 = KR_CLIENT; RETURN(&msg); msg.snd_key0 = KR_VOID; for(;;) { msg.snd_invKey = msg.rcv_key3; (void) ProcessRequest(&msg); RETURN(&msg); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -