⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keystruct.hxx

📁 C++ 编写的EROS RTOS
💻 HXX
字号:
#ifndef __KEYTYPE_HXX__#define __KEYTYPE_HXX__/* * Copyright (C) 1998, 1999, 2001, 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. */#include <disk/ErosTypes.h>#include <disk/KeyRing.hxx>#include <eros/StdKeyType.h>#include <eros/Key.h>/*  * KeyType - the major key types supported in EROS. Keys also have a subtype * For example, the Process Tool is KtMisc, KsProcTool. *  */#define PRIMARY_KEY_TYPES 32#define PRIMARY_KEY_TYPE_BITS 5/* If these numbers change, the dispatch table in kerninc/Invoke.cxx * must be changed as well.  Key preparation is a very frequent * operation in the kernel, so these numbers are ordered in such a way * as to take advantage of a representation pun.  Key types having a * prepared form appear starting at zero.  In the actual key data * structure, the first byte of the key is layed out as: *  *   (bit 7)   hazard[2] :: prepared :: keytype[5]   (bit 0) *  * Both the hazard field and the prepared field are 0 on an unprepared * key.  This allows a combined test on the byte value to determine * which keys need to be prepared and which keys need to be * validated.  If the byte value is <= LAST_OBJECT_KEYTYPE, then the * key is NOT prepared and needs to be.  If the key is prepared, it * needs to be validated.  */#define LAST_GATE_KEYTYPE KT_Resume#define LAST_OBJECT_KEYTYPE KT_Page#define FIRST_MISC_KEYTYPE KT_KeyBits#define LAST_KEYTYPE KT_MISC+1typedef unsigned KeyType;/* Subtypes of resume key: */#define KsitResume     0	/* normal resume key */#define KsitFault      1	/* fault key -- cannot convey message */struct Prio {  enum Priority {    Inactive = -2,    KernIdle = -1,    UserIdle = 0,    Normal = 8,    High = 15  };} ;#ifndef KT_Wrapperstruct BLSS {  enum {    bit32 = 7,    bit28 = 6,    bit24 = 5,    bit20 = 4,    bit16 = 3,    bit12 = 2,    RedSeg = 1,  };};#endif/* The ObjectHeader pointer declaration is unused in the on-disk * key format, but including it here is harmless and simplifies * the declarations in Key.hxx. */class ObjectTable;#if 0/************************************************************* * * NEW KEY TYPE BYTE ORGANIZATION (STILL EXPERIMENTAL): * *     7 6         2  1   0 *    +-+-----------+---+---+ *    |P|   type    |RHz|Whz| *    +-+-----------+---+---+ * * P == 1 ==> prepared in this design, only object keys are * prepared. * * RATIONALE: * * 1. Key type comparison requires a mask operation in most *    cases anyway, but since the comparison is to a constant *    the shift operation should be resolvable at compile time. * * 2. Key types requiring preparation (object types) can be *    tested for with a single less-than operation. * * 3. Key types requiring pin can be tested for with a simple *    bit test. * * This rearrangement is in fact a precursor to the pin logic * change. * * One problem with this rearrangement is that it destroys the * bit pun in the keyring.  That doesn't appear to be critical, * though. *************************************************************/#define KHAZARD_WRITE     0x1u#define KHAZARD_READ      0x2u#define PREPARED_KT_BIT    __U(0x80)#define KHAZARD_BITS       __U(0x3)#define KEYTYPE_BITS       __U(0x7c)		#define KEYTYPE_NEEDS_PREPARE(x) (x < ((LAST_OBJECT_KEYTYPE+1)))  /* #define PREPARABLE_TYPE(x) ( ((x) & KEYTYPE_BITS) <= LAST_PREPARED_KEYTYPE ) */#define UNPREPARED_KT(x) ((uint8_t)(x) & ~PREPARED_KT_BIT)#define PREPARED_KT(x)   ((uint8_t)(x) | PREPARED_KT_BIT)/* #define PREPPED_TYPE(ty)  ((ty <= LAST_PREPARED_KEYTYPE) ? (ty | 0x2u) : ty) */#else#define KFL_PREPARED       __U(0x80)#define KFL_RHAZARD        __U(0x40)#define KFL_WHAZARD        __U(0x20)#define KFL_HAZARD_BITS    __U(0x60)#define KFL_ALL_FLAG_BITS  __U(0xe0)#if 0#define PREPARED_KT_BIT    __U(0x80)#define KEYTYPE_BITS       __U(0x7f)#define KEYTYPE_IS_PREPPED(x)    (x >= (LAST_OBJECT_KEYTYPE+1))#define UNPREPARED_KT(x) ((uint8_t)(x) & ~PREPARED_KT_BIT)#define PREPARED_KT(x)   ((uint8_t)(x) | PREPARED_KT_BIT)#endif#endifstruct KeyBits {#ifdef BITFIELD_PACK_LOW  uint8_t keyType;  uint8_t keyFlags;  uint16_t keyData;#else#error "verify bitfield layout" #endif  /* ACCESSORS AND MUTATORS RELATING TO SEGMODE KEYS: */  uint32_t GetBlss() const  {    return keyData & SEGMODE_BLSS_MASK;  }  void SetBlss(uint32_t blss)  {    keyData = (keyData & ~SEGMODE_BLSS_MASK) | blss;  }    bool IsHazard() const  {    return (keyFlags & KFL_HAZARD_BITS);  }    void UnHazard()  {     keyFlags &= ~KFL_HAZARD_BITS;  }  void SetPrepared()  {    keyFlags |= KFL_PREPARED;  }    void SetUnprepared()  {    keyFlags &= ~KFL_PREPARED;  }    void SetRdHazard()  {     keyFlags |= KFL_RHAZARD;  }    void SetWrHazard()  {     keyFlags |= KFL_WHAZARD;  }    void SetRwHazard()  {     keyFlags |= KFL_RHAZARD|KFL_WHAZARD;  }  bool IsRdHazard()  {    return (keyFlags & KFL_RHAZARD);  }    bool IsWrHazard()  {    return (keyFlags & KFL_WHAZARD);  }    KeyType GetType() const  {    return (KeyType) keyType;  }    void InitType(uint8_t t)  {    keyType = (KeyType)t; /* not hazard, not prepared */    keyFlags = 0;    keyData = 0;  }    void SetType(KeyType kt)  {    keyType = kt;  }    bool IsType(uint8_t t) const  {    return (GetType() == t);  }  bool IsNoCall() const  {    return (keyData & (SEGMODE_NC|SEGMODE_WEAK)) ? true : false;  }    void SetNoCall()  {    keyData |= SEGMODE_NC;  }    bool IsReadOnly() const  {    return (keyData & SEGMODE_RO) ? true : false;  }    bool IsWeak() const  {    return (keyData & SEGMODE_WEAK) ? true : false;  }    void SetWeak()  {    keyData |= SEGMODE_WEAK;  }    bool IsPrepared() const    {      if (keyFlags & KFL_PREPARED)	return true;      return false;    }  bool IsUnprepared() const    {      if ((keyFlags & KFL_PREPARED) == 0)	return true;      return false;    }  bool IsPreparedResumeKey() const  {    /* Resume keys are never hazarded... */    return (IsType(KT_Resume) && IsPrepared()) ? true : false;  }    void SetReadOnly()  {    keyData |= SEGMODE_RO;  }  #ifndef KT_Wrapper  bool IsRedSegmentKey() const  {    return ((keyData & SEGMODE_BLSS_MASK) == BLSS::RedSeg) ? true : false;  }#endif    bool IsGateKey() const  {    return (GetType() <= LAST_GATE_KEYTYPE) ? true : false;  }    bool IsObjectKey() const  {    return (GetType() <= LAST_OBJECT_KEYTYPE) ? true : false;  }  bool NeedsPrepare() const    {      return IsUnprepared();    }    bool IsPreparedObjectKey() const    {      return (IsObjectKey() && IsPrepared()) ? true : false;    }        bool NeedsPin() const    {      return (IsObjectKey() && !IsGateKey()) ? true : false;    }    bool IsMiscKey() const  {    return (GetType() >= FIRST_MISC_KEYTYPE) ? true : false;  }  bool IsNodeKeyType() const;  bool IsSegKeyType() const  {    return (IsType(KT_Node) ||#ifdef KT_Wrapper	    IsType(KT_Wrapper) ||#endif	    IsType(KT_Segment));  }  bool IsDataPageType() const  {    return (IsType(KT_Page) || IsType(KT_TimePage));  }  bool IsSegModeType() const  {    return (IsSegKeyType() || IsDataPageType());  }  /* EVERYTHING ABOVE HERE IS GENERIC TO ALL KEYS.  Structures below   * this point should describe the layout of a particular key type   * and should occupy exactly three words.   */    union {    struct {      ObCount count;      OID     oid;    } unprep;    /* Changes to this substructure must be coordinated with     * KeyRing.hxx!     */    struct {      KeyRing *next;      KeyRing *prev;      struct ObjectHeader *pObj;    } ok;    struct {      KeyRing *next;      KeyRing *prev;      struct Process *pContext;    } gk;    struct {			/* NUMBER KEYS */      uint32_t value[3];    } nk;    /* Priority keys use the keyData field, but no other fields. */        /* Miscellaneous Keys have no substructure, but use the 'keyData'     * field.     */    /* Device Keys (currently) have no substructure, but use the     * 'keyData' field.      */    /* It is currently true that oidLo and oidHi in range keys and     * object keys overlap, but not important that they do so.     */    struct {			/* RANGE KEYS */      uint32_t    count;      OID     oid;    } rk;              struct {			/* DEVICE KEYS */      uint16_t devClass;      uint16_t devNdx;      uint32_t     devUnit;    } dk;    struct {			/* QUEUE MISC KEY */      uint32_t releaseCount;      uint32_t value[2];      /* This is a horrible representation pun, user here solely to       * avoid the need to publish the link structure outside the kernel       */      class ThreadPile& AsThreadPile()      {	return * ((ThreadPile *) &value[0]);      }    } semaMiscKey;  } ;  /* IsVoidKey does not check for a rescinded key, only that the     current representation is void. */  bool IsVoidKey() const  {    return IsType(KT_Void);  }#ifndef KT_Wrapper#ifdef NEW_SEGMENT_LOGIC  bool IsValidFormatKey() const  {    if ( ( IsType(KT_Number)) &&	 ( REDSEG_GET_BLSS(nk) > EROS_PAGE_BLSS ) && 	 ( REDSEG_GET_INITIAL_SLOTS(nk) <= REDSEG_GET_RESERVED_SLOTS(nk) ) &&	 ( REDSEG_GET_INITIAL_SLOTS(nk) < EROS_NODE_SLOT_MASK ) &&	 ( REDSEG_GET_RESERVED_SLOTS(nk) <= EROS_NODE_SLOT_MASK ) )      return true;    return false;  }#else  bool IsValidFormatKey() const  {    if ( ( IsType(KT_Number)) &&	 ( REDSEG_GET_BLSS(nk) > EROS_PAGE_BLSS ) && 	 ( (nk.value[0] & 0xc0) == 0 ) &&	 ( REDSEG_GET_INITIAL_SLOTS(nk) < EROS_NODE_SLOT_MASK ) &&	 ( REDSEG_GET_RESERVED_SLOTS(nk) <= EROS_NODE_SLOT_MASK ) )      return true;    return false;  }#endif#endif  #ifdef __KERNEL__  inline void KeyBits::IKS_Unchain();#endif    void KS_SetNumberKey(uint32_t hi, uint32_t mid, uint32_t lo);  inline void KS_VoidInitKey();  void KS_VoidKey();  void KS_RescindKey()  {    KS_VoidKey();  }    void KS_Set(KeyBits& kb);#ifdef __KERNEL__  inline void IKS_VoidKey();  inline void IKS_Set(KeyBits& kb);#endif} ;#ifdef __KERNEL__inline voidKeyBits::IKS_Unchain(){  if ( IsPreparedObjectKey() ) {    ok.next->prev = ok.prev;    ok.prev->next = ok.next;  }}#endifinline voidKeyBits::KS_VoidInitKey(){  /* Overwrite with void without first checking anything at all! */  InitType(KT_Void);    nk.value[2] = 0;  nk.value[1] = 0;  nk.value[0] = 0;}#ifdef __KERNEL__inline voidKeyBits::IKS_VoidKey(){#ifdef __KERNEL__  IKS_Unchain();#endif  KS_VoidInitKey();}inline voidKeyBits::IKS_Set(KeyBits& kb){  /* Skip copy if src == dest (surprisingly often!) */  if (&kb == (KeyBits*) this)    return;    #ifdef __KERNEL__  IKS_Unchain();#endif  keyType = kb.keyType;  keyFlags = kb.keyFlags & ~KFL_HAZARD_BITS;  keyData = kb.keyData;  nk.value[0] = kb.nk.value[0];  nk.value[1] = kb.nk.value[1];  nk.value[2] = kb.nk.value[2];  /* Update the linkages if destination is now prepared: */  if ( IsPreparedObjectKey() ) {    ok.prev->next = (KeyRing*) this;    ok.next = (KeyRing*) &kb;    kb.ok.prev = (KeyRing*) this;  }}#endif#endif /* __KEYTYPE_HXX__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -