Example #1
0
void PyrGC::DumpSet(int i)
{
	GCSet *set = mSets + i;

	// scan black list
	PyrObjectHdr *obj = set->mBlack.next;
	while (!IsMarker(obj)) {
		post("black %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size);
		obj = obj->next;
	}

	// scan white list
	obj = set->mWhite.next;
	while (obj != set->mFree) {
		post("white %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size);
		obj = obj->next;
	}

	// scan free list
	obj = set->mFree;
	while (!IsMarker(obj)) {
		post("free %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size);
		obj = obj->next;
	}
}
Example #2
0
void PyrGC::ClearMarks()
{
	for (int i=0; i<kNumGCSets; ++i) {
		GCSet *set = mSets + i;

		// scan black list
		PyrObjectHdr *obj = set->mBlack.next;
		while (!IsMarker(obj)) {
			obj->ClearMark(); // unmark it
			obj = obj->next;
		}

		// scan grey list
		obj = mGrey.next;
		while (!IsMarker(obj)) {
			obj->ClearMark(); // unmark it
			obj = obj->next;
		}

		// scan white list
		obj = set->mWhite.next;
		while (obj != set->mFree) {
			obj->ClearMark(); // unmark it
			obj = obj->next;
		}

		// scan free list
		obj = set->mFree;
		while (!IsMarker(obj)) {
			obj->ClearMark(); // unmark it
			obj = obj->next;
		}
	}
}
Example #3
0
void PyrGC::DumpInfo()
{
	int i;
	PyrObjectHdr *obj;
	int numblack, numwhite, numfree, settotal, setsiztotal;
	int totblack, totgrey, totwhite, totfree, totref, total, siztotal;

	REPORTPAUSE
	post("flips %d  collects %d   nalloc %d   alloc %d   grey %d\n", mFlips, mCollects, mNumAllocs, mAllocTotal, mNumGrey);

	totblack = 0;
	totgrey = 0;
	totwhite = 0;
	totfree = 0;
	totref = 0;
	total = 0;
	siztotal = 0;
	for (i=0; i<kNumGCSizeClasses; ++i) {
		GCSet *set = mSets + i;

		// scan black list
		numblack = 0;
		obj = set->mBlack.next;
		while (!IsMarker(obj)) {
			numblack++;
			obj = obj->next;
		}

		// scan white list
		numwhite = 0;
		obj = set->mWhite.next;
		while (obj != set->mFree) {
			numwhite++;
			obj = obj->next;
		}

		// scan free list
		numfree = 0;
		obj = set->mFree;
		while (!IsMarker(obj)) {
			numfree++;
			obj = obj->next;
		}
		settotal = numblack + numwhite + numfree;
		setsiztotal = settotal << (i + 3);
		siztotal += setsiztotal;
		totblack += numblack;
		totwhite += numwhite;
		totfree += numfree;
		total += settotal;
		if (settotal) {
			post("%2d  bwf t sz: %6d %6d %6d   %6d   %8d\n", i,
				numblack, numwhite, numfree, settotal, setsiztotal);
		}
	}
	post("tot bwf t sz: %6d %6d %6d   %6d   %8d\n",
		totblack, totwhite, totfree, total, siztotal);
}
Example #4
0
static void W_CoalesceMarkedResource(const char *start_marker,
                                     const char *end_marker, int li_namespace)
{
  lumpinfo_t *marked = malloc(sizeof(*marked) * numlumps);
  size_t i, num_marked = 0, num_unmarked = 0;
  int is_marked = 0, mark_end = 0;
  lumpinfo_t *lump = lumpinfo;

  for (i=numlumps; i--; lump++)
    if (IsMarker(start_marker, lump->name))       // start marker found
      { // If this is the first start marker, add start marker to marked lumps
        if (!num_marked)
          {
            strncpy(marked->name, start_marker, 8);
            marked->size = 0;  // killough 3/20/98: force size to be 0
            marked->li_namespace = ns_global;        // killough 4/17/98
            marked->wadfile = NULL;
            num_marked = 1;
          }
        is_marked = 1;                            // start marking lumps
      }
    else
      if (IsMarker(end_marker, lump->name))       // end marker found
        {
          mark_end = 1;                           // add end marker below
          is_marked = 0;                          // stop marking lumps
        }
      else
        if (is_marked)                            // if we are marking lumps,
          {                                       // move lump to marked list
            marked[num_marked] = *lump;
            marked[num_marked++].li_namespace = li_namespace;  // killough 4/17/98
          }
        else
          lumpinfo[num_unmarked++] = *lump;       // else move down THIS list

  // Append marked list to end of unmarked list
  memcpy(lumpinfo + num_unmarked, marked, num_marked * sizeof(*marked));

  free(marked);                                   // free marked list

  numlumps = num_unmarked + num_marked;           // new total number of lumps

  if (mark_end)                                   // add end marker
    {
      lumpinfo[numlumps].size = 0;  // killough 3/20/98: force size to be 0
      lumpinfo[numlumps].wadfile = NULL;
      lumpinfo[numlumps].li_namespace = ns_global;   // killough 4/17/98
      strncpy(lumpinfo[numlumps++].name, end_marker, 8);
    }
}
Example #5
0
PyrObject *PyrGC::NewFrame(size_t inNumBytes, long inFlags, long inFormat, bool inAccount)
{
	PyrObject *obj = NULL;

#if SANITYCHECK
	SanityCheck();
#endif

	// obtain size info

	int32 alignedSize = (inNumBytes + kAlignMask) & ~kAlignMask; // 16 byte align
	int32 numSlots = alignedSize / sizeof(PyrSlot);
	numSlots = numSlots < 1 ? 1 : numSlots;
	int32 sizeclass = LOG2CEIL(numSlots);
	sizeclass = sc_min(sizeclass, kNumGCSizeClasses-1);

	int32 credit = 1L << sizeclass;
	mAllocTotal += credit;
	mNumAllocs++;
	if (inAccount) {
		mNumToScan += credit;
		if (mNumToScan >= kScanThreshold) {
			Collect();
		}
	}

	GCSet *gcs = mSets + sizeclass;

	obj = (PyrObject*)gcs->mFree;
	if (!IsMarker(obj)) {
		// from free list
		gcs->mFree = obj->next;
	} else {
		if (sizeclass > kMaxPoolSet) {
			SweepBigObjects();
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mPool->Alloc(allocSize);
		} else {
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mNewPool.Alloc(allocSize);
		}
		if (!obj) {
			post("Frame alloc failed. size = %d\n", inNumBytes);
			MEMFAILED;
		}
		DLInsertAfter(&gcs->mWhite, obj);
	}

	obj->obj_sizeclass = sizeclass;
	obj->obj_format = inFormat;
	obj->obj_flags = inFlags;
	obj->size = 0;
	obj->classptr = class_frame;
	obj->gc_color = mWhiteColor;

#if SANITYCHECK
	SanityCheck();
#endif
	return obj;
}
Example #6
0
PyrObject *PyrGC::NewFinalizer(ObjFuncPtr finalizeFunc, PyrObject *inObject, bool inCollect)
{
	PyrObject *obj = NULL;

#ifdef GC_SANITYCHECK
	SanityCheck();
#endif

	// obtain size info

	int32 sizeclass = 1;

	int32 credit = 1L << sizeclass;
	mNumToScan += credit;
	mAllocTotal += credit;
	mNumAllocs++;

	if (inCollect && mNumToScan >= kScanThreshold) {
		Collect();
	}

	GCSet *gcs = mSets + kFinalizerSet;

	obj = (PyrObject*)gcs->mFree;
	if (!IsMarker(obj)) {
		// from free list
		gcs->mFree = obj->next;
	} else {
		if (sizeclass > kMaxPoolSet) {
			SweepBigObjects();
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mPool->Alloc(allocSize);
		} else {
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mNewPool.Alloc(allocSize);
		}
		if (!obj) {
			post("Finalizer alloc failed.\n");
			MEMFAILED;
		}
		DLInsertAfter(&gcs->mWhite, obj);
	}


	obj->obj_sizeclass = sizeclass;
	obj->obj_format = obj_slot;
	obj->obj_flags = 0;
	obj->size = 2;
	obj->classptr = class_finalizer;
	obj->gc_color = mWhiteColor;

	SetPtr(obj->slots+0, (void*)finalizeFunc);
	SetObject(obj->slots+1, inObject);

#ifdef GC_SANITYCHECK
	SanityCheck();
#endif
	return obj;
}
Example #7
0
void PyrGC::DumpGrey()
{

	// scan grey list
	PyrObjectHdr *obj = mGrey.next;
	while (!IsMarker(obj)) {
		post("grey %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size);
		obj = obj->next;
	}
}
Example #8
0
void PyrGC::SweepBigObjects()
{
	if (!mCanSweep) return;

	for (int i=kMaxPoolSet+1; i<kNumGCSizeClasses; ++i) {
		GCSet *gcs = mSets + i;
		PyrObjectHdr *obj = gcs->mFree;

		if (!IsMarker(obj)) {
			// unlink chain of free objects
			gcs->mFree = obj->prev->next = &gcs->mBlack;
			gcs->mBlack.prev = obj->prev;

			do {
				PyrObjectHdr *nextobj = obj->next;
				void* ptr = (void*)obj;
				mPool->Free(ptr);
				obj = nextobj;
			} while (!IsMarker(obj));
		}
	}
	mCanSweep = false;
}
Example #9
0
bool PyrGC::SanityCheck2()
{
	int numgrey = 0;
	PyrObjectHdr *grey = mGrey.next;
	while (!IsMarker(grey)) {
		numgrey++;
		if (!IsGrey(grey)) {
			postfl("sc Object on grey list not grey  %d %d   %d\n", grey->gc_color, mGreyColor, numgrey);
			return false;
		}
		grey = grey->next;
	}
	//postfl("sc %d %d\n", mNumGrey, numgrey);
	return mNumGrey == numgrey;
}
Example #10
0
void PyrGC::RunAllFinalizers()
{
	GCSet *gcs = &mSets[kFinalizerSet];

	PyrObjectHdr *obj = gcs->mBlack.next;
	while (!IsMarker(obj)) {
		Finalize((PyrObject*)obj);
		obj = obj->next;
	}

	obj = gcs->mWhite.next;
	PyrObjectHdr *firstFreeObj = gcs->mFree;
	while (obj != firstFreeObj) {
		Finalize((PyrObject*)obj);
		obj = obj->next;
	}

	obj = mGrey.next;
	while (!IsMarker(obj)) {
		if (obj->classptr == class_finalizer)
			Finalize((PyrObject*)obj);
		obj = obj->next;
	}
}
Example #11
0
void GCSet::MajorFlip()
{
	// move all white items to beginning of free list
	mFree = mWhite.next;
	if (!IsMarker(mBlack.next)) {
		// move all black items to white list
		mWhite.next = mBlack.next;
		mFree->prev = mWhite.prev;
		mBlack.next->prev = &mWhite;
		mWhite.prev->next = mFree;

		// black list empty
		mBlack.next = &mWhite;
		mWhite.prev = &mBlack;
	}
}
Example #12
0
HOT bool PyrGC::ScanOneObj()
{
	// Find a set that has a grey object
	PyrObject* obj;
	obj = (PyrObject*)mGrey.next;
	if (IsMarker(obj)) {
		if (mNumGrey) fatalerror("grey count error\n");
		return false;
	}

	/*if (!IsGrey(obj)) {
		postfl("Object on grey list not grey  %d %d\n", obj->gc_color, mGreyColor);
		fatalerror("C1");
	}*/

	mScans++;

	//post("-> scan %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan);
	// Found a grey object
	// move obj from grey to black

	ToBlack(obj);

	int32 size = ScanSize(obj);
	//post("<- scan %d %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan, size);
	if (size > mNumToScan + 32)
	{
		mPartialScanObj = obj;
		mPartialScanSlot = 0;
		DoPartialScan(size);
	}
	else if (size > 0)
	{
		ScanSlots(obj->slots, size);
		mNumToScan -= 1L << obj->obj_sizeclass;
		if (mNumToScan < 0) mNumToScan = 0;
	} else {
		mNumToScan -= 1L << obj->obj_sizeclass;
		if (mNumToScan < 0) mNumToScan = 0;
	}
	return true;
}
Example #13
0
static int W_CoalesceMarkedResource(const char *start_marker,
                                    const char *end_marker, int li_namespace)
{
    int result = 0;
    lumpinfo_t *marked = malloc(sizeof(*marked) * numlumps);
    size_t i, num_marked = 0, num_unmarked = 0;
    int is_marked = 0, mark_end = 0;
    lumpinfo_t *lump = lumpinfo;

    for (i=numlumps; i--; lump++)
        if (IsMarker(start_marker, lump->name))       // start marker found
        {   // If this is the first start marker, add start marker to marked lumps
            if (!num_marked)
            {
                strncpy(marked->name, start_marker, 8);
                marked->size = 0;  // killough 3/20/98: force size to be 0
                marked->li_namespace = ns_global;        // killough 4/17/98
                marked->wadfile = NULL;
                num_marked = 1;
            }
            is_marked = 1;                            // start marking lumps
        }
        else if (IsMarker(end_marker, lump->name))      // end marker found
        {
            mark_end = 1;                           // add end marker below
            is_marked = 0;                          // stop marking lumps
        }
        else if (is_marked || lump->li_namespace == li_namespace)
        {
            // if we are marking lumps,
            // move lump to marked list
            // sf: check for namespace already set

            // sf 26/10/99:
            // ignore sprite lumps smaller than 8 bytes (the smallest possible)
            // in size -- this was used by some dmadds wads
            // as an 'empty' graphics resource
            if(li_namespace != ns_sprites || lump->size > 8)
            {
                marked[num_marked] = *lump;
                marked[num_marked++].li_namespace = li_namespace;  // killough 4/17/98
                result++;
            }
        }
        else
            lumpinfo[num_unmarked++] = *lump;       // else move down THIS list

    // Append marked list to end of unmarked list
    memcpy(lumpinfo + num_unmarked, marked, num_marked * sizeof(*marked));

    free(marked);                                   // free marked list

    numlumps = num_unmarked + num_marked;           // new total number of lumps

    if (mark_end)                                   // add end marker
    {
        lumpinfo[numlumps].size = 0;  // killough 3/20/98: force size to be 0
        lumpinfo[numlumps].wadfile = NULL;
        lumpinfo[numlumps].li_namespace = ns_global;   // killough 4/17/98
        strncpy(lumpinfo[numlumps++].name, end_marker, 8);
    }

    return result;
}
Example #14
0
bool PyrGC::ListSanity()
{
	bool found;

	if (StackDepth() < 0) {
		fprintf(stderr, "stack underflow %d\n", (int)StackDepth());
		return false;
	}

	//postfl("PyrGC::ListSanity\n");
	for (int i=0; i<kNumGCSets; ++i) {
		PyrObjectHdr *obj;
		GCSet* set = mSets + i;

		// check black marker
		obj = &set->mBlack;
		if (!IsMarker(obj)) {
			//debugf("set %d black marker color wrong %d %p\n", i, obj->gc_color, obj);
			fprintf(stderr, "set %d black marker color wrong %d %p\n", i, obj->gc_color, obj);
			setPostFile(stderr);
			DumpBackTrace(mVMGlobals);
			dumpBadObject((PyrObject*)obj);
			return false;
		}

		// check white marker
		obj = &set->mWhite;
		if (!IsMarker(obj)) {
			//debugf("set %d white marker color wrong %d %p\n", i, obj->gc_color, obj);
			fprintf(stderr, "set %d white marker color wrong %d %p\n", i, obj->gc_color, obj);
			setPostFile(stderr);
			DumpBackTrace(mVMGlobals);
			dumpBadObject((PyrObject*)obj);
			return false;
		}

		// check free pointer between white and black marker
		if (set->mFree != &set->mBlack) {
			obj = set->mWhite.next;
			found = false;
			while (!IsMarker(obj)) {
				if (obj == set->mFree) { found = true; break; }
				obj = obj->next;
			}
			if (!found) {
				//debugf("set %d free pointer not between white and black\n", i);
				fprintf(stderr, "set %d free pointer not between white and black\n", i);
				fprintf(stderr, "set->mFree %p\n", set->mFree);
				fprintf(stderr, "set->mWhite %p\n", &set->mWhite);
				fprintf(stderr, "set->mBlack %p\n", &set->mBlack);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)set->mFree);

				fprintf(stderr, "black %d white %d grey %d\n", mBlackColor, mWhiteColor, mGreyColor);

				obj = &set->mWhite;
				int count = 0;
				do {
					if (obj == set->mFree) fprintf(stderr, "%4d %p %3d %d FREE\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else if (obj == &set->mWhite) fprintf(stderr, "%4d %p %3d %d WHITE\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else if (obj == &set->mBlack) fprintf(stderr, "%4d %p %3d %d BLACK\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else fprintf(stderr, "%4d %p %3d %d\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					obj = obj->next;
					count++;
				} while (obj != &set->mWhite);

				return false;
			}
		}

		// scan black list
		obj = set->mBlack.next;
		while (!IsMarker(obj)) {
			if (obj->gc_color != mBlackColor) {
				//debugf("set %d black list obj color wrong %d (%d, %d, %d) %p\n",
				//	i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				fprintf(stderr, "set %d black list obj color wrong %d (%d, %d, %d) %p\n",
					i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (GetGCSet(obj) != set) {
				//debugf("set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				setPostFile(stderr);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d black obj->next->prev != obj\n", i);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
			}

			// scan for refs to white.
			if (!BlackToWhiteCheck((PyrObject*)obj)) return false;

			obj = obj->next;
		}

		// scan white list
		obj = set->mWhite.next;
		while (obj != set->mFree) {
			if (obj->gc_color != mWhiteColor) {
				//debugf("set %d white list obj color wrong %d (%d, %d, %d) %p\n",
				//	i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				//debugf("hmmm free %p  black %p\n", set->mFree, set->black);
				fprintf(stderr, "set %d white list obj color wrong %d (%d, %d, %d) %p\n",
					i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				fprintf(stderr, "hmmm free %p  black %p\n", set->mFree, &set->mBlack);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (GetGCSet(obj) != set) {
				//debugf("set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d white obj->next->prev != obj\n", i);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
			}
			obj = obj->next;
		}

		// mark all free list items free
		obj = set->mFree;
		while (!IsMarker(obj)) {
			/*if (obj->gc_color == mGreyColor) {
				//debugf("grey obj on free list\n");
				fprintf(stderr, "grey obj on free list\n");
				return false;
			}*/
			//post("FREE\n");
			//dumpObject((PyrObject*)(PyrObject*)obj);
			obj->gc_color = mFreeColor;
			if (GetGCSet(obj) != set) {
				//debugf("set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				//dumpObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d free obj->next->prev != obj\n", i);
				//dumpObject((PyrObject*)obj);
			}
			obj = obj->next;
		}
	}

	int numgrey = 0;
	PyrObjectHdr *grey = mGrey.next;
	while (!IsMarker(grey)) {
		numgrey++;
		if (!IsGrey(grey)) {
			fprintf(stderr, "sc Object on grey list not grey  %d %d   %d\n", grey->gc_color, mGreyColor, numgrey);
			fprintf(stderr, "%p <- %p -> %p grey %p process %p\n", mGrey.prev, &mGrey, mGrey.next, grey, mProcess);
			return false;
		}
		grey = grey->next;
	}

	if (numgrey != mNumGrey) {
		fprintf(stderr, "grey count off %d %d\n", numgrey, mNumGrey);
		DumpInfo();
		fprintf(stderr, ".");
		return false;
	}
	return true;
}
Example #15
0
int CgptPrioritize(CgptPrioritizeParams *params) {
  struct drive drive;

  int priority;

  int gpt_retval;
  uint32_t index;
  uint32_t max_part;
  int num_root;
  int i,j;
  group_list_t *groups;

  if (params == NULL)
    return CGPT_FAILED;

  if (CGPT_OK != DriveOpen(params->drive_name, &drive, 0, O_RDWR))
    return CGPT_FAILED;

  if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
    Error("GptSanityCheck() returned %d: %s\n",
          gpt_retval, GptError(gpt_retval));
    return CGPT_FAILED;
  }

  max_part = GetNumberOfEntries(&drive);

  if (params->set_partition) {
    if (params->set_partition < 1 || params->set_partition > max_part) {
      Error("invalid partition number: %d (must be between 1 and %d\n",
            params->set_partition, max_part);
      goto bad;
    }
    index = params->set_partition - 1;
    // it must be a kernel
    if (!IsRoot(&drive, PRIMARY, index) && !IsMarker(&drive, PRIMARY, index)) {
      Error("partition %d is not a valid root\n", params->set_partition);
      goto bad;
    }
  }

  // How many kernel partitions do I have?
  num_root = 0;
  for (i = 0; i < max_part; i++) {
    if (IsRoot(&drive, PRIMARY, i) || IsMarker(&drive, PRIMARY, i))
      num_root++;
  }

  if (num_root) {
    // Determine the current priority groups
    groups = NewGroupList(num_root);
    for (i = 0; i < max_part; i++) {
      if (!IsRoot(&drive, PRIMARY, i) && !IsMarker(&drive, PRIMARY, i))
        continue;

      priority = GetPriority(&drive, PRIMARY, i);

      // Is this partition special?
      if (params->set_partition && (i+1 == params->set_partition)) {
        params->orig_priority = priority;  // remember the original priority
        if (params->set_friends)
          AddToGroup(groups, priority, i); // we'll move them all later
        else
          AddToGroup(groups, 99, i);       // move only this one
      } else {
        AddToGroup(groups, priority, i);   // just remember
      }
    }

    // If we're including friends, then change the original group priority
    if (params->set_partition && params->set_friends) {
      ChangeGroup(groups, params->orig_priority, 99);
    }

    // Sorting gives the new order. Now we just need to reassign the
    // priorities.
    SortGroups(groups);

    // We'll never lower anything to zero, so if the last group is priority zero
    // we can ignore it.
    i = groups->num_groups;
    if (groups->group[i-1].priority == 0)
      groups->num_groups--;

    // Where do we start?
    if (params->max_priority)
      priority = params->max_priority;
    else
      priority = groups->num_groups > 15 ? 15 : groups->num_groups;

    // Figure out what the new values should be
    for (i=0; i<groups->num_groups; i++) {
      groups->group[i].priority = priority;
      if (priority > 1)
        priority--;
    }

    // Now apply the ranking to the GPT
    for (i=0; i<groups->num_groups; i++)
      for (j=0; j<groups->group[i].num_parts; j++)
        SetPriority(&drive, PRIMARY,
                    groups->group[i].part[j], groups->group[i].priority);

    FreeGroups(groups);
  }

  // Write it all out
  UpdateAllEntries(&drive);

  return DriveClose(&drive, 1);

bad:
  (void) DriveClose(&drive, 0);
  return CGPT_FAILED;
}
Example #16
0
void W_MergeLumps (const char *start, const char *end, int space)
{
    char ustart[8], uend[8];
    lumpinfo_t *newlumpinfos;
    unsigned newlumps, oldlumps;
    BOOL insideBlock;
    unsigned flatHack, i;

    strncpy(ustart, start, 8);
    strncpy(uend, end, 8);

    std::transform(ustart, ustart + sizeof(ustart), ustart, toupper);
    std::transform(uend, uend + sizeof(uend), uend, toupper);

    // Some pwads use an icky hack to get flats with regular Doom.
    // This tries to detect them.
    flatHack = 0;
    if (!strcmp ("F_START", ustart) && !Args.CheckParm ("-noflathack"))
    {
        int fudge = 0;
        unsigned start = 0;

        for (i = 0; i < numlumps; i++) {
            if (IsMarker (lumpinfo + i, ustart))
                fudge++, start = i;
            else if (IsMarker (lumpinfo + i, uend))
                fudge--, flatHack = i;
        }
        if (start > flatHack)
            fudge--;
        if (fudge >= 0)
            flatHack = 0;
    }

    newlumpinfos = new lumpinfo_t[numlumps];

    newlumps = 0;
    oldlumps = 0;
    insideBlock = false;

    for (i = 0; i < numlumps; i++)
    {
        if (!insideBlock)
        {
            // Check if this is the start of a block
            if (IsMarker (lumpinfo + i, ustart))
            {
                insideBlock = true;

                // Create start marker if we haven't already
                if (!newlumps)
                {
                    newlumps++;
                    strncpy (newlumpinfos[0].name, ustart, 8);
                    newlumpinfos[0].handle = NULL;
                    newlumpinfos[0].position =
                        newlumpinfos[0].size = 0;
                    newlumpinfos[0].namespc = ns_global;
                }
            }
            else
            {
                // Copy lumpinfo down this list
                lumpinfo[oldlumps++] = lumpinfo[i];
            }
        }
        else
        {
            // Check if this is the end of a block
            if (flatHack)
            {
                if (flatHack == i)
                {
                    insideBlock = false;
                    flatHack = 0;
                }
                else
                {
                    if (lumpinfo[i].size != 4096)
                    {
                        lumpinfo[oldlumps++] = lumpinfo[i];
                    }
                    else
                    {
                        newlumpinfos[newlumps] = lumpinfo[i];
                        newlumpinfos[newlumps++].namespc = space;
                    }
                }
            }
            else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle)
            {
                // Blocks cannot span multiple files
                insideBlock = false;
                lumpinfo[oldlumps++] = lumpinfo[i];
            }
            else if (IsMarker (lumpinfo + i, uend))
            {
                // It is. We'll add the end marker once
                // we've processed everything.
                insideBlock = false;
            }
            else
            {
                newlumpinfos[newlumps] = lumpinfo[i];
                newlumpinfos[newlumps++].namespc = space;
            }
        }
    }

    // Now copy the merged lumps to the end of the old list
    // and create the end marker entry.

    if (newlumps)
    {
        if (oldlumps + newlumps > numlumps)
            lumpinfo = (lumpinfo_t *)Realloc (lumpinfo, oldlumps + newlumps);

        memcpy (lumpinfo + oldlumps, newlumpinfos, sizeof(lumpinfo_t) * newlumps);

        numlumps = oldlumps + newlumps;

        strncpy (lumpinfo[numlumps].name, uend, 8);
        lumpinfo[numlumps].handle = NULL;
        lumpinfo[numlumps].position =
            lumpinfo[numlumps].size = 0;
        lumpinfo[numlumps].namespc = ns_global;
        numlumps++;
    }

    delete[] newlumpinfos;
}
Example #17
0
//
// Merge lumps between start and end markers.
// Basically from Boom too, but modified.
//
void W_MergeLumps(char *start, char *end)
{
    lumpinfo_t	*newlumpinfo;
    int		oldlumps;
    int		newlumps;
    int		in_block = 0;
    int		i;

    newlumpinfo = (lumpinfo_t *)alloca(numlumps * sizeof(lumpinfo_t));
    oldlumps = newlumps = 0;

    for (i = 0; i < numlumps; i++)
    {
	// process lumps in global namespace
	if (!in_block)
	{
	    // check for start of block
            if (IsMarker(start, lumpinfo[i].name))
	    {
		in_block = 1;
		if (!newlumps)
		{
		    newlumps++;
		    memset(newlumpinfo[0].name, 0, 8);
		    strcpy(newlumpinfo[0].name, start);
		    newlumpinfo[0].handle = -1;
		    newlumpinfo[0].position = newlumpinfo[0].size = 0;
		}
	    }
	    // else copy it
	    else
	    {
		lumpinfo[oldlumps++] = lumpinfo[i];
	    }
	}
	// process lumps in sprites or flats namespace
	else
	{
	    // check for end of block
	    if (IsMarker(end, lumpinfo[i].name))
	    {
		in_block = 0;
	    }
	    else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle)
	    {
		in_block = 0;
		lumpinfo[oldlumps++] = lumpinfo[i];
	    }
	    else
	    {
		newlumpinfo[newlumps++] = lumpinfo[i];
	    }
	}
    }

    // now copy the merged lumps to the end of the old list
    if (newlumps)
    {
	if (oldlumps + newlumps > numlumps)
	    lumpinfo = realloc(lumpinfo, (oldlumps + newlumps) *
				 sizeof(lumpinfo_t));
	memcpy(lumpinfo + oldlumps, newlumpinfo, sizeof(lumpinfo_t) * newlumps);

	numlumps = oldlumps + newlumps;

	memset(lumpinfo[numlumps].name, 0, 8);
	strcpy(lumpinfo[numlumps].name, end);
	lumpinfo[numlumps].handle = -1;
	lumpinfo[numlumps].position = lumpinfo[numlumps].size = 0;
	numlumps++;
    }
}
Example #18
0
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack)
{
	bool warned = false;
	int numstartmarkers = 0, numendmarkers = 0;
	unsigned int i;
	TArray<Marker> markers;
	
	for(i = 0; i < NumLumps; i++)
	{
		if (IsMarker(i, startmarker))
		{
			Marker m = {0, i };
			markers.Push(m);
			numstartmarkers++;
		}
		else if (IsMarker(i, endmarker))
		{
			Marker m = {1, i };
			markers.Push(m);
			numendmarkers++;
		}
	}

	if (numstartmarkers == 0)
	{
		if (numendmarkers == 0) return;	// no markers found

		Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);

		
		if (flathack)
		{
			// We have found no F_START but one or more F_END markers.
			// mark all lumps before the last F_END marker as potential flats.
			int end = markers[markers.Size()-1].index;
			for(int i = 0; i < end; i++)
			{
				if (Lumps[i].LumpSize == 4096)
				{
					// We can't add this to the flats namespace but 
					// it needs to be flagged for the texture manager.
					DPrintf("Marking %s as potential flat\n", Lumps[i].Name);
					Lumps[i].Flags |= LUMPF_MAYBEFLAT;
				}
			}
		}
		return;
	}

	i = 0;
	while (i < markers.Size())
	{
		int start, end;
		if (markers[i].markertype != 0)
		{
			Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
			i++;
			continue;
		}
		start = i++;

		// skip over subsequent x_START markers
		while (i < markers.Size() && markers[i].markertype == 0)
		{
			Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", startmarker);
			i++;
			continue;
		}
		// same for x_END markers
		while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1))
		{
			Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker);
			i++;
			continue;
		}
		// We found a starting marker but no end marker. Ignore this block.
		if (i >= markers.Size())
		{
			Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker);
			end = NumLumps;
		}
		else
		{
			end = markers[i++].index;
		}

		// we found a marked block
		DPrintf("Found %s block at (%d-%d)\n", startmarker, markers[start].index, end);
		for(int j = markers[start].index + 1; j < end; j++)
		{
			if (Lumps[j].Namespace != ns_global)
			{
				if (!warned)
				{
					Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found (lump %d)\n", j);
				}
				warned = true;
			}
			else if (space == ns_sprites && Lumps[j].LumpSize < 8)
			{
				// sf 26/10/99:
				// ignore sprite lumps smaller than 8 bytes (the smallest possible)
				// in size -- this was used by some dmadds wads
				// as an 'empty' graphics resource
				DPrintf(" Skipped empty sprite %s (lump %d)\n", Lumps[j].Name, j);
			}
			else
			{
				Lumps[j].Namespace = space;
			}
		}
	}
}