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

📄 linedisc.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * Copyright (C) 2001, The EROS Group. * * 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 <eros/target.h>#include <eros/Invoke.h>#include <eros/ReturnerKey.h>#include <eros/ProcessKey.h>#include <eros/NodeKey.h>#include <eros/SleepKey.h>#include <eros/Key.h>#include <eros/StdKeyType.h>#include <domain/Runtime.h>#include "constituents.h"#include "linedisc.h"#include "cmpxchg.h"#include <domain/SpaceBankKey.h>#include <domain/ConstructorKey.h>#include <domain/ProtoSpace.h>#include <domain/domdbg.h>#define KR_DOMCRE    3#define KR_RETURNER  6#define KR_OSTREAM   7  /* DEBUGGING */#define KR_BUDDOM    8  /* for shoving the return key into */#define KR_CHRSRC    9#define KR_SCRATCH  10#define KR_SCRATCH2 11#define KR_ARG0     28  /* at startup, holds charsrc key */#define KR_ARG1     29#define KR_ARG2     30#define KR_RESUME   31 /* DON'T USE IT FOR ANYTHING ELSE! */const uint32_t defInputFlags = LD_In_DoInpProc | LD_In_Echo;/*                           (LD_In_DoInpProc			    | LD_In_LineMode			    | LD_In_Echo			    | LD_In_EchoCtrl			    | LD_In_VisErase			    | LD_In_VisKill			    | LD_In_SwapCRNL			   ); */const uint32_t defOutputFlags = (LD_Out_DoOutpProc			     | LD_Out_NLtoCRNL			     | LD_Out_CRtoNL			    );/* make sure this matches the positions in LineDiscKey.h */const uint16_t defCtrlChars[LD_Num_CC] = {  LD_CC_EraseDef,  LD_CC_AltEraseDef,  LD_CC_EraseWordDef,  LD_CC_KillLineDef,  LD_CC_ReprintDef,  LD_CC_QuoteDef,  LD_CC_SFStopDef,  LD_CC_SFStartDef};/* this is the under-routine for YIELD, defined in util.h */void __yield(void)  /* SMASHES KR_SCRATCH2 */{  node_copy(KR_CONSTIT,KC_SLEEP,KR_SCRATCH2);  sl_sleep(KR_SCRATCH2,0); /* sleep for 0 ms -- yields the processor */}void init_shared(void){  register uint32_t idx;  assert(sizeof(struct shared) <= EROS_PAGE_SIZE);    init_write_buff_ctl(&SHARED.wrt_buff.ctl);  SHARED.readerWants = UINT32_MAX;  SHARED.inpProcFlags = defInputFlags;  SHARED.outpProcFlags = defOutputFlags;  for (idx = 0; idx < LD_Num_CC; idx++) {    SHARED.control_chars[idx] = defCtrlChars[idx];  }  CLEAR_MASK(SHARED.char_mask);  SHARED.linedisc_status = LD_Stat_Ready;}uint32_t start_buddy(uint32_t krSharedPage){  Message msg;  register uint32_t retval;    DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDisc: Calling buddy constructor\n");  /* make sure we won't smash the shared page */  assert(krSharedPage != KR_BUDDOM);    node_copy(KR_CONSTIT, KC_BUDDYC, KR_BUDDOM);  retval = constructor_request(KR_BUDDOM,			       KR_BANK,			       KR_SCHED,			       KR_CHRSRC, /* pass over the char source */			       KR_BUDDOM);  assert("Constructing buddy" && retval == RC_OK);  /* KR_SCRATCH now holds a START key to our buddy.     We CALL him back to trade the shared page for his domain key. */  DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDisc: Calling buddy with shared page, expecting a domkey\n");  msg.snd_key0 = krSharedPage;  msg.snd_key1 = KR_VOID;  msg.snd_key2 = KR_VOID;  msg.snd_key3 = KR_VOID;  msg.snd_w1 = 0u;  msg.snd_w2 = 0u;  msg.snd_w3 = 0u;  msg.snd_len = 0u; /* no data */  msg.rcv_key0 = KR_BUDDOM; /* he'll return a domain key */  msg.rcv_key1 = KR_VOID;  msg.rcv_key2 = KR_VOID;  msg.rcv_key3 = KR_VOID;  msg.rcv_len = 0u; /* no data */    msg.snd_invKey = KR_BUDDOM;  msg.snd_code = RC_OK; /* We're doing fine */  retval = CALL(&msg);  assert("starting buddy" && retval == RC_OK);  DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDisc: Buddy CALLED me -- success!\n");    return RC_OK;}uint32_t wakeup_buddy(enum LD_WakeupReasons reasons){  charsrc_post_event(KR_CHRSRC,		     reasons | CharSrc_UserEvent(0));  return RC_OK;}void destroy_self(uint32_t retCode, bool buddyThere){  register uint32_t retval;  uint32_t keyType;    if (buddyThere) {    /* tell my pal to jump off the bridge first */    DEBUG(destroy)      kprintf(KR_OSTREAM,	      "LineDisc: Telling my buddy to suicide\n");        SHARED.linedisc_status = LD_Stat_TearDown;    wakeup_buddy(LD_Wakeup_TearDown);     /* wait for him to acknowledge */    while (SHARED.linedisc_status == LD_Stat_TearDown)      YIELD();     /* he's gone now */  }    /* get my address space into scratch */  retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH);  assert(retval == RC_OK);  DEBUG(destroy)    kprintf(KR_OSTREAM,	    "LineDisc: destroying databuff page\n");  /* get data page into scratch2 */  retval = node_copy(KR_SCRATCH, DATABUFF_SLOT, KR_SCRATCH2);  assert(retval == RC_OK);  key_kt(KR_SCRATCH2, &keyType, 0);  if (keyType == AKT_Page) {    /* sell the page back to the space bank */    retval = spcbank_return_data_page(KR_BANK, KR_SCRATCH2);    if (retval != RC_OK) {      kdprintf(KR_OSTREAM,"Returning databuff page to spacebank failed!\n");    }  } else {    DEBUG(destroy)      kprintf(KR_OSTREAM,	      "LineDisc: Databuff not page\n");  }    DEBUG(destroy)    kprintf(KR_OSTREAM,	    "LineDisc: destroying shared page\n");  /* get shared page into scratch2 */  retval = node_copy(KR_SCRATCH, SHARED_SLOT, KR_SCRATCH2);  assert(retval == RC_OK);  key_kt(KR_SCRATCH2, &keyType, 0);  if (keyType == AKT_Page) {    /* sell the page back to the space bank */    retval = spcbank_return_data_page(KR_BANK, KR_SCRATCH2);    if (retval != RC_OK) {      kdprintf(KR_OSTREAM,"Returning shared page to spacebank failed!\n");    }  } else {    DEBUG(destroy)      kprintf(KR_OSTREAM,	      "LineDisc: Shared not page\n");  }    DEBUG(destroy)    kdprintf(KR_OSTREAM,	    "LineDisc: Suiciding\n");    /* all of my stuff is gone, my buddy's gone -- better kill myself */  node_copy(KR_CONSTIT,KC_PROTO,KR_SCRATCH);  /* FIXME: Due to Intel's broken architecture, I can't return anything but     RC_OK to the caller.  If retCode != RC_OK, what should I do? */    protospace_destroy(KR_RETURNER,		     KR_SCRATCH,		     KR_SELF,		     KR_DOMCRE,		     KR_BANK,		     1); /* small space */  /* NOTREACHED */}#ifndef NDEBUGint __assert(const char *expr, const char *file, int line){  kdprintf(KR_OSTREAM, "%s:%d: Assertion failed: '%s'\n",	   file, line, expr);  return 0;}#endifvoidinitialize_linedisc(void){  register uint32_t retval;  /* copy stuff out of constit */  node_copy(KR_CONSTIT, KC_RETURNER, KR_RETURNER);  node_copy(KR_CONSTIT, KC_OSTREAM,  KR_OSTREAM);  /* copy the character source key into its key reg. (I could use     KR_SELF, but the Returner key is much cooler) */  copy_key_reg(KR_RETURNER, KR_ARG0, KR_CHRSRC);  DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDisc: Returner worked -- buying shared page\n");    retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH);  assert("process_copy(ProcAddrSpace)" && retval == RC_OK);  /* buy a new page and insert it into address space for the databuff*/  retval = spcbank_buy_data_pages(KR_BANK, 1, KR_SCRATCH2, 0, 0);  assert("spcbank_buy_data_pages(1)" && retval == RC_OK);  /* swap the new node in, putting the old contents over the address node */  retval = node_swap(KR_SCRATCH, DATABUFF_SLOT, KR_SCRATCH2, KR_SCRATCH);  assert("node_swap(AddrSpc,DATABUFF_SLOT,newPage)" && retval == RC_OK);  DEBUG(init) {    uint32_t keyType;    kprintf(KR_OSTREAM,	    "LineDisc: Databuff page installed -- checking "	    "previous occupant.\n");    key_kt(KR_SCRATCH, &keyType, 0);    if (keyType != RC_Void) {      kdprintf(KR_OSTREAM,	      "Hey! the previous occupant wasn't void!\n");    }    kprintf(KR_OSTREAM,	    "LineDisc: Checking that databuff is actually there.\n");    assert(DATABUFF[0] == 0);    DATABUFF[0] = 1;    assert(DATABUFF[0] != 0);    DATABUFF[0] = 0;    kprintf(KR_OSTREAM,	    "LineDisc: Databuff there. \n");      }    retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH);  assert("process_copy(ProcAddrSpace)" && retval == RC_OK);  /* buy the page for the shared data */  retval = spcbank_buy_data_pages(KR_BANK, 1, KR_SCRATCH2, 0, 0);  assert("spcbank_buy_data_pages(1)" && retval == RC_OK);  /* swap the new node in, putting the old contents over the address     node */  retval = node_swap(KR_SCRATCH, SHARED_SLOT, KR_SCRATCH2, KR_SCRATCH);  assert("node_swap(AddrSpc,SHARED_SLOT,newPage)" && retval == RC_OK);  DEBUG(init) {    uint32_t keyType;    kprintf(KR_OSTREAM,	    "LineDisc: Shared page installed -- checking "	    "previous occupant.\n");    key_kt(KR_SCRATCH, &keyType, 0);    if (keyType != RC_Void) {      kdprintf(KR_OSTREAM,	      "Hey! the previous occupant wasn't void!\n");    }  }  DEBUG(init)    kprintf(KR_OSTREAM,	    "Initializing shared data\n");    init_shared();  DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDisc: Successfully initialized shared page\n");  /* initialize buddy */  retval = start_buddy(KR_SCRATCH2);  assert("starting buddy" && retval == RC_OK);    /* now get a start key so we can rock-and-roll */  retval = process_make_start_key(KR_SELF, 0u, KR_ARG0);  assert("Making start key" && retval == RC_OK);    /* done intializing */  return;}

⌨️ 快捷键说明

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