📄 reader.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * * 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. *//* Signal MUX -- distributor for single-bit signals */#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/SigMuxKey.h>#include <domain/ProtoSpace.h>#define KR_VOID 0#define KR_CONSTIT 1#define KR_SELF 2#define KR_DOMCRE 3#define KR_BANK 4#define KR_SCHED 5#define KR_OSTREAM 6#define KR_SCRATCH 29#define KR_SIGMUX 30#define KR_RESUME 31#define KC_OSTREAM 0const uint32_t __rt_stack_pages = 1;const uint32_t __rt_stack_pointer = 0x20000;#if 0#define KC_RETURNER 1#define KC_PROTOSPC 2intProcessRequest(Message *msg){ int i; uint32_t result = RC_OK; uint32_t code = msg->rcv_code; Message wakeMsg; msg->snd_w1 = 0; msg->snd_key0 = KR_VOID; bzero(&wakeMsg, sizeof(wakeMsg)); switch(code) { case OC_SigMux_Post: { if (msg->rcv_keyInfo != KI_MASTER) { result = RC_UnknownRequest; break; } for (i = 0; i < NCLIENT; i++) { uint32_t shouldWake = 0; client[i].pending |= msg->rcv_w1; if (client[i].sleeping) { shouldWake = client[i].wakeup & client[i].pending; client[i].pending &= ~shouldWake; if (shouldWake) { wakeMsg.snd_w1 = shouldWake; wakeMsg.snd_invKey = KR_CLIENT(i); SEND(&wakeMsg); } } } break; } case OC_SigMux_Wait: { uint32_t shouldWake; if (msg->rcv_keyInfo >= NCLIENT) { result = RC_UnknownRequest; break; } i = msg->rcv_keyInfo; client[i].wakeup = msg->rcv_w1; shouldWake = client[i].wakeup & client[i].pending; msg->snd_w1 = shouldWake; if (shouldWake) { client[i].sleeping = 0; client[i].pending &= ~shouldWake; /* We will simply return to the caller */ } else { client[i].sleeping = 1; msg->snd_invKey = KR_VOID; copy_key_reg(KR_RETURNER, KR_RESUME, KR_CLIENT(i)); } break; } case OC_SigMux_MakeRecipient: { if (msg->rcv_keyInfo != KI_MASTER) { result = RC_UnknownRequest; break; } if (msg->rcv_w1 < NCLIENT) { result = process_make_start_key(KR_SELF, msg->rcv_w1, KR_SCRATCH); msg->snd_key0 = KR_SCRATCH; } else { result = RC_RequestError; } break; } case OC_Destroy: teardown(); return 0; /* CAN'T HAPPEN */ default: result = RC_UnknownRequest; break; } msg->snd_code = result; return 1;}voidInitSigMux(){ int i; for (i = 0; i < NCLIENT; i++) { client[i].pending = 0; client[i].wakeup = 0; client[i].sleeping = 0; }}#endifvoidmain(void){ uint32_t myid; uint32_t sleepmask = 0; 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_SIGMUX; 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_OSTREAM, KR_OSTREAM); /* Fabricate the master start key and arrange to return that: */ process_make_start_key(KR_SELF, 0, KR_SCRATCH); msg.snd_key0 = KR_SCRATCH; msg.snd_invKey = KR_RESUME; /* Return to our fabricator, who will call us back */ RETURN(&msg); myid = msg.rcv_w1; msg.rcv_key0 = KR_VOID; msg.snd_invKey = KR_SIGMUX; if (myid == 0) sleepmask = 1 | 2 | 4 | 8; if (myid & 1) sleepmask |= 1; if (myid & 2) sleepmask |= 2; if (myid & 4) sleepmask |= 4; if (myid & 8) sleepmask |= 8; kprintf(KR_OSTREAM, "Reader %d is initialized.\n", myid); for (;;) { uint32_t outmask; sigmux_wait(KR_SIGMUX, sleepmask, &outmask); kprintf(KR_OSTREAM, "Reader %d wakes on 0x%08x\n", myid, outmask); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -