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

📄 keyset.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
      /* We don't contain theirEntry -- copy it into my table */      *STAT.end_of_table = *theirEntry;      STAT.end_of_table++;      STAT.numUnsorted++;      /* now increment past it */      theirEntry++;      theirCount--;    } else {      /* They don't contain our entry -- increment mine */      myEntry++;      myCount--;    }  }  /* copy any remaining items from them */  while (theirCount) {    *STAT.end_of_table = *theirEntry;    STAT.end_of_table++;    STAT.numUnsorted++;        theirEntry++;    theirCount--;  }  if (STAT.numUnsorted > MAX_UNSORTED) {    /* too many unsorted -- sort them in */    require_sorted_table();  }    /* Now, return the segment to the other guy. */  ReturnSegment();  return 0;}uint32_tRemoveKeysNotInSet(uint32_t krOtherSet){  uint32_t theirCount;  uint32_t myCount = STAT.numSorted;  uint32_t result;  struct table_entry *myEntry = the_table;  struct table_entry *theirEntry = other_table;  struct table_entry *myNewEnd = the_table;  uint32_t myNewCount = 0u;    result = VerifyAndGetSegmentOfSet(krOtherSet, &theirCount);  if (result == RC_Internal_KeyToSelf)     return RC_OK; /* We already contain ourself */  else if (result == RC_KeySet_PassedSetInvalid)    return RC_KeySet_PassedSetInvalid;  else if (result != RC_OK) {    /* nice try. */    return RC_RequestError;  }  /* now we've got the other segment */  /* search through my table for items not in theirs, and remove them.     (note that both of the lists are sorted coming into this code) */    while (theirCount && myCount) {    int cmpres = compare(myEntry->w, theirEntry->w);        if (cmpres == 0) {      /* We match -- copy if necessary, then increment both */      if (myEntry != myNewEnd) {	/*this guy's position has changed -- copy him to new position*/	*myNewEnd = *myEntry;	      }      myNewEnd++;      myNewCount++;      myEntry++;      myCount--;            theirEntry++;      theirCount--;    } else if (cmpres > 0) {      /* We don't contain theirEntry -- skip it */      theirEntry++;      theirCount--;    } else {      /* They don't contain our entry -- skip it, removing it from our	 ending list. */      myEntry++;      myCount--;    }  }  STAT.end_of_table = myNewEnd;  STAT.numSorted = myNewCount;  STAT.numUnsorted = 0;  /* Now, return the segment to the other guy. */  ReturnSegment();  return 0;}uint32_tCompareSets(uint32_t krOtherSet, uint32_t compareData){  uint32_t theirCount;  uint32_t myCount = STAT.numSorted;  uint32_t result;  uint32_t emptyintersect = 1; /* ME intersect HIM == 0 */  uint32_t othermissing = 0;   /* he's missing something I have */  uint32_t memissing = 0;      /* I'm missing something he has */  uint32_t datamismatch = 0;   /* data fields mismatch -- only if				  compareData */  struct table_entry *myEntry = the_table;  struct table_entry *theirEntry = other_table;  result = VerifyAndGetSegmentOfSet(krOtherSet, &theirCount);  if (result == RC_Internal_KeyToSelf)    return RC_KeySet_SetsEqual; /* We equal ourself, thank you */  else if (result == RC_KeySet_PassedSetInvalid)    return RC_KeySet_PassedSetInvalid;  else if (result != RC_OK) {    /* nice try. */    return RC_RequestError;  }  /* now we've got the other segment */  /* walk through both (sorted) tables, comparing the current pointers in     each:     If the keys are equal, we increment both counters to get past them.     If *myEntry < *theirEntry, increment myEntry.     if *myEntry > *theirEntry, we can't contain them, so break.   */    while (theirCount && myCount) {    int cmpres;    #if 0    kdprintf(KR_OSTREAM,	     "Comparing 0x%08x %08x %08x %08x\n"	     "       to 0x%08x %08x %08x %08x\n",	     myEntry->w[0], myEntry->w[1], myEntry->w[2], myEntry->w[3],	     theirEntry->w[0], theirEntry->w[1], theirEntry->w[2],	     theirEntry->w[3]);#endif        cmpres = compare(myEntry->w, theirEntry->w);        if (cmpres == 0) {      emptyintersect = 0;      if (compareData) {	if (myEntry->w[4] != theirEntry->w[4]) {	  datamismatch = 1;	  break;	}      }      /* increment both */      myEntry++;      myCount--;            theirEntry++;      theirCount--;    } else if (cmpres > 0) {      /* Can't contain their item */      memissing = 1;      theirEntry++;      theirCount--;    } else {      /* increment mine */      othermissing = 1;      myEntry++;      myCount--;    }  }  if (!datamismatch) {    if (myCount != 0)      othermissing = 1;    if (theirCount != 0)      memissing = 1;  }  /* Now, return the segment to the other guy. */  ReturnSegment();#if 0  kdprintf(KR_OSTREAM, "Contains completes. theirCount = %d\n", theirCount);#endif    if (compareData && datamismatch)     return RC_KeySet_DataMismatch;  if (!memissing && !othermissing)    return RC_KeySet_SetsEqual;  if (emptyintersect)  /* both empty is taken care of by Equal case */    return RC_KeySet_SetsDisjoint;  if (!memissing && othermissing) /* I contain him */    return RC_KeySet_SetContainsOtherSet;  if (memissing && !othermissing) /* He contains me */    return RC_KeySet_OtherSetContainsSet;  /* none of the above */  return RC_KeySet_SetsDifferent;}uint32_tProcessRequest(Message *msg){  Bits curBits;  uint32_t kbVersion;  uint32_t rdOnly = (msg->rcv_keyInfo == ReadOnly_KeyData);  uint32_t setInvalid = 0;  GetKeyBits(KR_KEYBITS, KR_ARG0, &kbVersion, &curBits);  if (kbVersion != STAT.startKeyBitsVersion      && (STAT.numSorted || STAT.numUnsorted)) {    /* we aren't empty, and keybits version changed */    kdprintf(KR_OSTREAM, "Hey! Keybits version changed!\n");    setInvalid = 1; /* everything should check readonly first, then		       setInvalid */  }  DEBUG(cmds) {    kprintf(KR_OSTREAM,	    "KeySet: Got request 0x%08x, w1 = 0x%08x\n",	    msg->rcv_code,	    msg->rcv_w1);    kprintf(KR_OSTREAM,	    "Slot %d Keybits 0x%08x %08x %08x %08x\n",	    KR_ARG0,	    curBits.w[0],	    curBits.w[1],	    curBits.w[2],	    curBits.w[3]);  }    msg->snd_code = RC_UnknownRequest;  msg->snd_w1 = 0;  msg->snd_w2 = 0;  msg->snd_w3 = 0;  switch(msg->rcv_code) {  case OC_KeySet_AddKey:    {      struct table_entry *the_entry;      if (rdOnly) {	msg->snd_code = RC_UnknownRequest;	break;      } else if (setInvalid) {	msg->snd_code = RC_KeySet_SetInvalid;	break;      }      the_entry = FIND(the_table, curBits.w,STAT);      DEBUG(add) kprintf(KR_OSTREAM,			 "AddKey:  FIND returned %08x\n",			 the_entry);            if (the_entry != NULL) {	/* already there, just update the entry. */	msg->snd_w1 = the_entry->w[4];	the_entry->w[4] = msg->rcv_w1;		msg->snd_code = RC_OK;      } else {	/* not there -- insert it */	the_entry = STAT.end_of_table;	STAT.end_of_table++;	STAT.numUnsorted++;      	DEBUG(add) kprintf(KR_OSTREAM,			   "AddKey:  Writing new entry at 0x%08x\n",			   the_entry);      	the_entry->w[0] = curBits.w[0];	the_entry->w[1] = curBits.w[1];	the_entry->w[2] = curBits.w[2];	the_entry->w[3] = curBits.w[3];	the_entry->w[4] = msg->rcv_w1; /* data field gets w1 */	if (STAT.numUnsorted > MAX_UNSORTED) {	  /* too many unsorted -- sort them in */	  require_sorted_table();	}	msg->snd_code = RC_OK;      }      break;    }  case OC_KeySet_RemoveKey:    {      struct table_entry *entry;      if (rdOnly) {	msg->snd_code = RC_UnknownRequest;	break;      } else if (setInvalid) {	msg->snd_code = RC_KeySet_SetInvalid;	break;      }      entry = FIND(the_table, curBits.w,STAT);      if (entry == NULL) {	msg->snd_code = RC_KeySet_KeyNotInSet;	break;      } else {	uint32_t x = the_table - entry;	uint32_t max = STAT.numSorted + STAT.numUnsorted;	/* copy out the stored uint32_t */	msg->snd_w1 = entry->w[4];	/* update the counts -- moving blows away x */	if (x < STAT.numSorted) {	  STAT.numSorted--;	} else {	  STAT.numUnsorted--;	}		/* move everything back 1 slot */#if 0 /* USE_MEMCPY */		memcpy(&the_table[x],   /* to */	       &the_table[x+1], /*from*/	       ((max - x) - 1)*sizeof(struct table_entry)); /* bytes */#else /* ! USE_MEMCPY */	for (x++ ; x < max; x++) {	  the_table[x-1] = the_table[x];	}#endif	msg->snd_code = RC_OK;      }    }  case OC_KeySet_ContainsKey:    {      struct table_entry *entry;            if (setInvalid) {	msg->snd_code = RC_KeySet_SetInvalid;	break;      }      entry = FIND(the_table, curBits.w,STAT);      DEBUG(contains)	kprintf(KR_OSTREAM,		"KeySet: FIND returns 0x%08x\n", entry);      if (entry == NULL) {	msg->snd_code = RC_KeySet_KeyNotInSet;	break;      } else {	msg->snd_w1 = entry->w[4]; /* give back the word */	msg->snd_code = RC_OK;	break;      }    }  case OC_KeySet_IsEmpty:    if (setInvalid) {      msg->snd_code = RC_UnknownRequest;      break;    }    /* return 0 if we have entries, 1 if not */    msg->snd_code = (STAT.numSorted || STAT.numUnsorted)?0:1;  case OC_KeySet_Empty:    if (rdOnly) {      msg->snd_code = RC_UnknownRequest;      break;    }    /* if we are not valid, emptying the set makes us valid, so... */    STAT.numSorted = 0;    STAT.numUnsorted = 0;        msg->snd_code = RC_OK;    /* if shap ever gets around to implementing FreshSpace's truncate,       We'll use it to free all of the allocated space.  Until       then... */    break;      case OC_KeySet_MakeReadOnlyKey:        /* FIXME: check return code */    process_make_start_key(KR_SELF,			  ReadOnly_KeyData,			  KR_SCRATCH);        msg->snd_key0 = KR_SCRATCH;    msg->snd_code = RC_OK;    break;      case OC_KeySet_AddKeysFromSet:    if (rdOnly) {      msg->snd_code = RC_UnknownRequest;      break;    } else if (setInvalid) {      msg->snd_code = RC_KeySet_SetInvalid;      break;    }    require_sorted_table();    msg->snd_code = AddKeysFromSet(KR_ARG0);    break;  case OC_KeySet_RemoveKeysNotInSet:    if (rdOnly) {      msg->snd_code = RC_UnknownRequest;      break;    } else if (setInvalid) {      msg->snd_code = RC_KeySet_SetInvalid;      break;    }    require_sorted_table();    msg->snd_code = RemoveKeysNotInSet(KR_ARG0);    break;#if 1 /* IsSubsetOfSet */  case OC_KeySet_IsSubsetOfSet:#else  case OC_KeySet_CompareSets: /* does expanded CompareSets imply a				 security problem for Constructors? */#endif    if (setInvalid) {          msg->snd_code = RC_KeySet_SetInvalid;      break;    }    require_sorted_table();#if 1 /* isSubSetOfSet */    msg->snd_code = CompareSets(KR_ARG0,				0);    msg->snd_code = (msg->snd_code == RC_KeySet_SetsEqual		     || msg->snd_code == RC_KeySet_SetContainsOtherSet		    ) ? RC_OK : 1;#else    msg->snd_code = CompareSets(KR_ARG0,				msg->rcv_w1);#endif    break;  case OC_KeySet_Internal_GetSegment:        if (setInvalid) {      msg->snd_code = RC_KeySet_SetInvalid;      break;    }    msg->snd_code = SlaveProtocol();    break;  case OC_Destroy:    if (rdOnly) {      msg->snd_code = RC_UnknownRequest;      break;    }    teardown();    return 0; /* CAN'T HAPPEN */  }  DEBUG(cmds)    kprintf(KR_OSTREAM,	    "KeySet: Returning result 0x%08x\n",	    msg->snd_code);  /* update keyData field, if appropriate (i.e. we were empty and     something was added to us) -- This happens if the keyDatas don't     match, we are valid, and we are now non-empty */  if (kbVersion != STAT.startKeyBitsVersion      && !setInvalid      && (STAT.numSorted || STAT.numUnsorted)) {    STAT.startKeyBitsVersion = kbVersion;  }  return 1;}intmain(){  Message msg;    Initialize();  /* make a write key and return it. */  process_make_start_key(KR_SELF, Normal_KeyData, KR_ARG0);  DEBUG(init) kdprintf(KR_OSTREAM,		       "KeySet: 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_len = 0;  msg.rcv_code = 0;  msg.rcv_w1 = 0;  msg.rcv_w2 = 0;  msg.rcv_w3 = 0;  do {    RETURN(&msg);    /* clear all of the slots we might use for sending */    msg.snd_key0 = KR_VOID;              /* until otherwise proven */    ProcessRequest(&msg);  } while(1); /*forever*/}#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;}#endif

⌨️ 快捷键说明

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