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

📄 spacebank_test.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * Copyright (C) 2001, The EROS Group, LLC. * * 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/KeyBitsKey.h>#include <eros/NodeKey.h>#include <eros/PageKey.h>#include <eros/StdKeyType.h>#include <eros/SleepKey.h>#include <domain/SpaceBankKey.h>#include <domain/domdbg.h>#define NODE_ALLOC_CHECK#ifdef GNU#define INLINE inline#else#define INLINE#endif/* define the following if you want the test to stop after each stage *//* #define STPRINTF kdprintf */#define VERBOSE#ifndef STPRINTF#define STPRINTF kprintf#endif#define KR_VOID       0#define KR_SPACEBANK  1#define KR_CONSOLEKEY 2#define KR_SLEEPKEY   3#define KR_KEYBITS    4#define KR_PARBANK    5#define KR_SUBBANK    6#define KR_TMP0       7#define KR_TMP1       8#define KR_TMP2       9#define KR_TMP3      10/* key stuff */#define KR_KEYBASE   11#define KR_KEY(x)    (KR_KEYBASE+(x))#define NUM_KEYS     (EROS_PROCESS_KEYREGS-KR_KEYBASE)#define SLEEP_TME  0 /* (100/7) *//* define DIRTY_OBJECTS if you want all allocated objects dirtied */#define DIRTY_OBJECTS 1#define NUM_LEVELS (3u)/* nnumber of levels in the node tree */#define NUM_ITEMS (1u << (4*NUM_LEVELS))/* == 16 ^ NUM_LEVELS *//**Handle the stack stuff**/const uint32_t __rt_stack_pages = 0;const uint32_t __rt_stack_pointer = 0x10000;/* key_array_info holds information about the tree of nodes used   to store keys.    For each level i, KR_KEY(i) refers to the current node at level i,   and alloced[i] is the number of slots used in the node at level i+1   (except that if alloced[i+1]==0, i is the top level).   The leaf nodes are at level 0. */struct key_array_info{  uint32_t alloced[NUM_KEYS];    uint32_t curKeys;  /* number of keys in 0th-level node */};uint32_tinit_key_array(struct key_array_info *info,	       const char *name,	       uint32_t krBank){  int idx;  for (idx = 0; idx < NUM_KEYS; idx++)     info->alloced[idx] = 0;    /* allocate the starting node */  if (spcbank_buy_nodes(krBank,1,KR_KEY(0),KR_VOID,KR_VOID)       != RC_OK) {    return 1;  }  info->alloced[0]++;  /*mark it as allocated */  info->curKeys = 0;  return 0;}uint32_tinsert_key(struct key_array_info *info, 	   const char *name,	   uint32_t krBank,	   uint32_t fromSlot){  if (info->curKeys >= EROS_NODE_SIZE) {    /* We need to grow the tree. */    uint32_t maxEff;    uint32_t cur;    uint32_t didAllocBase = 0;    /* find the first non-full level */    for (maxEff = 0;          maxEff < NUM_KEYS	  && info->alloced[maxEff] >= EROS_NODE_SIZE;           maxEff++)      ; /* NOTHING */        if (maxEff >= NUM_KEYS	|| info->alloced[maxEff] == 0 ) {      /* SHOULDN'T HAPPEN */      kdprintf(KR_CONSOLEKEY,	       "%s: Impossible condition in insert_key %d %d\n",	       name, maxEff, info->alloced[maxEff]);      return 1;    }        if (maxEff == NUM_KEYS - 1) {      kdprintf(KR_CONSOLEKEY,               "%s: Hey!  We're going to use more than %d levels!\n"	       "     That's pow(%d,%d) keys!\n",	       name,NUM_KEYS,EROS_NODE_SIZE,NUM_KEYS);      return 1; /* FAILED */    }    if (info->alloced[maxEff+1] == 0) {      /* We need to increase the depth of the tree. */      /* Buy the node for level maxEff+1 */      if (spcbank_buy_nodes(krBank,1,KR_KEY(maxEff+1),KR_VOID,KR_VOID) 	  != RC_OK) {	kprintf(KR_CONSOLEKEY,		"%s: Hey! Failed to allocate new head node (%d levels).\n",		name,maxEff);	return 1; /* FAILED */      }      /* mark level maxEff+1 as having a single node */      info->alloced[maxEff+1]++;      /* mark this true so we can remove it later. */      didAllocBase = 1;      /* copy in the maxEff level key as the first key in the new node */      node_swap(KR_KEY(maxEff+1),0,KR_KEY(maxEff),KR_VOID);      #ifdef VERBOSE      kprintf(KR_CONSOLEKEY,"%d", maxEff+1);#endif    }    /* Now KR_KEY(maxEff) isn't the only key to its node. */    /* loop, creating a new node at each level */    cur = maxEff;    do {      if (spcbank_buy_nodes(krBank,1,KR_KEY(cur),KR_VOID,KR_VOID)	  != RC_OK) {	kprintf(KR_CONSOLEKEY,"\n%s: Failed to buy node.\n",name);	/* clean up */	while (cur < maxEff) {	  cur++;	  if (spcbank_return_node(krBank,KR_KEY(cur)) != RC_OK) {	    kdprintf(KR_CONSOLEKEY,"%s: Failed to return node.\n",name);	  }	  info->alloced[cur]--;	  node_copy(KR_KEY(cur + 1),info->alloced[cur],KR_KEY(cur));	}	if (didAllocBase) {	  if (spcbank_return_node(krBank,KR_KEY(maxEff+1)) != RC_OK) {	    kdprintf(KR_CONSOLEKEY,"%s: Failed to return node.\n",name);	  }	  	  info->alloced[maxEff+1] = 0;	}	return 1;      }      node_swap(KR_KEY(cur+1),		info->alloced[cur],		KR_KEY(cur),		KR_VOID);      info->alloced[cur]++;#ifdef VERBOSE      kprintf(KR_CONSOLEKEY,"+");#endif          } while (cur-- > 0);    /* now that we have successfully allocated everything, update the       table. */    for (cur = 0; cur < maxEff; cur++) {      info->alloced[cur] = 1; /* the higher node is empty                                  except for a pointer to this node */    }    info->curKeys = 0; /* we now have a new bottom level node */  }  /* curKeys is now guarenteed to be < EROS_NODE_SIZE -- we can insert     the new key into the curKeys slot...*/  node_swap(KR_KEY(0),	    info->curKeys++,	    fromSlot,	    KR_VOID);  return RC_OK;}uint32_tdealloc_array(struct key_array_info *info,	      const char *name,	      uint32_t (*dealloc_func)(uint32_t fromSlot, uint32_t krBank),	      uint32_t krBank,	      uint32_t tmpSlot){  /* smashes tmpSlot */  uint32_t curpos[NUM_KEYS];  uint32_t lvl;  uint32_t maxLvl;  uint32_t slotNum;  uint32_t numDeallocs;    /* clear the curpos array */  for (lvl = 0; lvl < NUM_KEYS; lvl++)    curpos[lvl] = 0;   /* find the maximum level */  maxLvl = 0;  while(1) {    if (info->alloced[maxLvl] == 1	&& (maxLvl == NUM_KEYS-1 || info->alloced[maxLvl+1] == 0))      break;    maxLvl++;    /* sanity check */    if (maxLvl >= NUM_KEYS) {      kdprintf(KR_CONSOLEKEY,"%s: dealloc_array Impossible condition\n",name);      return 1;    }  }    curpos[maxLvl] = 1;    /* grab the first items all the way down the tree */  lvl = maxLvl;  while (lvl > 0) {    lvl--;    node_swap(KR_KEY(lvl+1),0,KR_VOID,KR_KEY(lvl));  }  /* the bottom level isn't incremented until we have deallocated it   */  curpos[0] = 0;#ifdef VERBOSE  /* NO NEWLINE -- we print a dot/object deallocated */  kprintf(KR_CONSOLEKEY,"%s: Deallocating",name);#endif  numDeallocs = 0;  while (maxLvl > 0) {    /* first, deallocate the items in the key(0) slot */    for (slotNum = 0; slotNum < info->curKeys; slotNum++) {      numDeallocs++;            node_swap(KR_KEY(0),slotNum,KR_VOID,tmpSlot);      if ((*dealloc_func)(tmpSlot,krBank) != RC_OK) {	kdprintf(KR_CONSOLEKEY,		 "\n%s: Error deallocating object #%d.\n",		 name,		 numDeallocs);	return 1;      }#ifdef VERBOSE      kprintf(KR_CONSOLEKEY,".");#endif    }    if (spcbank_return_node(krBank,KR_KEY(0)) != RC_OK) {      kdprintf(KR_CONSOLEKEY,	       "\n%s: Error deallocating node!\n",name);      return 1;    }    curpos[0]++; /* we are done with this node */#ifdef VERBOSE      kprintf(KR_CONSOLEKEY,"+");#endif    for (lvl = 0;	  lvl < maxLvl - 1	  && curpos[lvl] == EROS_NODE_SIZE;  	   lvl++) {      /* this level is empty -- remove the enclosing node */      if (spcbank_return_node(krBank,KR_KEY(lvl+1)) != RC_OK) {	kdprintf(KR_CONSOLEKEY,		 "\n%s: Error deallocating node.\n",		 name);      }#ifdef VERBOSE      kprintf(KR_CONSOLEKEY,"+");#endif      curpos[lvl+1]++;      curpos[lvl] = 0;    }    if (maxLvl == lvl + 1 	   && curpos[lvl] + 1 == info->alloced[lvl]) {      /* We will be putting in the last node from the maxLvl pile.	 get the last node by hand, and deallocate the outer node. */            node_swap(KR_KEY(lvl+1),curpos[lvl],KR_VOID,KR_KEY(lvl));      if (spcbank_return_node(krBank,KR_KEY(maxLvl)) != RC_OK) {	kdprintf(KR_CONSOLEKEY,		 "\n%s: Error deallocating node.\n",		 name);      }#ifdef VERBOSE      kprintf(KR_CONSOLEKEY,"+");#endif      maxLvl--;      lvl--;    } else if (maxLvl == lvl + 1 	       && curpos[lvl] + 1 > info->alloced[lvl]) {      kdprintf(KR_CONSOLEKEY,	       "%s: Impossible condition in dealloc_tree\n",	       name);    }    /* now, we need to walk back down, getting the new nodes and       resetting the current pointers. */    do {      node_swap(KR_KEY(lvl+1),curpos[lvl],KR_VOID,KR_KEY(lvl));    } while (lvl-- > 0);  }  /* do the last one by hand */  for (slotNum = 0; slotNum < info->curKeys; slotNum++) {    numDeallocs++;    node_swap(KR_KEY(0),slotNum,KR_VOID,tmpSlot);    if ((*dealloc_func)(tmpSlot,krBank) != RC_OK) {      kdprintf(KR_CONSOLEKEY,	       "\n%s: Error deallocating object #%d.\n",	       name,	       numDeallocs);      return 1;    }#ifdef VERBOSE    kprintf(KR_CONSOLEKEY,".");#endif  }  if (spcbank_return_node(krBank,KR_KEY(0)) != RC_OK) {    kdprintf(KR_CONSOLEKEY,	     "\n%s: Error deallocating last node!\n",name);    return 1;  }#ifdef VERBOSE  kprintf(KR_CONSOLEKEY,"+");#endif  return 0;}uint32_tRunAllocTest(const char *test_name,             uint32_t (*alloc_func)(uint32_t toSlot, uint32_t sbSlot),             uint32_t (*dealloc_func)(uint32_t fromSlot, uint32_t sbSlot)){  /* this is a generic testing interface -- It basically    calls *alloc_func with a slot number repeatedly, storing the    result key away somewhere, until it returns a non-zero value, or    is unable to allocate more storage for the keys.  At this point,    it walks through the allocated objects, calling *dealloc_func for    each one.       if dealloc_func is NULL, then the allocated objects are not    SMASHES KR_TMP0 and KR_PARBANK!!!   */  struct key_array_info info;  /* holds the key array data */  uint32_t count; /* number of alloced objects */  /* first create a bank for the test */#ifdef VERBOSE  kprintf(KR_CONSOLEKEY,	  "%s: Allocating bank\n",test_name);#endif  if (spcbank_create_subbank(KR_SPACEBANK,KR_PARBANK) != RC_OK) {    kdprintf(KR_CONSOLEKEY,	     "%s: Unable to create subbank for testing.\n",	     test_name);    return 1;  }  if (init_key_array(&info,test_name,KR_PARBANK) != RC_OK) {    kdprintf(KR_CONSOLEKEY,	     "%s: Unable in init Key Array.\n",	     test_name);    return 1;  }

⌨️ 快捷键说明

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