gceSTATUS vgsMEMORYMANAGER_Construct( IN gcoOS Os, IN gctUINT ItemSize, IN gctUINT Granularity, OUT vgsMEMORYMANAGER_PTR * Manager ) { gceSTATUS status; vgsMEMORYMANAGER_PTR manager = gcvNULL; gcmHEADER_ARG("Os=0x%x ItemSize=0x%x Granularity=0x%x Manager=0x%x", Os, ItemSize, Granularity, Manager); gcmVERIFY_ARGUMENT(ItemSize > 0); gcmVERIFY_ARGUMENT(Granularity > 0); gcmVERIFY_ARGUMENT(Manager != gcvNULL); do { gctUINT itemSize; gctUINT allocationSize; /* Allocate the memory manager structure. */ gcmERR_BREAK(gcoOS_Allocate( Os, gcmSIZEOF(vgsMEMORYMANAGER), (gctPOINTER *) &manager )); /* Determine the size of the item. */ itemSize = gcmSIZEOF(vgsMEMORYITEM) + ItemSize; /* Determine the allocation size. */ allocationSize = gcmSIZEOF(vgsMEMORYITEM) + Granularity * itemSize; /* Initialize the structure. */ manager->os = Os; manager->allocationSize = allocationSize; manager->itemCount = Granularity; manager->itemSize = itemSize; manager->firstAllocated = gcvNULL; manager->firstFree = gcvNULL; #if vgvVALIDATE_MEMORY_MANAGER manager->allocatedCount = 0; manager->maximumAllocated = 0; manager->allocatedBufferCount = 0; #endif /* Set the result pointer. */ * Manager = manager; } while (gcvNULL); gcmFOOTER(); /* Return status. */ return status; }
/******************************************************************************* ** ** gcoDUMP_DumpData ** ** Dump data the file. ** ** INPUT: ** ** gcoDUMP Dump ** Pointer to a gcoDUMP object. ** ** gceDUMP_TAG Type ** Type of data. ** ** gctUINT32 Address ** Physical address to be used as a handle for the data. ** ** gctSIZE_T ByteCount ** Number of bytes to write. ** ** gctCONST_POINTER Data ** Pointer to the data to write. ** ** OUTPUT: ** ** Nothing. */ gceSTATUS gcoDUMP_DumpData( IN gcoDUMP Dump, IN gceDUMP_TAG Type, IN gctUINT32 Address, IN gctSIZE_T ByteCount, IN gctCONST_POINTER Data ) { gceSTATUS status; gcsDUMP_DATA header; gcmHEADER_ARG("Dump=0x%x Type=%d Address=%x ByteCount=%d Data=0x%x", Dump, Type, Address, ByteCount, Data); /* Verify the arguments. */ gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP); gcmVERIFY_ARGUMENT(ByteCount > 0); gcmVERIFY_ARGUMENT(Data != gcvNULL); if (Dump->file == gcvNULL) { /* There is no open dump file. */ gcmFOOTER_NO(); return gcvSTATUS_OK; } do { /* Write the data record. */ header.type = Type; header.length = ByteCount; header.address = Address; gcmERR_BREAK( gcoOS_Write(gcvNULL, Dump->file, sizeof(header), &header)); /* Write the data. */ gcmERR_BREAK(gcoOS_Write(gcvNULL, Dump->file, ByteCount, Data)); /* Update the frame length. */ Dump->frameLength += sizeof(header) + ByteCount; /* Update the file length. */ Dump->length += sizeof(header) + ByteCount; } while (gcvFALSE); /* Return the status. */ gcmFOOTER(); return status; }
/******************************************************************************* ** ** gcoDUMP_AddSurface ** ** Allocate a surface. ** ** INPUT: ** ** gcoDUMP Dump ** Pointer to a gcoDUMP object. ** ** gctINT32 Width, Height ** Width and height of the surface. ** ** gceSURF_FORMAT PixelFormat ** Pixel format for the surface. ** ** gctUINT32 Address ** Physical address to be used as a handle for the surface. ** ** gctSIZE_T ByteCount ** Number of bytes inside the surface. ** ** OUTPUT: ** ** Nothing. */ gceSTATUS gcoDUMP_AddSurface( IN gcoDUMP Dump, IN gctINT32 Width, IN gctINT32 Height, IN gceSURF_FORMAT PixelFormat, IN gctUINT32 Address, IN gctSIZE_T ByteCount ) { gceSTATUS status; gcsDUMP_SURFACE surface; gcmHEADER_ARG("Dump=0x%x Width=%d Height=%d PixelFormat=%d Address=%x " "ByteCount=%d", Dump, Width, Height, PixelFormat, Address, ByteCount); /* Verify the arguments. */ gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP); gcmVERIFY_ARGUMENT(ByteCount > 0); if (Dump->file == gcvNULL) { /* There is no open dump file. */ gcmFOOTER_NO(); return gcvSTATUS_OK; } do { /* Write the data record. */ surface.type = gcvTAG_SURFACE; surface.address = Address; surface.width = (gctINT16) Width; surface.height = (gctINT16) Height; surface.format = PixelFormat; surface.length = ByteCount; gcmERR_BREAK( gcoOS_Write(gcvNULL, Dump->file, sizeof(surface), &surface)); /* Update the frame length. */ Dump->frameLength += sizeof(surface); /* Update the file length. */ Dump->length += sizeof(surface); } while (gcvFALSE); /* Return the status. */ gcmFOOTER(); return status; }
gceSTATUS vgsMEMORYMANAGER_Destroy( IN vgsMEMORYMANAGER_PTR Manager ) { gceSTATUS status; vgsMEMORYITEM_PTR current; vgsMEMORYITEM_PTR next; gcmHEADER_ARG("Manager=0x%x", Manager); /* Verify arguments. */ gcmVERIFY_ARGUMENT(Manager != gcvNULL); /* Assume success. */ status = gcvSTATUS_OK; /* Everything has to be freed. */ #if vgvVALIDATE_MEMORY_MANAGER gcmASSERT(Manager->allocatedCount == 0); #endif /* Destroy all allocated buffers. */ while (Manager->firstAllocated) { /* Get the current buffer. */ current = Manager->firstAllocated; /* Get the next buffer. */ next = current->next; /* Free the current. */ gcmERR_BREAK(gcoOS_Free(Manager->os, current)); /* Advance to the next one. */ Manager->firstAllocated = next; } /* Success? */ if (gcmIS_SUCCESS(status)) { status = gcoOS_Free(Manager->os, Manager); } gcmFOOTER(); /* Return status. */ return status; }
/******************************************************************************* ** ** gcoDUMP_IsEnabled ** ** Test whether dumping is enabeld or not. ** ** INPUT: ** ** gcoDUMP Dump ** Pointer to a gcoDUMP object. ** ** OUTPUT: ** ** gctBOOL * Enabled ** Pointer to a variable receiving the dump status. */ gceSTATUS gcoDUMP_IsEnabled( IN gcoDUMP Dump, OUT gctBOOL * Enabled ) { gcmHEADER_ARG("Dump=0x%x Enabled=0x%x", Dump, Enabled); /* Verify the arguments. */ gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP); gcmVERIFY_ARGUMENT(Enabled != gcvNULL); /* Return dump status. */ *Enabled = (Dump->file != gcvNULL); /* Success. */ gcmFOOTER_ARG("*Enabled=%d", *Enabled); return gcvSTATUS_OK; }
/******************************************************************************* ** ** gcoDUMP_Construct ** ** Construct a new gcoDUMP object. ** ** INPUT: ** ** gcoOS Os ** Pointer to an gcoOS object. ** ** gcoOS Hal ** Pointer to an gcoHAL object. ** ** OUTPUT: ** ** gcoDUMP * Dump ** Pointer to a variable receiving the gcoDUMP object pointer. */ gceSTATUS gcoDUMP_Construct( IN gcoOS Os, IN gcoHAL Hal, OUT gcoDUMP * Dump ) { gceSTATUS status; gcoDUMP dump; gctPOINTER pointer = gcvNULL; gcmHEADER_ARG("Os=0x%x Dump=0x%x", Os, Dump); /* Verify the arguments. */ gcmVERIFY_ARGUMENT(Dump != gcvNULL); do { /* Allocate the gcoDUMP structure. */ gcmERR_BREAK(gcoOS_Allocate(Os, sizeof(struct _gcoDUMP), &pointer)); dump = pointer; /* Initialize the gcoDUMP object. */ dump->object.type = gcvOBJ_DUMP; dump->file = gcvNULL; /* Return pointer to the object. */ *Dump = dump; } while (gcvFALSE); /* Return the status. */ gcmFOOTER_ARG("*Dump=0x%x", *Dump); return status; }
gceSTATUS gcoQUEUE_Construct( IN gcoOS Os, OUT gcoQUEUE * Queue ) { gcoQUEUE queue = gcvNULL; gceSTATUS status; #ifdef __QNXNTO__ gctSIZE_T allocationSize; gctPHYS_ADDR physAddr; #endif gctPOINTER pointer = gcvNULL; gcmHEADER(); /* Verify the arguments. */ gcmVERIFY_ARGUMENT(Queue != gcvNULL); /* Create the queue. */ gcmONERROR( gcoOS_Allocate(gcvNULL, gcmSIZEOF(struct _gcoQUEUE), &pointer)); queue = pointer; /* Initialize the object. */ queue->object.type = gcvOBJ_QUEUE; /* Nothing in the queue yet. */ queue->head = queue->tail = gcvNULL; queue->recordCount = 0; #ifdef __QNXNTO__ /* Allocate buffer of records. */ allocationSize = BUFFER_SIZE; physAddr = 0; gcmONERROR( gcoOS_AllocateNonPagedMemory(gcvNULL, gcvTRUE, &allocationSize, &physAddr, (gctPOINTER *) &queue->records)); queue->freeBytes = allocationSize; queue->offset = 0; #else queue->freeList = gcvNULL; #endif /* Return gcoQUEUE pointer. */ *Queue = queue; /* Success. */ gcmFOOTER_ARG("*Queue=0x%x", *Queue); return gcvSTATUS_OK; OnError: if (queue != gcvNULL) { /* Roll back. */ gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, queue)); } /* Return the status. */ gcmFOOTER(); return status; }
gceSTATUS gcoQUEUE_AppendEvent( IN gcoQUEUE Queue, IN gcsHAL_INTERFACE * Interface ) { gceSTATUS status; gcsQUEUE_PTR record = gcvNULL; #ifdef __QNXNTO__ gctSIZE_T allocationSize; gctPHYS_ADDR physAddr; #else gctPOINTER pointer = gcvNULL; #endif gcmHEADER_ARG("Queue=0x%x Interface=0x%x", Queue, Interface); /* Verify the arguments. */ gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE); gcmVERIFY_ARGUMENT(Interface != gcvNULL); /* Allocate record. */ #ifdef __QNXNTO__ allocationSize = gcmSIZEOF(gcsQUEUE); if (Queue->freeBytes < allocationSize) { gctSIZE_T recordsSize = BUFFER_SIZE; gcsQUEUE_PTR prevRecords = Queue->records; gcsHAL_INTERFACE iface; /* Allocate new set of records. */ gcmONERROR( gcoOS_AllocateNonPagedMemory(gcvNULL, gcvTRUE, &recordsSize, &physAddr, (gctPOINTER *) &Queue->records)); Queue->freeBytes = recordsSize; Queue->offset = 0; if ( Queue->freeBytes < allocationSize ) { gcmFOOTER_ARG("status=%d", gcvSTATUS_DATA_TOO_LARGE); return gcvSTATUS_DATA_TOO_LARGE; } /* Schedule to free Queue->records, * hence not unmapping currently scheduled events immediately. */ iface.command = gcvHAL_FREE_NON_PAGED_MEMORY; iface.u.FreeNonPagedMemory.bytes = BUFFER_SIZE; iface.u.FreeNonPagedMemory.physical = 0; iface.u.FreeNonPagedMemory.logical = prevRecords; gcmONERROR( gcoQUEUE_AppendEvent(Queue, &iface)); } record = (gcsQUEUE_PTR)((gctUINT32)Queue->records + Queue->offset); Queue->offset += allocationSize; Queue->freeBytes -= allocationSize; #else /* Check if we have records on the free list. */ if (Queue->freeList != gcvNULL) { /* Allocate from hte free list. */ record = Queue->freeList; Queue->freeList = record->next; } else { gcmONERROR(gcoOS_Allocate(gcvNULL, gcmSIZEOF(gcsQUEUE), &pointer)); record = pointer; } #endif /* Initialize record. */ record->next = gcvNULL; gcoOS_MemCopy(&record->iface, Interface, gcmSIZEOF(record->iface)); if (Queue->head == gcvNULL) { /* Initialize queue. */ Queue->head = record; } else { /* Append record to end of queue. */ Queue->tail->next = record; } /* Mark end of queue. */ Queue->tail = record; /* update count */ Queue->recordCount++; /* Success. */ gcmFOOTER_NO(); return gcvSTATUS_OK; OnError: #ifndef __QNXNTO__ if (pointer != gcvNULL) { /* Put record on free list. */ record->next = Queue->freeList; Queue->freeList = record; } #endif /* Return the status. */ gcmFOOTER(); return status; }
gceSTATUS vgsMEMORYMANAGER_Allocate( IN vgsMEMORYMANAGER_PTR Manager, OUT gctPOINTER * Pointer ) { gceSTATUS status; vgsMEMORYITEM_PTR firstFree; gcmHEADER_ARG("Manager=0x%x Pointer=0x%x", Manager, Pointer); /* Verify arguments. */ gcmVERIFY_ARGUMENT(Manager != gcvNULL); gcmVERIFY_ARGUMENT(Pointer != gcvNULL); /* Get the first free. */ firstFree = Manager->firstFree; /* Are there free items? */ if (firstFree != gcvNULL) { /* Set the result. */ * Pointer = firstFree + 1; /* Remove from the free list. */ Manager->firstFree = firstFree->next; /* Update allocated items count. */ #if vgvVALIDATE_MEMORY_MANAGER Manager->allocatedCount += 1; if ((gctUINT) Manager->allocatedCount > Manager->maximumAllocated) { Manager->maximumAllocated = Manager->allocatedCount; } #endif /* Success. */ gcmFOOTER_ARG("*Pointer=0x%x", *Pointer); return gcvSTATUS_OK; } /* No free items available. */ do { vgsMEMORYITEM_PTR newBuffer; gctUINT i, itemCount; gctUINT itemSize; /* Allocate a new buffer. */ gcmERR_BREAK(gcoOS_Allocate( Manager->os, Manager->allocationSize, (gctPOINTER) &newBuffer )); /* Link in. */ newBuffer->next = Manager->firstAllocated; Manager->firstAllocated = newBuffer; /* Set the result. */ * Pointer = newBuffer + 2; /* Update allocated items count. */ #if vgvVALIDATE_MEMORY_MANAGER Manager->allocatedCount += 1; Manager->allocatedBufferCount += 1; if ((gctUINT) Manager->allocatedCount > Manager->maximumAllocated) { Manager->maximumAllocated = Manager->allocatedCount; } #endif /* Get the number of items per allocation. */ itemCount = Manager->itemCount; /* Get the item size. */ itemSize = Manager->itemSize; /* Determine the first free item. */ firstFree = (vgsMEMORYITEM_PTR) ( (gctUINT8_PTR) (newBuffer + 1) + itemSize ); /* Populate the new buffer. */ for (i = 1; i < itemCount; i++) { /* Add to the free item list. */ firstFree->next = Manager->firstFree; Manager->firstFree = firstFree; /* Advance to the next item. */ firstFree = (vgsMEMORYITEM_PTR) ( (gctUINT8_PTR) firstFree + itemSize ); } } while (gcvFALSE); gcmFOOTER(); /* Return status. */ return status; }