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

📄 directory.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
   of. It walks through the entries in the page, bringing all of the   in-use entries to the front of the page. Leave an entry with   d_inuse == false at the end containing all the free space. */struct direct *coalesce_page(struct direct *dp){  uint32_t offset = 0;  uint32_t bytes = 0;  uint32_t free = 0;    uint8_t *page_start = (uint8_t *)dp;  #ifndef NDEBUG  if ((uint32_t) dp & EROS_PAGE_MASK)    DEBUG(link) kdprintf(KR_OSTREAM, "coalesce(): start dp 0x%08x not at page boundary\n", dp);#endif  while (bytes < EROS_PAGE_SIZE) {    if (dp->d_inuse == false) {      free += dp->d_inuse;    }    else {      uint32_t truelen = DIRSIZ(dp);      uint32_t dp_free = dp->d_reclen - DIRSIZ(dp);            if (offset != bytes) {	bcopy(dp, page_start + offset, truelen);	offset += truelen;      }      ((struct direct *) (page_start + offset))->d_reclen = truelen;            free += dp_free;    }          bytes += dp->d_reclen;  }  if (free < 12)    DEBUG(link) kdprintf(KR_OSTREAM, "Insufficient free space in page\n");    /* All active entries have now been moved to the front of the page,     and FREE now contains the number of free bytes in this page.     Create a new, unallocated struct direct at the end of the page     which contains all the free space. */  {    struct direct *tail;    tail = (struct direct *) (page_start + free);    tail->d_reclen = free;    tail->d_inuse = false;    tail->d_namlen = 0;    tail->d_name[0] = 0;    tail->d_name[1] = 0;    tail->d_name[2] = 0;    tail->d_name[3] = 0;    return tail;  }}struct direct *find_space(uint32_t len, state_t *state){  struct direct *dp = first_entry;  DEBUG(link) kdprintf(KR_OSTREAM, "find_space(%d)\n", len);  while (dp != state->dir_top) {    struct direct * page_start_dp = dp;    uint32_t bytes = 0;    uint32_t free_bytes = 0;    while (bytes < EROS_PAGE_SIZE) {      uint32_t free = dp->d_reclen - DIRSIZ(dp);      DEBUG(link)	kdprintf(KR_OSTREAM, "Considering dp=0x%08x sz %d reclen %d inuse? %c\n",		 dp, DIRSIZ(dp), dp->d_reclen, dp->d_inuse ? 'y' : 'n');          if (dp->d_inuse == false)	free += DIRSIZ(dp);            if (dp->d_inuse == false && free >= len)	return dp;      if (dp->d_inuse && free >= len) {	/* Fashion a new entry here: */	dp->d_reclen = DIRSIZ(dp);	dp = NEXTDIR(dp);	dp->d_reclen = free;	dp->d_inuse = false;	dp->d_namlen = 0;	dp->d_name[0] = 0;	dp->d_name[1] = 0;	dp->d_name[2] = 0;	dp->d_name[3] = 0;	return dp;      }	      free_bytes += free;      bytes += dp->d_reclen;      dp = NEXTDIR(dp);    }    if (len <= free_bytes) {      dp = coalesce_page(page_start_dp);      return dp;    }  }  return 0;}uint32_tlink(char *name, uint32_t kr, state_t * state){  uint32_t len;  struct direct *dp = find(name, state);  if (dp)    return RC_Directory_Exists;  /* This is NOT the standard roundup.  if the name is exactly a     multiple of 4 bytes, we WANT the trailing 4 bytes to get added: */  len = strlen(name);  len += 4;			/* round up to NEXT 4 byte multiple */  len &= ~3u;  len += 8;			/* overhead per dirent */    /* Run through the directory looking for a page that has sufficient     space.  The dp->d_namlen test works when we overrun the current     directory because the VCS will demand allocate a zero page for     us. */  dp = first_entry;  if ( (dp = find_space(len, state)) == 0 ) {    dp = state->dir_top;    bcopy(&blank_page, state->dir_top, sizeof(blank_page));    state->dir_top =      (struct direct *) ((uint8_t *)state->dir_top + EROS_PAGE_SIZE);  }  DEBUG(link) kdprintf(KR_OSTREAM, "Inserting dirent at dp=0x%08x\n", dp);  if ( insert_dirent(dp, name, kr, state) == false )    return RC_Directory_NoSpace;    return RC_OK;}intProcessRequest(Message *msg, state_t *state){  switch (msg->rcv_code) {          case OC_Directory_Lookup:    DEBUG(op) kprintf(KR_OSTREAM, "DIR: lookup(\"%s\")\n", state->name);    msg->snd_code = lookup (state->name, KR_ARG0, state);    msg->snd_key0 = KR_ARG0;    break;  case OC_Directory_Link:    DEBUG(op) kprintf(KR_OSTREAM, "DIR: link(\"%s\", <key>)\n", state->name);    msg->snd_code = link (state->name, msg->rcv_key0, state);    break;  case OC_Directory_Unlink:    DEBUG(op) kprintf(KR_OSTREAM, "DIR: unlink(\"%s\") => <key>\n", state->name);    msg->snd_code = unlink (state->name, msg->rcv_key0, state);    break;  case OC_KeyType:			/* check alleged keytype */    msg->snd_code = RC_OK;    msg->snd_w1 = AKT_Directory;    break;  default:    msg->snd_code = RC_UnknownRequest;    break;  };      return 1;}voidInitialize(state_t *state){  uint32_t result;  node_copy(KR_CONSTIT, KC_OSTREAM, KR_OSTREAM);  /* Using KR_ARG0, KR_SNODE as scratch registers */  /* Construct the ZS that will hold the actual directory data */  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: Building ZS\n");  node_copy(KR_CONSTIT, KC_ZSF, KR_SNODE);  result = constructor_request(KR_SNODE, KR_BANK, KR_SCHED, KR_VOID, KR_SNODE);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: Result is: 0x%08x\n", result);  /* Buy the new root node to hold it: */  result = spcbank_buy_nodes(KR_BANK, 1, KR_ARG0, KR_VOID, KR_VOID);  if (result != RC_OK)    DEBUG(init) kdprintf(KR_OSTREAM, "DIR: spcbank nodes exhausted\n", result);    /* make that node LSS=TOP_LSS */  node_make_node_key(KR_ARG0, EROS_ADDRESS_BLSS, KR_ARG0);  /* plug in newly allocated ZSF */  DEBUG(init) kdprintf(KR_OSTREAM, 		       "DIR: plugging zsf into new spc root\n", result);  node_swap(KR_ARG0, 8, KR_SNODE, KR_VOID);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: fetch my own space\n", result);  process_copy(KR_SELF, ProcAddrSpace, KR_SNODE);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: plug self spc into new spc root\n", result);  node_swap(KR_ARG0, 0, KR_SNODE, KR_VOID);    DEBUG(init) kdprintf(KR_OSTREAM, "DIR: before lobotomy\n", result);  process_swap(KR_SELF, ProcAddrSpace, KR_ARG0, KR_VOID);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: post lobotomy\n", result);  node_copy(KR_CONSTIT, KC_SNODEC, KR_SNODE);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: buying supernode\n");  result = constructor_request(KR_SNODE, KR_BANK, KR_SCHED, KR_VOID, KR_SNODE);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: Got it. Result 0x%08x\n", result);  /* insert key for ".." entry: */  supernode_swap(KR_SNODE, 1, KR_ARG0, KR_VOID);  /* make start key to us: */  process_make_start_key(KR_SELF, 0, KR_ARG0);    /* insert key for "." entry: */  supernode_swap(KR_SNODE, 0, KR_ARG0, KR_VOID);  state->ndirent = 2;  state->dir_top = (struct direct *) ((uint8_t *)first_entry+EROS_PAGE_SIZE);  bzero(state->freeMap, EROS_PAGE_SIZE * N_FREEMAP_PAGE);  bcopy(&template, first_entry, sizeof(template));	  DEBUG(init) kdprintf(KR_OSTREAM, "Allocate Initial slots...\n");  (void) alloc_dirent(state);  (void) alloc_dirent(state);  DEBUG(init) kdprintf(KR_OSTREAM, "Initial slots allocated\n");}intmain(){  state_t state;  Message msg;  Initialize(&state);  process_make_start_key(KR_SELF, 0, KR_ARG0);  DEBUG(init) kdprintf(KR_OSTREAM, "DIR: Got start key. Ready to rock and roll\n");  // kdprintf(KR_OSTREAM, "DIR: Got start key. Ready to rock and roll\n");  msg.snd_invKey = KR_RETURN;  msg.snd_key0 = KR_ARG0;  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_ARG0;  msg.rcv_key1 = KR_VOID;  msg.rcv_key2 = KR_VOID;  msg.rcv_key3 = KR_RETURN;  msg.rcv_data = state.name;  msg.rcv_len = MAXNAMLEN;  msg.rcv_code = 0;  msg.rcv_w1 = 0;  msg.rcv_w2 = 0;  msg.rcv_w3 = 0;  do {    msg.rcv_len = MAXNAMLEN;    RETURN(&msg);    ((uint8_t *) msg.rcv_data)[msg.rcv_len] = 0;    msg.snd_key0 = KR_VOID;		 /* until otherwise proven */    kdprintf(KR_OSTREAM, "Before ProcessRequest(): freemap = 0x%08x\n",	     state.freeMap);  } while ( ProcessRequest(&msg, &state) );  return 0;}/* * Copyright (c) 1982, 1986, 1989, 1993 *	The Regents of the University of California.  All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)dir.h	8.4 (Berkeley) 8/10/94 */

⌨️ 快捷键说明

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