RingStatus_t RingGeneric_c::Extract( unsigned int *Value, unsigned int BlockingPeriod ) { // // If there is nothing in the ring we wait for upto the specified period. // OS_ResetEvent( &Signal ); if( (NextExtract == NextInsert) && (BlockingPeriod != RING_NONE_BLOCKING) ) OS_WaitForEvent( &Signal, BlockingPeriod ); OS_LockMutex( &Lock ); if( NextExtract != NextInsert ) { *Value = Storage[NextExtract]; NextExtract++; if( NextExtract == Limit ) NextExtract = 0; OS_UnLockMutex( &Lock ); return RingNoError; } OS_UnLockMutex( &Lock ); return RingNothingToGet; }
//}}} //{{{ RemoveStream HavanaStatus_t HavanaPlayback_c::RemoveStream (class HavanaStream_c* HavanaStream) { int i; PLAYBACK_DEBUG("\n"); if (HavanaStream == NULL) return HavanaStreamInvalid; OS_LockMutex (&Lock); for (i = 0; i < MAX_STREAMS_PER_PLAYBACK; i++) { if (Stream[i] == HavanaStream) break; } if (i == MAX_STREAMS_PER_PLAYBACK) { PLAYBACK_ERROR("Unable to locate stream for delete\n"); OS_UnLockMutex (&Lock); return HavanaStreamInvalid; } //PLAYBACK_DEBUG ("Removing stream %p, %d\n", Stream[i], i); delete Stream[i]; Stream[i] = NULL; OS_UnLockMutex (&Lock); return HavanaNoError; }
//}}} //{{{ DeletePlayback HavanaStatus_t HavanaPlayer_c::DeletePlayback (HavanaPlayback_c* HavanaPlayback) { int i; if (HavanaPlayback == NULL) return HavanaPlaybackInvalid; OS_LockMutex (&Lock); for (i = 0; i < MAX_PLAYBACKS; i++) { if (Playback[i] == HavanaPlayback) break; } if (i == MAX_PLAYBACKS) { HAVANA_ERROR("Unable to locate playback for delete\n"); OS_UnLockMutex (&Lock); return HavanaPlaybackInvalid; } delete HavanaPlayback; Playback[i] = NULL; OS_UnLockMutex (&Lock); return HavanaNoError; }
RingStatus_t RingGeneric_c::Insert( unsigned int Value ) { unsigned int OldNextInsert; OS_LockMutex( &Lock ); OldNextInsert = NextInsert; Storage[NextInsert] = Value; NextInsert++; if( NextInsert == Limit ) NextInsert = 0; if( NextInsert == NextExtract ) { NextInsert = OldNextInsert; OS_UnLockMutex( &Lock ); return RingTooManyEntries; } OS_UnLockMutex( &Lock ); OS_SetEvent( &Signal ); return RingNoError; }
BufferStatus_t BufferManager_Generic_c::DestroyPool(BufferPool_t Pool) { BufferPool_Generic_t LocalPool = (BufferPool_Generic_t)Pool; BufferPool_Generic_t *LocationOfPointer; // // First find and remove the pool from our list // OS_LockMutex(&Lock); for (LocationOfPointer = &ListOfBufferPools; *LocationOfPointer != NULL; LocationOfPointer = &((*LocationOfPointer)->Next)) if (*LocationOfPointer == LocalPool) break; if (*LocationOfPointer == NULL) { report(severity_error, "BufferManager_Generic_c::DestroyPool - Pool not found.\n"); OS_UnLockMutex(&Lock); return BufferPoolNotFound; } *LocationOfPointer = LocalPool->Next; OS_UnLockMutex(&Lock); // // Then destroy the actual pool // delete LocalPool; return BufferNoError; }
//}}} //{{{ AddStream //{{{ doxynote /// \brief Create a new stream, initialise it and add it to this playback /// \param Media Textual description of media (audio or video) /// \param Format Stream packet format (PES) /// \param Encoding The encoding of the stream content (MPEG2/H264 etc) /// \param SurfaceId Topological identifier for PiP and speaker-in-speaker. /// \param HavanaStream Reference to created stream /// \return Havana status code, HavanaNoError indicates success. //}}} HavanaStatus_t HavanaPlayback_c::AddStream (char* Media, char* Format, char* Encoding, unsigned int SurfaceId, class HavanaStream_c** HavanaStream) { HavanaStatus_t Status; int i; //if (*HavanaStream != NULL) // Device already has this stream // return HavanaStreamAlreadyExists; OS_LockMutex (&Lock); for (i = 0; i < MAX_STREAMS_PER_PLAYBACK; i++) { if (Stream[i] == NULL) break; } if (i == MAX_STREAMS_PER_PLAYBACK) { PLAYBACK_ERROR("Unable to create stream context - Too many streams\n"); OS_UnLockMutex (&Lock); return HavanaTooManyStreams; } Stream[i] = new HavanaStream_c(); if (Stream[i] == NULL) { PLAYBACK_ERROR("Unable to create stream context - insufficient memory\n"); OS_UnLockMutex (&Lock); return HavanaNoMemory; } Status = Stream[i]->Init (HavanaPlayer, Player, PlayerPlayback, Media, Format, Encoding, SurfaceId); if (Status != HavanaNoError) { delete Stream[i]; Stream[i] = NULL; OS_UnLockMutex (&Lock); return Status; } //PLAYBACK_DEBUG ("Adding stream %p, %d\n", Stream[i], i); *HavanaStream = Stream[i]; OS_UnLockMutex (&Lock); return HavanaNoError; }
AllocatorStatus_t AllocatorSimple_c::ExtendToLargest( unsigned int *Size, unsigned char **Block, bool ExtendUpwards) { unsigned int i; unsigned char *BoundaryToExtend; // if (ExtendUpwards) { // // First check to see if extension is even possible // BoundaryToExtend = *Block + *Size; if (On64MBBoundary(BoundaryToExtend) || (BoundaryToExtend >= (PhysicalAddress + BufferSize))) return AllocatorNoMemory; // // Now scan for an adjacent block // OS_LockMutex(&Lock); for (i = 0; i < (HighestUsedBlockIndex + 1); i++) if (Blocks[i].InUse && (BoundaryToExtend == Blocks[i].Base)) { *Size += Blocks[i].Size; Blocks[i].Size = 0; Blocks[i].InUse = false; OS_UnLockMutex(&Lock); return AllocatorNoError; } } else { // // First check to see if extension is even possible // BoundaryToExtend = *Block; if (On64MBBoundary(BoundaryToExtend) || (BoundaryToExtend == PhysicalAddress)) return AllocatorNoMemory; // // Now scan for an adjacent block // OS_LockMutex(&Lock); for (i = 0; i < (HighestUsedBlockIndex + 1); i++) if (Blocks[i].InUse && (BoundaryToExtend == (Blocks[i].Base + Blocks[i].Size))) { *Size += Blocks[i].Size; *Block = Blocks[i].Base; Blocks[i].Size = 0; Blocks[i].InUse = false; OS_UnLockMutex(&Lock); return AllocatorNoError; } } OS_UnLockMutex(&Lock); return AllocatorUnableToAllocate; }
StackStatus_t StackGeneric_c::Push(unsigned int Value) { OS_LockMutex(&Lock); if (Level == Limit) { OS_UnLockMutex(&Lock); return StackTooManyEntries; } Storage[Level++] = Value; OS_UnLockMutex(&Lock); return StackNoError; }
ManifestorStatus_t Manifestor_Audio_c::DequeueBuffer(unsigned int *BufferIndexPtr, bool NonBlock) { unsigned int BufferIndex; while( !ForcedUnblock ) { // // Dequeue the buffer // OS_LockMutex(&BufferQueueLock); if( BufferQueueHead != INVALID_BUFFER_ID ) { #ifdef __TDT__ if(QueuedBufferCount < 3) inject_silent_count = 3; if(inject_silent_count > 0) { OS_UnLockMutex(&BufferQueueLock); inject_silent_count--; return ManifestorWouldBlock; } #endif BufferIndex = BufferQueueHead; BufferQueueHead = StreamBuffer[BufferIndex].NextIndex; QueuedBufferCount--; NotQueuedBufferCount++; OS_UnLockMutex(&BufferQueueLock); *BufferIndexPtr = BufferIndex; return ManifestorNoError; } OS_UnLockMutex(&BufferQueueLock); // // Block if no buffer is available. // if( NonBlock ) return ManifestorWouldBlock; OS_WaitForEvent(&BufferQueueUpdated, OS_INFINITE); OS_ResetEvent(&BufferQueueUpdated); } return ManifestorError; }
//}}} //{{{ CreatePlayback HavanaStatus_t HavanaPlayer_c::CreatePlayback (HavanaPlayback_c** HavanaPlayback) { HavanaStatus_t HavanaStatus; int i; HAVANA_DEBUG("\n"); OS_LockMutex (&Lock); for (i = 0; i < MAX_PLAYBACKS; i++) { if (Playback[i] != NULL) { if (Playback[i]->Active () == HavanaPlaybackActive) continue; } break; } if (i == MAX_PLAYBACKS) { HAVANA_ERROR("Unable to create playback context - Too many playbacks\n"); OS_UnLockMutex (&Lock); return HavanaTooManyPlaybacks; } if (Playback[i] == NULL) Playback[i] = new HavanaPlayback_c (); if (Playback[i] == NULL) { HAVANA_ERROR("Unable to create playback context - insufficient memory\n"); OS_UnLockMutex (&Lock); return HavanaNoMemory; } HavanaStatus = Playback[i]->Init (this, Player, BufferManager); if (HavanaStatus != HavanaNoError) { HAVANA_ERROR("Unable to create playback context %x\n", HavanaStatus); delete Playback[i]; Playback[i] = NULL; OS_UnLockMutex (&Lock); return HavanaStatus; } *HavanaPlayback = Playback[i]; OS_UnLockMutex (&Lock); return HavanaNoError; }
AllocatorStatus_t AllocatorSimple_c::Allocate( unsigned int Size, unsigned char **Block, bool NonBlocking) { unsigned int i; // if (this == NULL) return AllocatorError; // InAllocate = true; Size = (((Size + SegmentSize - 1) / SegmentSize) * SegmentSize); do { OS_LockMutex(&Lock); OS_ResetEvent(&EntryFreed); // if (BeingDeleted) break; // for (i = 0; i < (HighestUsedBlockIndex + 1); i++) if (Blocks[i].InUse && (Blocks[i].Size >= Size)) { *Block = Blocks[i].Base; Blocks[i].Base += Size; Blocks[i].Size -= Size; if (Blocks[i].Size == 0) Blocks[i].InUse = false; OS_UnLockMutex(&Lock); InAllocate = false; return AllocatorNoError; } // #if 0 { report(severity_info, "Waiting for memory \n"); for (i = 0; i < ALLOCATOR_SIMPLE_MAX_BLOCKS; i++) if (Blocks[i].InUse) report(severity_info, " %08x - %06x\n", Blocks[i].Base, Blocks[i].Size); } #endif // OS_UnLockMutex(&Lock); if (!NonBlocking) OS_WaitForEvent(&EntryFreed, OS_INFINITE); } while (!NonBlocking && !BeingDeleted); InAllocate = false; return AllocatorUnableToAllocate; }
//////////////////////////////////////////////////////////////////////////// /// /// Release any buffers queued within the StreamBuffer structure. /// /// Pass any buffer held on the Manifestor_Audio_c::StreamBuffer structure /// onto the output ring. /// /// The super-class will tidy up an queued events. /// ManifestorStatus_t Manifestor_Audio_c::ReleaseQueuedDecodeBuffers() { ManifestorStatus_t Status; MANIFESTOR_DEBUG(">><<\n"); OS_LockMutex(&BufferQueueLock); // // Emit all the queued buffers // for (unsigned int BufferIndex = BufferQueueHead; BufferIndex != INVALID_BUFFER_ID; BufferIndex = StreamBuffer[BufferIndex].NextIndex) { Status = ReleaseBuffer(BufferIndex); if (Status != ManifestorNoError) { MANIFESTOR_ERROR("Sub-class got cross when we tried to release a buffer - ignoring them\n"); } QueuedBufferCount--; if (StreamBuffer[BufferIndex].EventPending) ServiceEventQueue(BufferIndex); OutputRing->Insert((unsigned int) StreamBuffer[BufferIndex].Buffer); } BufferQueueHead = INVALID_BUFFER_ID; BufferQueueTail = ANY_BUFFER_ID; OS_UnLockMutex(&BufferQueueLock); return Manifestor_Base_c::ReleaseQueuedDecodeBuffers(); }
AllocatorStatus_t AllocatorSimple_c::Free(void) { int i; unsigned int LocalBufferSize; unsigned int MaxBlockSize; unsigned char *LocalOffset; OS_LockMutex(&Lock); memset(Blocks, 0x00, sizeof(Blocks)); LocalBufferSize = BufferSize; LocalOffset = NULL; MaxBlockSize = 0x4000000 - ((uintptr_t)PhysicalAddress & 0x03ffffff); HighestUsedBlockIndex = 0; for (i = 0; ((LocalBufferSize != 0) && (i < ALLOCATOR_SIMPLE_MAX_BLOCKS)); i++) { Blocks[i].InUse = true; Blocks[i].Size = min(LocalBufferSize, MaxBlockSize); Blocks[i].Base = LocalOffset; LocalBufferSize -= Blocks[i].Size; LocalOffset += Blocks[i].Size; MaxBlockSize = 0x4000000; HighestUsedBlockIndex = i; } OS_SetEvent(&EntryFreed); OS_UnLockMutex(&Lock); return AllocatorNoError; }
OS_Status_t OS_ResetEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = false; OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
BufferStatus_t BufferManager_Generic_c::CreatePool( BufferPool_t *Pool, BufferType_t Type, unsigned int NumberOfBuffers, unsigned int Size, void *MemoryPool[3], void *ArrayOfMemoryBlocks[][3], char *DeviceMemoryPartitionName) { BufferStatus_t Status; BufferDataDescriptor_t *Descriptor; BufferPool_Generic_t NewPool; // // Initialize the return parameter // *Pool = NULL; // // Get the descriptor // Status = GetDescriptor(Type, BufferDataTypeBase, &Descriptor); if (Status != BufferNoError) return Status; // // Perform simple parameter checks // if (Pool == NULL) { report(severity_error, "BufferManager_Generic_c::CreatePool - Null supplied as place to return Pool pointer.\n"); return BufferError; } if (Descriptor->AllocateOnPoolCreation && (NumberOfBuffers == NOT_SPECIFIED)) { report(severity_error, "BufferManager_Generic_c::CreatePool - Unable to allocate on creation, NumberOfBuffers not specified.\n"); return BufferParametersIncompatibleWithAllocationSource; } // // Perform the creation // NewPool = new BufferPool_Generic_c(this, Descriptor, NumberOfBuffers, Size, MemoryPool, ArrayOfMemoryBlocks, DeviceMemoryPartitionName); if ((NewPool == NULL) || (NewPool->InitializationStatus != BufferNoError)) { BufferStatus_t Status; Status = BufferInsufficientMemoryForPool; if (NewPool != NULL) Status = NewPool->InitializationStatus; report(severity_error, "BufferManager_Generic_c::CreatePool - Failed to create pool (%08x).\n", Status); return Status; } // // Insert the pool into our list // OS_LockMutex(&Lock); NewPool->Next = ListOfBufferPools; ListOfBufferPools = NewPool; OS_UnLockMutex(&Lock); // *Pool = NewPool; return BufferNoError; }
//////////////////////////////////////////////////////////////////////////// /// /// Populate the DecodeContext structure with parameters for MPEG audio. /// This can be over-ridden by WMA to not have any output buffer, as it will /// do an MME_SEND_BUFFERS instead of MME_TRANSFORM /// CodecStatus_t Codec_MmeAudio_c::FillOutDecodeContext(void) { CodecStatus_t Status; // // Obtain a new buffer if needed // if (CurrentDecodeBufferIndex == INVALID_INDEX) { Status = GetDecodeBuffer(); if (Status != CodecNoError) { report(severity_error, "Codec_MmeAudio_c::Input(%s) - Failed to get decode buffer.\n", Configuration.CodecName); ReleaseDecodeContext(DecodeContext); return Status; } } // // Record the buffer being used in the decode context // DecodeContext->BufferIndex = CurrentDecodeBufferIndex; // // Provide default values for the input and output buffers (the sub-class can change this if it wants to). // // Happily the audio firmware is less mad than the video firmware on the subject of buffers. // memset(&DecodeContext->MMECommand, 0x00, sizeof(MME_Command_t)); SetCommandIO(); OS_LockMutex(&Lock); DecodeContext->DecodeInProgress = true; BufferState[CurrentDecodeBufferIndex].DecodesInProgress++; BufferState[CurrentDecodeBufferIndex].OutputOnDecodesComplete = true; OS_UnLockMutex(&Lock); return CodecNoError; }
OS_Status_t OS_WaitForEvent(OS_Event_t *Event, OS_Timeout_t Timeout) { if (!((*Event)->Valid)) { OS_LockMutex(&((*Event)->Mutex)); if (!((*Event)->Valid)) // NOTE this may have changed before we locked access { OS_UnLockMutex(&((*Event)->Mutex)); OSDEV_WaitForQueue((*Event)->Queue, &((*Event)->Valid), (Timeout == OS_INFINITE) ? OSDEV_INFINITE : Timeout); return ((*Event)->Valid) ? OS_NO_ERROR : OS_TIMED_OUT; } else OS_UnLockMutex(&((*Event)->Mutex)); } return OS_NO_ERROR; }
DemultiplexorStatus_t Demultiplexor_Base_c::RemoveStream( DemultiplexorContext_t Context, unsigned int StreamIdentifier) { unsigned int i, j; DemultiplexorBaseContext_t BaseContext = (DemultiplexorBaseContext_t)Context; // report(severity_info, "Demultiplexor_Base_c::RemoveStream - %d.\n", StreamIdentifier); OS_LockMutex(&BaseContext->Lock); for (i = 0; i < DEMULTIPLEXOR_MAX_STREAMS; i++) if (BaseContext->Streams[i].Identifier == StreamIdentifier) { // // Scan, and if no other identifier (pid in ts) is injecting to the same stream // then we can detach the multiplexor from it. NOTE this means we will work if you // have multiple identifiers going to the same stream. // for (j = 0; j < DEMULTIPLEXOR_MAX_STREAMS; j++) if ((j != i) && (BaseContext->Streams[i].Stream == BaseContext->Streams[j].Stream)) break; if (j == DEMULTIPLEXOR_MAX_STREAMS) Player->DetachDemultiplexor(BaseContext->Streams[i].Stream); // // release and return. // BaseContext->Streams[i].Stream = NULL; BaseContext->Streams[i].Identifier = INVALID_INDEX; } // OS_UnLockMutex(&BaseContext->Lock); return DemultiplexorNoError; }
OS_Status_t OS_SetEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = true; OSDEV_WakeUpQueue((*Event)->Queue); OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
BufferStatus_t Buffer_Generic_c::DetachMetaData( MetaDataType_t Type ) { BlockDescriptor_t *LocationOfBlockPointer; BlockDescriptor_t Block; // // First find the descriptor block in the buffer // AssertNonZeroReferenceCount( "Buffer_Generic_c::DetachMetaData" ); OS_LockMutex( &Lock ); for( LocationOfBlockPointer = &ListOfMetaData; *LocationOfBlockPointer != NULL; LocationOfBlockPointer = &((*LocationOfBlockPointer)->Next) ) if( ((*LocationOfBlockPointer)->Descriptor->Type == Type) && !((*LocationOfBlockPointer)->AttachedToPool) ) break; if( *LocationOfBlockPointer == NULL ) { report( severity_error, "Buffer_Generic_c::DetachMetaData - No meta data of the specified type is attached to the buffer.\n" ); OS_UnLockMutex( &Lock ); return BufferMetaDataTypeNotFound; } // // Get a local block pointer, and unthread the block from the list // Block = *LocationOfBlockPointer; *LocationOfBlockPointer = Block->Next; // // Free up the memory, and delete the block record. // Pool->DeAllocateMemoryBlock( Block ); delete Block; // OS_UnLockMutex( &Lock ); return BufferNoError; }
OS_Status_t OS_ReInitializeEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = false; OSDEV_ReInitializeWaitQueue((*Event)->Queue); OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
AllocatorStatus_t AllocatorSimple_c::LargestFreeBlock(unsigned int *Size) { int Index; OS_LockMutex(&Lock); Index = LargestFreeBlock(); *Size = (Index < 0) ? 0 : Blocks[Index].Size; OS_UnLockMutex(&Lock); return AllocatorNoError; }
RingStatus_t RingGeneric_c::Flush( void ) { OS_LockMutex( &Lock ); NextExtract = 0; NextInsert = 0; OS_UnLockMutex( &Lock ); return RingNoError; }
void BufferManager_Generic_c::Dump(unsigned int Flags) { unsigned int i; BufferPool_Generic_t Pool; // if ((Flags & DumpBufferTypes) != 0) { report(severity_info, "Dump of Buffer Types\n"); for (i = 0; i < TypeDescriptorCount; i++) if ((TypeDescriptors[i].Type & TYPE_TYPE_MASK) == BufferDataTypeBase) { report(severity_info, " Buffer Type $%04x - '%s'\n", TypeDescriptors[i].Type, (TypeDescriptors[i].TypeName == NULL) ? "Unnamed" : TypeDescriptors[i].TypeName); report(severity_info, "\tAllocationSource = %s\n", (TypeDescriptors[i].AllocationSource <= AllocateIndividualSuppliedBlocks) ? AllocationSources[TypeDescriptors[i].AllocationSource] : "Invalid"); report(severity_info, "\tRequiredAllignment = %08x, AllocationUnitSize = %08x, AllocateOnPoolCreation = %d\n", TypeDescriptors[i].RequiredAllignment, TypeDescriptors[i].AllocationUnitSize, TypeDescriptors[i].AllocateOnPoolCreation); report(severity_info, "\tHasFixedSize = %d, FixedSize = %08x\n", TypeDescriptors[i].HasFixedSize, TypeDescriptors[i].FixedSize); } report(severity_info, "\n"); } // if ((Flags & DumpMetaDataTypes) != 0) { report(severity_info, "Dump of Meta Data Types\n"); for (i = 0; i < TypeDescriptorCount; i++) if ((TypeDescriptors[i].Type & TYPE_TYPE_MASK) == MetaDataTypeBase) { report(severity_info, " Buffer Type $%04x - '%s'\n", TypeDescriptors[i].Type, (TypeDescriptors[i].TypeName == NULL) ? "Unnamed" : TypeDescriptors[i].TypeName); report(severity_info, "\tAllocationSource = %s\n", (TypeDescriptors[i].AllocationSource <= AllocateIndividualSuppliedBlocks) ? AllocationSources[TypeDescriptors[i].AllocationSource] : "Invalid"); report(severity_info, "\tRequiredAllignment = %08x, AllocationUnitSize = %08x, AllocateOnPoolCreation = %d\n", TypeDescriptors[i].RequiredAllignment, TypeDescriptors[i].AllocationUnitSize, TypeDescriptors[i].AllocateOnPoolCreation); report(severity_info, "\tHasFixedSize = %d, FixedSize = %08x\n", TypeDescriptors[i].HasFixedSize, TypeDescriptors[i].FixedSize); } report(severity_info, "\n"); } // if ((Flags & DumpListPools) != 0) { report(severity_info, "Dump of Buffer Pools\n"); OS_LockMutex(&Lock); for (Pool = ListOfBufferPools; Pool != NULL; Pool = Pool->Next) { Pool->Dump(Flags); } OS_UnLockMutex(&Lock); } }
//////////////////////////////////////////////////////////////////////////// /// /// Push a previously dequeued buffer back to the head of the buffer queue. /// /// Must be called only from the mixer playback thread. /// /// \param BufferIndex Index of the previously dequeued buffer. /// void Manifestor_Audio_c::PushBackBuffer(unsigned int BufferIndex) { OS_LockMutex(&BufferQueueLock); StreamBuffer[BufferIndex].NextIndex = BufferQueueHead; if (BufferQueueHead == INVALID_BUFFER_ID) BufferQueueTail = BufferIndex; BufferQueueHead = BufferIndex; QueuedBufferCount++; NotQueuedBufferCount--; OS_UnLockMutex(&BufferQueueLock); }
BufferStatus_t Buffer_Generic_c::DetachBuffer( Buffer_t Buffer ) { unsigned int i; // AssertNonZeroReferenceCount( "Buffer_Generic_c::DetachBuffer" ); OS_LockMutex( &Lock ); for( i=0; i<MAX_ATTACHED_BUFFERS; i++ ) if( AttachedBuffers[i] == Buffer ) { AttachedBuffers[i] = NULL; OS_UnLockMutex( &Lock ); Buffer->DecrementReferenceCount( IdentifierAttachedToOtherBuffer ); return BufferNoError; } report( severity_error, "Buffer_Generic_c::DetachBuffer - Attached buffer not found.\n" ); OS_UnLockMutex( &Lock ); return BufferAttachmentNotFound; }
BufferStatus_t Buffer_Generic_c::AttachBuffer( Buffer_t Buffer ) { unsigned int i; // AssertNonZeroReferenceCount( "Buffer_Generic_c::AttachBuffer" ); OS_LockMutex( &Lock ); for( i=0; i<MAX_ATTACHED_BUFFERS; i++ ) if( AttachedBuffers[i] == NULL ) { AttachedBuffers[i] = Buffer; OS_UnLockMutex( &Lock ); Buffer->IncrementReferenceCount(); return BufferNoError; } report( severity_error, "Buffer_Generic_c::AttachBuffer - Too many buffers attached to this one.\n" ); OS_UnLockMutex( &Lock ); return BufferTooManyAttachments; }
AllocatorStatus_t AllocatorSimple_c::AllocateLargest( unsigned int *Size, unsigned char **Block, bool NonBlocking) { int Index; // if (this == NULL) return AllocatorError; // InAllocate = true; do { OS_LockMutex(&Lock); OS_ResetEvent(&EntryFreed); // if (BeingDeleted) break; // Index = LargestFreeBlock(); if ((Index >= 0) && (Blocks[Index].Size >= (*Size))) { *Size = Blocks[Index].Size; *Block = Blocks[Index].Base; Blocks[Index].Size = 0; Blocks[Index].InUse = false; OS_UnLockMutex(&Lock); InAllocate = false; return AllocatorNoError; } OS_UnLockMutex(&Lock); if (!NonBlocking) OS_WaitForEvent(&EntryFreed, OS_INFINITE); } while (!NonBlocking && !BeingDeleted); InAllocate = false; return AllocatorUnableToAllocate; }
BufferStatus_t Buffer_Generic_c::ObtainMetaDataReference( MetaDataType_t Type, void **Pointer ) { BlockDescriptor_t Block; // // Find the descriptor block // AssertNonZeroReferenceCount( "Buffer_Generic_c::ObtainMetaDataReference " ); OS_LockMutex( &Lock ); for( Block = ListOfMetaData; Block != NULL; Block = Block->Next ) if( Block->Descriptor->Type == Type ) break; if( Block == NULL ) { report( severity_error, "Buffer_Generic_c::ObtainMetaDataReference - No meta data of the specified type is attached to the buffer.\n" ); OS_UnLockMutex( &Lock ); return BufferMetaDataTypeNotFound; } // // Return the appropriate value // *Pointer = Block->Address[CachedAddress]; OS_UnLockMutex( &Lock ); // return BufferNoError; }
StackStatus_t StackGeneric_c::Pop(unsigned int *Value) { // // If there is nothing in the Stack we return // if (Level != 0) { OS_LockMutex(&Lock); *Value = Storage[--Level]; OS_UnLockMutex(&Lock); return StackNoError; } return StackNothingToGet; }