#include "IrEvent.h"
#include "CList.h"
#include "CListIterator.h"
#include "CBufferSegment.h"
#include "IrDALog.h"
#define private static
#if (hasTracing > 0 && hasIrEventTracing > 0)
enum TraceCodes
{
kLogInitEventLists = 1,
kLogDeleteEventList,
kAllocateEventBlock,
kGrabEventBlock,
kReleaseEventBlock,
kLogReleaseErr1,
kLogReleaseErr2,
kLogReleaseErr3,
kLogGrabErr1,
kLogGrabErr2,
kLogGrabErr3
};
private
EventTraceCauseDesc TraceEvents[] = {
{kLogInitEventLists, "IrEvent: Init event block lists"},
{kLogDeleteEventList, "IrEvent: Delete event list, contents=, count="},
{kAllocateEventBlock, "IrEvent: Allocate Event Block, list size="},
{kGrabEventBlock, "IrEvent: Grab Event Block"},
{kReleaseEventBlock, "IrEvent: Release Event Block"},
{kLogReleaseErr1, "IrEvent: Release ERROR, not on in use list, err="},
{kLogReleaseErr2, "IrEvent: Release ERROR, in use list="},
{kLogReleaseErr3, "IrEvent: Release ERROR, in use size, members="},
{kLogGrabErr1, "IrEvent: Grab ERROR, failed to add to in-use list, err="},
{kLogGrabErr2, "IrEvent: Grab ERROR, in use list="},
{kLogGrabErr3, "IrEvent: Grab ERROR, in use size, members="}
};
#define XTRACE(x, y, z) IrDALogAdd (x, y, (uintptr_t)z & 0xffff, TraceEvents, true )
#else
#define XTRACE(x, y, z) ((void)0)
#endif
CList *gFreeEventList = nil;
CList *gInUseEventList = nil;
void DeleteEventListItems(CList *eventlist, Boolean check_contents);
#define super OSObject
OSDefineMetaClassAndStructors(TIrEvent, OSObject);
IrDAErr
TIrEvent::InitEventLists()
{
XTRACE(kLogInitEventLists, 0, 0);
ncheck(gFreeEventList);
ncheck(gInUseEventList);
check(sizeof(TIrLargestEvent) >= sizeof(TIrEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrDiscoverEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrExtDiscoverEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrLSAPConnEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrConnectEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrDataXferEvent));
check(sizeof(TIrLargestEvent) >= sizeof(TIrLookupEvent));
gFreeEventList = CList::cList();
require(gFreeEventList, Fail);
gInUseEventList = CList::cList();
require(gInUseEventList, Fail);
return noErr;
Fail:
if (gFreeEventList) gFreeEventList->release();
gFreeEventList->release();
if (gInUseEventList) gInUseEventList->release();
gInUseEventList->release();
return kIrDAErrNoMemory;
}
void
TIrEvent::DeleteEventLists(void)
{
if (gFreeEventList) { DeleteEventListItems(gFreeEventList, false);
gFreeEventList->release();
gFreeEventList = nil;
}
if (gInUseEventList) { DeleteEventListItems(gInUseEventList, true);
gInUseEventList->release();
gInUseEventList = nil;
}
}
void
DeleteEventListItems(CList *eventlist, Boolean check_contents)
{
XTRACE(kLogDeleteEventList, check_contents, eventlist->GetArraySize());
if (eventlist->GetArraySize() > 0) {
TIrEvent *event;
for (int index = eventlist->GetArraySize() - 1; index >= 0 ; index--) {
event = (TIrEvent*)eventlist->At(index);
eventlist->RemoveAt(index);
require(event, Fail);
XTRACE(kLogDeleteEventList, 0, event);
XTRACE(kLogDeleteEventList, 0, event->fEvent);
event->release();
}
}
Fail:
return;
}
TIrEvent *
TIrEvent::GrabEventBlock(ULong event, ULong size)
{
#pragma unused(size)
TIrEvent* eventBlock = nil;
IrDAErr err;
require(gFreeEventList, Fail_New_EventBlock);
require(gInUseEventList, Fail_New_EventBlock);
check( size <= sizeof( TIrLargestEvent ) );
if (gFreeEventList->GetArraySize() > 0) {
eventBlock = (TIrEvent *)gFreeEventList->Last();
require(eventBlock, Fail_New_EventBlock);
check(eventBlock->fAllocated == false);
gFreeEventList->RemoveLast();
}
else {
XTRACE(kAllocateEventBlock, gInUseEventList->GetArraySize(), gFreeEventList->GetArraySize());
eventBlock = TIrLargestEvent::tIrLargestEvent();
require(eventBlock, Fail_New_EventBlock);
}
err = gInUseEventList->InsertLast(eventBlock); ncheck(err);
if (err) {
XTRACE(kLogGrabErr1, err >> 16, err);
XTRACE(kLogGrabErr2, 0, gInUseEventList);
XTRACE(kLogGrabErr3, 0, gInUseEventList->GetArraySize());
}
eventBlock->fEvent = (UByte)event;
eventBlock->fClient = nil;
eventBlock->fDest = nil;
eventBlock->fResult = noErr;
eventBlock->fAllocated = true;
Fail_New_EventBlock:
XTRACE( kGrabEventBlock, 0, eventBlock);
return eventBlock;
}
void
TIrEvent::ReleaseEventBlock(TIrEvent * eventBlock)
{
XTRACE( kReleaseEventBlock, 0, eventBlock);
require(eventBlock, Fail);
require(eventBlock->fAllocated == true, Fail);
if (gInUseEventList) { IrDAErr err;
err = gInUseEventList->Remove(eventBlock);
ncheck(err);
if (err) {
XTRACE(kLogReleaseErr1, err >> 16, err);
XTRACE(kLogReleaseErr2, 0, gInUseEventList);
XTRACE(kLogReleaseErr3, 0, gInUseEventList->GetArraySize());
}
}
eventBlock->fAllocated = false;
if (gFreeEventList) { gFreeEventList->InsertLast(eventBlock);
}
else { eventBlock->release();
}
Fail:
return;
}
#if (hasTracing > 0 && hasIrEventTracing > 1)
#endif // #if hasIrEventTracing > 1
#undef super
#define super TIrEvent
OSDefineMetaClassAndStructors(TIrLargestEvent, TIrEvent);
TIrLargestEvent *
TIrLargestEvent::tIrLargestEvent()
{
TIrLargestEvent *obj;
obj = new TIrLargestEvent;
if (obj && !obj->init()) {
obj->release();
obj = nil;
}
return obj;
}
#pragma mark ------ Code recycle bin
#ifdef never
Boolean
TIrEvent::CheckAllocated(TIrEvent * eventBlock)
{
int index;
XTRACE(kLogChecking, (int)eventBlock >> 16, eventBlock);
if (gInUseEventList) {
DumpCList(gInUseEventList);
index = gInUseEventList->GetIdentityIndex(eventBlock);
if (index >= 0) {
XTRACE(kLogCheckOk, 0, index);
return true;
}
else {
IOLog("Event check failed\n");
XTRACE(kLogCheckFailed, 0xffff, 0xffff);
return false;
}
}
return false;
}
void DumpCList(CList *list)
{
XTRACE(kLogCList, (int)list >> 16, list);
XTRACE(kLogCListSize, list->fSize >> 16, list->fSize);
XTRACE(kLogCListElemSize, list->fElementSize >> 16, list->fElementSize);
XTRACE(kLogCListChunk, list->fChunkSize >> 16, list->fChunkSize);
XTRACE(kLogCListAllocated, list->fAllocatedSize >> 16, list->fAllocatedSize);
XTRACE(kLogCListBuffer, (int)list->fArrayBlock >> 16, list->fArrayBlock);
XTRACE(kLogCListIters, (int)list->fIterator >> 16, list->fIterator);
if (list->fElementSize == 4 && list->fArrayBlock) { int i;
UInt32 *block = (UInt32 *)list->fArrayBlock;
for (i = 0 ; i < list->fAllocatedSize; i++) {
UInt32 x;
x = *block++;
XTRACE(kLogCListContents, x >> 16, x);
}
}
}
#endif // never