/* TrashTracker.c */
/*****************************************************************************/
/*                                                                           */
/*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
/*    Copyright (C) 1994  Thomas R. Lawrence                                 */
/*                                                                           */
/*    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 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
/*                                                                           */
/*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
/*                                                                           */
/*****************************************************************************/

#include "MiscInfo.h"
#include "Audit.h"
#include "Debug.h"
#include "Definitions.h"

#include "TrashTracker.h"
#include "Memory.h"


typedef struct ConsCellRec
	{
		void*									TheBlock;
		struct ConsCellRec*		Next;
	} ConsCellRec;


struct TrashTrackRec
	{
		ConsCellRec*					ItemList;
	};


/* create a trash tracking record */
TrashTrackRec*		NewTrashTracker(void)
	{
		TrashTrackRec*	Trash;

		Trash = (TrashTrackRec*)AllocPtrCanFail(sizeof(TrashTrackRec),"TrashTrackRec");
		if (Trash == NIL)
			{
			 FailurePoint1:
				return NIL;
			}
		Trash->ItemList = NIL;
		return Trash;
	}


/* dispose a trash tracking record & delete all blocks it contains */
void							DisposeTrashTracker(TrashTrackRec* Trash)
	{
		ConsCellRec*		Scan;

		CheckPtrExistence(Trash);
		Scan = Trash->ItemList;
		while (Scan != NIL)
			{
				ConsCellRec*		Temp;

				Temp = Scan;
				Scan = Scan->Next;
				ReleasePtr((char*)Temp->TheBlock);
				ReleasePtr((char*)Temp);
			}
		ReleasePtr((char*)Trash);
	}


/* allocate a new block & store a reference in the trash record */
/* blocks allocated from this routine are normal heap blocks which may be */
/* used anywhere a block from AllocPtrCanFail() may be used. */
char*							AllocTrackedBlock(long NumBytes, TrashTrackRec* Trash)
	{
		char*						TheBlock;
		ConsCellRec*		TrackRecord;

		CheckPtrExistence(Trash);
		TheBlock = AllocPtrCanFail(NumBytes,"AllocTrackedBlock: block");
		if (TheBlock == NIL)
			{
			 FailurePoint1:
				return NIL;
			}

		TrackRecord = (ConsCellRec*)AllocPtrCanFail(sizeof(ConsCellRec),
			"AllocTrackedBlock: ConsCellRec");
		if (TrackRecord == NIL)
			{
			 FailurePoint2:
				ReleasePtr((char*)TheBlock);
				goto FailurePoint1;
			}

		TrackRecord->TheBlock = TheBlock;
		TrackRecord->Next = Trash->ItemList;
		Trash->ItemList = TrackRecord;
		return TheBlock;
	}
