📄 invocation.hxx
字号:
#ifndef __INVOKE_HXX__#define __INVOKE_HXX__/* * 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. *//* This file requires #include <eros/memory.h> (for bcopy) *//* This file requires #include <kerninc/Key.hxx> *//* This file requires #include <disk/KeyStruct.hxx> *//* This file requires #include <kerninc/kernel.hxx> *//* There are real speed advantages to the assymetry in these * structures. The entry keys do not need to be copied from their key * registers, and every key you don't have to copy saves about 60 * instructions in the IPC path. */struct EntryBlock { fixreg_t code; fixreg_t w1; fixreg_t w2; fixreg_t w3; uint8_t *data; uint32_t len; Key *key[4]; EntryBlock() { key[0] = 0; key[1] = 0; key[2] = 0; key[3] = 0; }};struct ExitBlock { fixreg_t code; fixreg_t w1; fixreg_t w2; fixreg_t w3; uint8_t *data; uint32_t len; Key *pKey[4]; ExitBlock() { pKey[0] = 0; pKey[1] = 0; pKey[2] = 0; pKey[3] = 0; }};#ifndef NDEBUGextern bool InvocationCommitted;#endif#if 0#define INV_RESUMEKEY 0x100u#endif#define INV_SCRATCHKEY 0x200u#define INV_REDNODEKEY 0x400u#define INV_EXITKEY0 0x001u#define INV_EXITKEY3 0x008u#define INV_EXITKEYOTHER 0x00eu#ifdef OPTION_DDBextern uint32_t ddb_inv_flags;#define DDB_INV_all 0x1u#define DDB_INV_gate 0x2u#define DDB_INV_return 0x4u#define DDB_INV_keeper 0x8u#define DDB_INV_keyerr 0x10u#define DDB_INV_pflag 0x20u /* a per-process debug flag has been set */#endif /* OPTION_DDB */struct Invocation { uint32_t flags; Key *key; /* key that was invoked */#if 0 Key resumeKey; /* synthesized resume key */#endif Key scratchKey; /* for call on red segments; not usually used. */ Key redNodeKey; /* for seg keeper; not usually used. */ bool suppressXfer; /* should transfer be suppressed? */ uint32_t invType; /* extracted from the key for efficiency */ EntryBlock entry; ExitBlock exit; uint32_t validLen; uint8_t keyType; /* extracted from the key for efficiency */ uint32_t nextPC; /* PC of the instruction that will run */ /* after the current invocation completes. */ Process *invokee; /* extracted from the key for efficiency */ /* Copy at most COUNT bytes in from the process. If the process * send length is less than COUNT, copy the number of bytes in the * send buffer. Return the number of bytes transferred. */ inline uint32_t CopyIn(uint32_t count, void *where); /* Copy at most COUNT bytes out to the process. If the process * receive length is less than COUNT, silently truncate the outgoing * bytes. Rewrite the process receive count field to indicate the * number of bytes actually transferred. */ inline uint32_t CopyOut(uint32_t count, void *where); bool CanCommit() { extern bool PteZapped; return PteZapped ? false : true; } inline bool IsActive() { return (key != 0); } bool IsInvocationKey(const Key *); void RetryInvocation(); void MaybeDecommit() { if (CanCommit() == false) RetryInvocation(); } void Commit();#ifndef NDEBUG bool IsCorrupted();#endif Invocation(); void Cleanup();#if 0 ~Invocation();#endif inline void SetExitKey(uint32_t ndx, Key& k) {#ifndef NDEBUG assert(InvocationCommitted);#endif if (exit.pKey[ndx]) exit.pKey[ndx]->NH_Set(k);#if 0 /* This will compile into |= of constant after inlining: */ flags |= (1u << ndx);#endif }#if defined(OPTION_KERN_TIMING_STATS) static uint64_t KeyHandlerCycles[PRIMARY_KEY_TYPES][3]; static uint64_t KeyHandlerCounts[PRIMARY_KEY_TYPES][3]; static void ZeroStats();#endif static void BootInit();};inline uint32_tInvocation::CopyOut(uint32_t len, void *data){ assert(InvocationCommitted); if (validLen < len) len = validLen; exit.len = len; if (exit.len) bcopy(data, exit.data, exit.len); return exit.len;}inline uint32_tInvocation::CopyIn(uint32_t len, void *data){ assert(InvocationCommitted); if (entry.len < len) len = entry.len; if (entry.len) bcopy(entry.data, data, len); return len;}extern Invocation inv;extern bool PteZapped;typedef void (*KeyHandler)(Invocation&);extern void FaultGate(Invocation&);/* Commit point appears in each invocation where the invocation should * now be able to proceed without impediment. At some point in the * near future I shall NDEBUG this so as to check the invariant in the * debug kernel. */#define COMMIT_POINT() \ do { \ extern Invocation inv; \ inv.Commit(); \ } while (0) #endif /* __INVOKE_HXX__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -