VOID MmInitializeHeap(PVOID PageLookupTable) { ULONG PagesNeeded; ULONG HeapStart; #ifndef _M_ARM MEMORY_TYPE Type; PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable; // HACK: Make it so it doesn't overlap kernel space Type = RealPageLookupTable[0x100].PageAllocated; MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, LoaderSystemCode); #endif // Find contigious memory block for HEAP:STACK PagesNeeded = HEAP_PAGES + STACK_PAGES; HeapStart = MmFindAvailablePages(PageLookupTable, TotalPagesInLookupTable, PagesNeeded, FALSE); #ifndef _M_ARM // Unapply the hack MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, Type); #endif if (HeapStart == 0) { UiMessageBox("Critical error: Can't allocate heap!"); return; } // Initialize BGET bpool(HeapStart << MM_PAGE_SHIFT, PagesNeeded << MM_PAGE_SHIFT); // Mark those pages as used MmMarkPagesInLookupTable(PageLookupTableAddress, HeapStart, PagesNeeded, LoaderOsloaderHeap); TRACE("Heap initialized, base 0x%08x, pages %d\n", (HeapStart << MM_PAGE_SHIFT), PagesNeeded); }
void cmsMem_initSharedMem(void *addr, UINT32 len) { mStats.shmAllocStart = (UINT32) addr; mStats.shmAllocEnd = mStats.shmAllocStart + len; mStats.shmTotalBytes = len; cmsLog_notice("shm pool: %p-%p", mStats.shmAllocStart, mStats.shmAllocEnd); bpool(addr, len); }
/* BufferPoolCreate * Creates a new buffer-pool from the given buffer object. * This allows sub-allocations from a buffer-object. */ OsStatus_t BufferPoolCreate( _In_ DmaBuffer_t* Buffer, _Out_ BufferPool_t** Pool) { // Allocate the pool *Pool = (BufferPool_t*)malloc(sizeof(BufferPool_t)); (*Pool)->Buffer = Buffer; return bpool((void*)GetBufferDataPointer(Buffer), GetBufferSize(Buffer), &(*Pool)->Pool); }
/* initializer of zlib (replaces glibc prologue) */ static void _init() { /* setup memory manager */ bpool(MANIFEST->heap_ptr, MANIFEST->heap_size); }
//***************************************************************************** // // The program main function. It performs initialization, then handles wav // file playback. // //***************************************************************************** int main(void) { int nStatus; // // Set the system clock to run at 80MHz from the PLL. // ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // // Give bget some memory to work with. // bpool(g_pulHeap, sizeof(g_pulHeap)); // // Set the device pin out appropriately for this board. // PinoutSet(); // // Configure the relevant pins such that UART0 owns them. // ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Open the UART for I/O // UARTStdioInit(0); UARTprintf("i2s_speex_enc\n"); // // Configure and enable uDMA // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlDelay(10); ROM_uDMAControlBaseSet(&sDMAControlTable[0]); ROM_uDMAEnable(); // // Enable Interrupts // ROM_IntMasterEnable(); // // Configure the I2S peripheral. // SoundInit(1); // // Set the format of the play back in the sound driver. // SoundSetFormat(AUDIO_RATE, AUDIO_BITS, AUDIO_CHANNELS); // // Print out some header information to the serial console. // UARTprintf("\ni2s_speex_enc Stellaris Example\n"); UARTprintf("Streaming at %d %d bit ",SoundSampleRateGet(), AUDIO_BITS); if(AUDIO_CHANNELS == 2) { UARTprintf("Stereo\n"); } else { UARTprintf("Mono\n"); } // // Set the initial volume. // SoundVolumeSet(INITIAL_VOLUME_PERCENT); // // Initialize the Speex decoder. // SpeexDecodeInit(); // // Set the default quality to 2. // g_iQuality = 2; // // Initialize the Speex encoder to Complexity of 1 and Quality 2. // SpeexEncodeInit(AUDIO_RATE, 1, g_iQuality); // // Initialize the audio buffers. // InitBuffers(); // // Initialize the applications global state flags. // g_ulFlags = 0; // // Kick off a request for a buffer play back and advance the encoder // pointer. // SoundBufferRead(g_pucRecBuffer, RECORD_BUFFER_INC, RecordBufferCallback); g_pucEncode += RECORD_BUFFER_INC; // // Kick off a second request for a buffer play back and advance the encode // pointer. // SoundBufferRead(&g_pucRecBuffer[RECORD_BUFFER_INC], RECORD_BUFFER_INC, RecordBufferCallback); g_pucEncode += RECORD_BUFFER_INC; // // The rest of the handling occurs at interrupt time so the main loop will // simply stall here. // while(1) { // // Print a prompt to the console. Show the CWD. // UARTprintf("\n> "); // // Get a line of text from the user. // UARTgets(g_cCmdBuf, sizeof(g_cCmdBuf)); // // Pass the line from the user to the command processor. // It will be parsed and valid commands executed. // nStatus = CmdLineProcess(g_cCmdBuf); // // Handle the case of bad command. // if(nStatus == CMDLINE_BAD_CMD) { UARTprintf("Bad command!\n"); } // // Handle the case of too many arguments. // else if(nStatus == CMDLINE_TOO_MANY_ARGS) { UARTprintf("Too many arguments for command processor!\n"); } // // Otherwise the command was executed. Print the error // code if one was returned. // else if(nStatus != 0) { UARTprintf("Command returned error code \n"); } } }
// Create default_methods list for the current class. // With the VM only processing erased signatures, the VM only // creates an overpass in a conflict case or a case with no candidates. // This allows virtual methods to override the overpass, but ensures // that a local method search will find the exception rather than an abstract // or default method that is not a valid candidate. static void create_defaults_and_exceptions( GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS) { GrowableArray<Method*> overpasses; GrowableArray<Method*> defaults; BytecodeConstantPool bpool(klass->constants()); for (int i = 0; i < slots->length(); ++i) { EmptyVtableSlot* slot = slots->at(i); if (slot->is_bound()) { MethodFamily* method = slot->get_binding(); BytecodeBuffer buffer; #ifndef PRODUCT if (TraceDefaultMethods) { tty->print("for slot: "); slot->print_on(tty); tty->cr(); if (method->has_target()) { method->print_selected(tty, 1); } else if (method->throws_exception()) { method->print_exception(tty, 1); } } #endif // ndef PRODUCT if (method->has_target()) { Method* selected = method->get_selected_target(); if (selected->method_holder()->is_interface()) { defaults.push(selected); } } else if (method->throws_exception()) { int max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK); AccessFlags flags = accessFlags_from( JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), flags, max_stack, slot->size_of_parameters(), ConstMethod::OVERPASS, CHECK); // We push to the methods list: // overpass methods which are exception throwing methods if (m != NULL) { overpasses.push(m); } } } } #ifndef PRODUCT if (TraceDefaultMethods) { tty->print_cr("Created %d overpass methods", overpasses.length()); tty->print_cr("Created %d default methods", defaults.length()); } #endif // ndef PRODUCT if (overpasses.length() > 0) { switchover_constant_pool(&bpool, klass, &overpasses, CHECK); merge_in_new_methods(klass, &overpasses, CHECK); } if (defaults.length() > 0) { create_default_methods(klass, &defaults, CHECK); } }
//***************************************************************************** // // Play the Colossal Cave Adventure game using either an Ethernet telnet // connection or a USB CDC serial connection. // //***************************************************************************** int main(void) { // // Set the clocking to run from the PLL at 80 MHz. // ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // // Enable the UART. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioInit(0); // // Print out a greeting. // UARTprintf("\033[2JColossal Cave Adventure\n"); UARTprintf("-----------------------\n"); UARTprintf("Connect to either the USB virtual COM port or\n"); UARTprintf("telnet into the Ethernet port in order to play.\n\n"); // // Enable the GPIO that is used for the on-board push button. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_4); ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); // // Enable the GPIO that is used for the on-board LED. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); // // Configure SysTick for a periodic interrupt. // ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKHZ); ROM_SysTickEnable(); ROM_SysTickIntEnable(); // // Enable processor interrupts. // ROM_IntMasterEnable(); // // Initialize the Ethernet and USB interfaces. // EnetIFInit(); USBIFInit(); // // Provide a working area to the memory allocator. // bpool(g_pucPool, sizeof(g_pucPool)); // // Configure the Z-machine interpreter. // configure(V1, V5); // // Initialize the Z-machine screen interface. // initialize_screen(); // // Pre-fill the Z-machine interpreter's cache. // load_cache(); // // Loop forever. // while(1) { // // Wait until a connection has been made via either the Ethernet or USB // interfaces. // while(g_ulGameIF == GAME_IF_NONE) { } // // Turn on the LED to indicate that the game is in progress. // ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0); // // Loop until the game has been exited. Repeat this loop if the game // exited because the restart button was pressed. // do { // // Take the Z-machine interpreter out of the halt state. // halt = 0; // // Set the restart flag to zero. // g_ulRestart = 0; // // Restart the Z-machine interpreter. // restart(); // // Run the Z-machine interpreter until it halts. // interpret(); } while(g_ulRestart); // // Turn off the LED to indicate that the game has finished. // ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); // // Close down the Ethernet connection if it was being used to play the // game. // if(g_ulGameIF == GAME_IF_ENET) { EnetIFClose(); } // // Forget the interface used to play the game so that the selection // process will be repeated. // g_ulGameIF = GAME_IF_NONE; } }
//***************************************************************************** // //! Initializes the SDRAM. //! //! \param ulEPIDivider is the EPI clock divider to use. //! \param ulConfig is the SDRAM interface configuration. //! \param ulRefresh is the refresh count in core clocks (0-2047). //! //! This function must be called prior to ExtRAMAlloc() or ExtRAMFree(). It //! configures the Stellaris microcontroller EPI block for SDRAM access and //! initializes the SDRAM heap (if SDRAM is found). The parameter \e ulConfig //! is the logical OR of several sets of choices: //! //! The processor core frequency must be specified with one of the following: //! //! - \b EPI_SDRAM_CORE_FREQ_0_15 - core clock is 0 MHz < clk <= 15 MHz //! - \b EPI_SDRAM_CORE_FREQ_15_30 - core clock is 15 MHz < clk <= 30 MHz //! - \b EPI_SDRAM_CORE_FREQ_30_50 - core clock is 30 MHz < clk <= 50 MHz //! - \b EPI_SDRAM_CORE_FREQ_50_100 - core clock is 50 MHz < clk <= 100 MHz //! //! The low power mode is specified with one of the following: //! //! - \b EPI_SDRAM_LOW_POWER - enter low power, self-refresh state //! - \b EPI_SDRAM_FULL_POWER - normal operating state //! //! The SDRAM device size is specified with one of the following: //! //! - \b EPI_SDRAM_SIZE_64MBIT - 64 Mbit device (8 MB) //! - \b EPI_SDRAM_SIZE_128MBIT - 128 Mbit device (16 MB) //! - \b EPI_SDRAM_SIZE_256MBIT - 256 Mbit device (32 MB) //! - \b EPI_SDRAM_SIZE_512MBIT - 512 Mbit device (64 MB) //! //! The parameter \e ulRefresh sets the refresh counter in units of core //! clock ticks. It is an 11-bit value with a range of 0 - 2047 counts. //! //! \return Returns \b true on success of \b false if no SDRAM is found or //! any other error occurs. // //***************************************************************************** tBoolean SDRAMInit(unsigned long ulEPIDivider, unsigned long ulConfig, unsigned long ulRefresh) { // // Enable the EPI peripheral // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0); // // Configure the GPIO for communication with SDRAM. // #ifdef EPI_PORTA_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_GPIOPadConfigSet(GPIO_PORTA_BASE, EPI_PORTA_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTA_BASE, EPI_PORTA_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_GPIOB_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, EPI_GPIOB_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTB_BASE, EPI_GPIOB_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTC_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); ROM_GPIOPadConfigSet(GPIO_PORTC_BASE, EPI_PORTC_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTC_BASE, EPI_PORTC_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTD_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, EPI_PORTD_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTD_BASE, EPI_PORTD_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTE_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); ROM_GPIOPadConfigSet(GPIO_PORTE_BASE, EPI_PORTE_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTE_BASE, EPI_PORTE_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTF_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_GPIOPadConfigSet(GPIO_PORTF_BASE, EPI_PORTF_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTF_BASE, EPI_PORTF_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTG_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); ROM_GPIOPadConfigSet(GPIO_PORTG_BASE, EPI_PORTG_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTG_BASE, EPI_PORTG_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTH_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); ROM_GPIOPadConfigSet(GPIO_PORTH_BASE, EPI_PORTH_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTH_BASE, EPI_PORTH_PINS, GPIO_DIR_MODE_HW); #endif #ifdef EPI_PORTJ_PINS ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); ROM_GPIOPadConfigSet(GPIO_PORTJ_BASE, EPI_PORTJ_PINS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIODirModeSet(GPIO_PORTJ_BASE, EPI_PORTJ_PINS, GPIO_DIR_MODE_HW); #endif #if defined(EPI_CLK_PORT) && defined(EPI_CLK_PIN) ROM_GPIOPadConfigSet(EPI_CLK_PORT, EPI_CLK_PIN, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU); #endif // // Set the EPI divider. // EPIDividerSet(EPI0_BASE, ulEPIDivider); // // Select SDRAM mode. // EPIModeSet(EPI0_BASE, EPI_MODE_SDRAM); // // Configure SDRAM mode. // EPIConfigSDRAMSet(EPI0_BASE, ulConfig, ulRefresh); // // Set the address map. // EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_256MB | EPI_ADDR_RAM_BASE_6); // // Set the EPI mem pointer to the base of EPI mem // g_pusEPIMem = (unsigned short *)0x60000000; // // Wait for the EPI initialization to complete. // while(HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ) { // // Wait for SDRAM initialization to complete. // } // // At this point, the SDRAM should be accessible. We attempt a couple // of writes then read back the memory to see if it seems to be there. // g_pusEPIMem[0] = 0xABCD; g_pusEPIMem[1] = 0x5AA5; // // Read back the patterns we just wrote to make sure they are valid. Note // that we declared g_pusEPIMem as volatile so the compiler should not // optimize these reads out of the image. // if((g_pusEPIMem[0] == 0xABCD) && (g_pusEPIMem[1] == 0x5AA5)) { // // The memory appears to be there so remember that we found it. // g_bSDRAMPresent = true; // // Now set up the heap that ExtRAMAlloc() and ExtRAMFree() will use. // bpool((void *)g_pusEPIMem, SDRAM_SIZE_BYTES); } // // If we get this far, the SDRAM heap has been successfully initialized. // return(g_bSDRAMPresent); }
void *bget(bufsize requested_size) { uint32_t size = (uint32_t)requested_size; struct bfhead *b; #ifdef BestFit struct bfhead *best; #endif void *buf = NULL; #ifdef BECtl int32_t compactseq = 0; int8_t acquireLoop = 1; /* boolean used for first while loop control */ int8_t BECtlLoop = 1; /* boolean used for second while loop control */ #endif int32_t compfcnResult = 0; /* used to store compfcn call result */ int32_t foundBuffer = 0; /* Boolean indicating if we found a buffer. */ /* It is used to avoid multiple calls to return, */ /* which is not MISRA compliant */ #ifdef BECtl /* If an acquire function was provided in the call to bectl(), wrap a loop around the allocation process to allow acquire to intervene in case we don't find a suitable buffer in the chain. */ while (acquireLoop != 0) { acquireLoop = 0; #endif assert(size > 0); if (size < SizeQ) { /* Need at least room for the */ size = SizeQ; /* queue links. */ } #ifdef SizeQuant #if SizeQuant > 1 size = (size + ((uint32_t)SizeQuant - 1)) & (~((uint32_t)SizeQuant - 1)); #endif #endif size += sizeof(struct bhead); /* Add overhead in allocated buffer to size required. */ #ifdef BECtl /* If a compact function was provided in the call to bectl(), wrap a loop around the allocation process to allow compaction to intervene in case we don't find a suitable buffer in the chain. */ while (BECtlLoop != 0) { #endif b = freelist.ql.flink; #ifdef BestFit best = &freelist; #endif /* Scan the free list searching for the first buffer big enough to hold the requested size buffer. */ #ifdef BestFit while (b != &freelist) { if (b->bh.bsize >= (int32_t)size) { if ((best == &freelist) || (b->bh.bsize < best->bh.bsize)) { best = b; } } b = b->ql.flink; /* Link to next buffer */ } b = best; #endif /* BestFit */ while ((b != &freelist) && (foundBuffer == 0)) { if ((bufsize) b->bh.bsize >= (int32_t)size) { /* Buffer is big enough to satisfy the request. Allocate it to the caller. We must decide whether the buffer is large enough to split into the part given to the caller and a free buffer that remains on the free list, or whether the entire buffer should be removed from the free list and given to the caller in its entirety. We only split the buffer if enough room remains for a header plus the minimum quantum of allocation. */ if ((b->bh.bsize - (int32_t)size) > (int32_t)(SizeQ + (sizeof(struct bhead)))) { struct bhead *ba, *bn; ba = BH(getPointerOffset(b, (b->bh.bsize - (bufsize)size))); bn = BH(getPointerOffset(ba, (int32_t)size)); assert(bn->prevfree == b->bh.bsize); /* Subtract size from length of free block. */ b->bh.bsize -= (bufsize)size; /* Link allocated buffer to the previous free buffer. */ ba->prevfree = b->bh.bsize; /* Plug negative size into user buffer. */ ba->bsize = -(bufsize) size; /* Mark buffer after this one not preceded by free block. */ bn->prevfree = 0; #ifdef BufStats totalloc += (int32_t)size; numget++; /* Increment number of bget() calls */ #endif buf = (void *) getPointerOffset(ba, sizeof(struct bhead)); foundBuffer = 1; } else { struct bhead *ba; ba = BH(getPointerOffset(b, b->bh.bsize)); assert(ba->prevfree == b->bh.bsize); /* The buffer isn't big enough to split. Give the whole shebang to the caller and remove it from the free list. */ assert(b->ql.blink->ql.flink == b); assert(b->ql.flink->ql.blink == b); b->ql.blink->ql.flink = b->ql.flink; b->ql.flink->ql.blink = b->ql.blink; #ifdef BufStats totalloc += b->bh.bsize; numget++; /* Increment number of bget() calls */ #endif /* Negate size to mark buffer allocated. */ b->bh.bsize = -(b->bh.bsize); /* Zero the back pointer in the next buffer in memory to indicate that this buffer is allocated. */ ba->prevfree = 0; /* Give user buffer starting at queue links. */ buf = (void *) &(b->ql); foundBuffer = 1; } } if (foundBuffer == 0) { b = b->ql.flink; /* Link to next buffer */ } } #ifdef BECtl if (foundBuffer == 0 ) { /* We failed to find a buffer. If there's a compact function defined, notify it of the size requested. If it returns TRUE, try the allocation again. */ compactseq++; if (compfcn != NULL) { compfcnResult = (*compfcn)((bufsize)size, compactseq); } if ((compfcn == NULL) || (compfcnResult == 0)) { BECtlLoop = 0; } } else { BECtlLoop = 0; } } if (foundBuffer == 0 ) { /* No buffer available with requested size free. */ /* Don't give up yet -- look in the reserve supply. */ if (acqfcn != NULL) { if ((int32_t)size > (exp_incr - (int32_t)sizeof(struct bhead))) { /* Request is too large to fit in a single expansion block. Try to satisy it by a direct buffer acquisition. */ struct bdhead *bdh; size += (sizeof(struct bdhead) - sizeof(struct bhead)); bdh = BDH((*acqfcn)((bufsize) size)); if (bdh != NULL) { /* Mark the buffer special by setting the size field of its header to zero. */ bdh->bh.bsize = 0; bdh->bh.prevfree = 0; bdh->tsize = (bufsize)size; #ifdef BufStats totalloc += (int32_t)size; numget++; /* Increment number of bget() calls */ numdget++; /* Direct bget() call count */ #endif /* Bufstats */ buf = (void *) getPointerOffset(bdh,1); } } else { /* Try to obtain a new expansion block */ void *newpool; newpool = (*acqfcn)((bufsize) exp_incr); if (newpool != NULL) { bpool(newpool, exp_incr); acquireLoop = 1; } } } } /* Still no buffer available */ } #endif /* BECtl */ return buf; }
void* BGet::bget(bufsize requested_size) { bufsize size = requested_size; struct bfhead *b; #ifdef BestFit struct bfhead *best; #endif void *buf; assert(size >= 0); if (size < SizeQ) { /* Need at least room for the */ size = SizeQ; /* queue links. */ } #ifdef SizeQuant #if SizeQuant > 1 size = (size + (SizeQuant - 1)) & (~(SizeQuant - 1)); #endif #endif size += sizeof(struct bhead); /* Add overhead in allocated buffer to size required. */ b = freelist.ql.flink; #ifdef BestFit best = &freelist; #endif /* Scan the free list searching for the first buffer big enough to hold the requested size buffer. */ #ifdef BestFit while (b != &freelist) { if (b->bh.bsize >= size) { if ((best == &freelist) || (b->bh.bsize < best->bh.bsize)) { best = b; } } b = b->ql.flink; /* Link to next buffer */ } b = best; #endif /* BestFit */ while (b != &freelist) { if ((bufsize) b->bh.bsize >= size) { /* Buffer is big enough to satisfy the request. Allocate it to the caller. We must decide whether the buffer is large enough to split into the part given to the caller and a free buffer that remains on the free list, or whether the entire buffer should be removed from the free list and given to the caller in its entirety. We only split the buffer if enough room remains for a header plus the minimum quantum of allocation. */ if ((b->bh.bsize - size) > (SizeQ + (sizeof(struct bhead)))) { struct bhead *ba, *bn; ba = BH(((char *) b) + (b->bh.bsize - size)); bn = BH(((char *) ba) + size); assert(bn->prevfree == b->bh.bsize); /* Subtract size from length of free block. */ b->bh.bsize -= size; /* Link allocated buffer to the previous free buffer. */ ba->prevfree = b->bh.bsize; /* Plug negative size into user buffer. */ ba->bsize = -(bufsize) size; /* Mark buffer after this one not preceded by free block. */ bn->prevfree = 0; buf = (void *) ((((char *) ba) + sizeof(struct bhead))); return buf; } else { struct bhead *ba; ba = BH(((char *) b) + b->bh.bsize); assert(ba->prevfree == b->bh.bsize); /* The buffer isn't big enough to split. Give the whole shebang to the caller and remove it from the free list. */ assert(b->ql.blink->ql.flink == b); assert(b->ql.flink->ql.blink == b); b->ql.blink->ql.flink = b->ql.flink; b->ql.flink->ql.blink = b->ql.blink; /* Negate size to mark buffer allocated. */ b->bh.bsize = -(b->bh.bsize); /* Zero the back pointer in the next buffer in memory to indicate that this buffer is allocated. */ ba->prevfree = 0; /* Give user buffer starting at queue links. */ buf = (void *) &(b->ql); return buf; } } b = b->ql.flink; /* Link to next buffer */ } #ifdef BECtl /* No buffer available with requested size free. */ /* Don't give up yet -- look in the reserve supply. */ if (acqfcn != NULL) { if (size > exp_incr - sizeof(struct bhead)) { /* Request is too large to fit in a single expansion block. Try to satisy it by a direct buffer acquisition. */ struct bdhead *bdh; size += sizeof(struct bdhead) - sizeof(struct bhead); if ((bdh = BDH((*acqfcn)((bufsize) size))) != NULL) { /* Mark the buffer special by setting the size field of its header to zero. */ bdh->bh.bsize = 0; bdh->bh.prevfree = 0; bdh->tsize = size; buf = (void *) (bdh + 1); return buf; } } else { /* Try to obtain a new expansion block */ void *newpool; if ((newpool = (*acqfcn)((bufsize) exp_incr)) != NULL) { bpool(newpool, exp_incr); buf = bget(requested_size); /* This can't, I say, can't get into a loop. */ return buf; } } } /* Still no buffer available */ #endif /* BECtl */ return NULL; }
/* bget * Used for buffer allocation with the given pool. Returns NULL if there * is no more room available. */ void* bget( _In_ BytePool_t *pool, _In_ long requested_size) { // Variables long size = requested_size; struct bfhead *b; #ifdef BestFit struct bfhead *best; #endif void *buf; #ifdef BECtl int compactseq = 0; #endif assert(pool != NULL); assert(size > 0); if (size < SizeQ) { /* Need at least room for the */ size = SizeQ; /* queue links. */ } #ifdef SizeQuant #if SizeQuant > 1 size = (size + (SizeQuant - 1)) & (~(SizeQuant - 1)); #endif #endif size += sizeof(struct bhead); /* Add overhead in allocated buffer to size required. */ #ifdef BECtl /* If a compact function was provided in the call to bectl(), wrap a loop around the allocation process to allow compaction to intervene in case we don't find a suitable buffer in the chain. */ while (1) { #endif b = pool->freelist.ql.flink; #ifdef BestFit best = &pool->freelist; #endif /* Scan the free list searching for the first buffer big enough to hold the requested size buffer. */ #ifdef BestFit while (b != &pool->freelist) { if (b->bh.bsize >= size) { if ((best == &pool->freelist) || (b->bh.bsize < best->bh.bsize)) { best = b; } } b = b->ql.flink; /* Link to next buffer */ } b = best; #endif /* BestFit */ while (b != &pool->freelist) { if ((long) b->bh.bsize >= size) { /* Buffer is big enough to satisfy the request. Allocate it to the caller. We must decide whether the buffer is large enough to split into the part given to the caller and a free buffer that remains on the free list, or whether the entire buffer should be removed from the free list and given to the caller in its entirety. We only split the buffer if enough room remains for a header plus the minimum quantum of allocation. */ if ((b->bh.bsize - size) > (SizeQ + (sizeof(struct bhead)))) { struct bhead *ba, *bn; ba = BH(((char *) b) + (b->bh.bsize - size)); bn = BH(((char *) ba) + size); assert(bn->prevfree == b->bh.bsize); /* Subtract size from length of free block. */ b->bh.bsize -= size; /* Link allocated buffer to the previous free buffer. */ ba->prevfree = b->bh.bsize; /* Plug negative size into user buffer. */ ba->bsize = -(long) size; /* Mark buffer after this one not preceded by free block. */ bn->prevfree = 0; #ifdef BufStats pool->totalloc += size; pool->numget++; /* Increment number of bget() calls */ #endif buf = (void *) ((((char *) ba) + sizeof(struct bhead))); return buf; } else { struct bhead *ba; ba = BH(((char *) b) + b->bh.bsize); assert(ba->prevfree == b->bh.bsize); /* The buffer isn't big enough to split. Give the whole shebang to the caller and remove it from the free list. */ assert(b->ql.blink->ql.flink == b); assert(b->ql.flink->ql.blink == b); b->ql.blink->ql.flink = b->ql.flink; b->ql.flink->ql.blink = b->ql.blink; #ifdef BufStats pool->totalloc += b->bh.bsize; pool->numget++; /* Increment number of bget() calls */ #endif /* Negate size to mark buffer allocated. */ b->bh.bsize = -(b->bh.bsize); /* Zero the back pointer in the next buffer in memory to indicate that this buffer is allocated. */ ba->prevfree = 0; /* Give user buffer starting at queue links. */ buf = (void *) &(b->ql); return buf; } } b = b->ql.flink; /* Link to next buffer */ } #ifdef BECtl /* We failed to find a buffer. If there's a compact function defined, notify it of the size requested. If it returns TRUE, try the allocation again. */ if ((pool->compfcn == NULL) || (!(*pool->compfcn)(size, ++compactseq))) { break; } } /* No buffer available with requested size free. */ /* Don't give up yet -- look in the reserve supply. */ if (pool->acqfcn != NULL) { if (size > pool->exp_incr - sizeof(struct bhead)) { /* Request is too large to fit in a single expansion block. Try to satisy it by a direct buffer acquisition. */ struct bdhead *bdh; size += sizeof(struct bdhead) - sizeof(struct bhead); if ((bdh = BDH((*pool->acqfcn)((long) size))) != NULL) { /* Mark the buffer special by setting the size field of its header to zero. */ bdh->bh.bsize = 0; bdh->bh.prevfree = 0; bdh->tsize = size; #ifdef BufStats pool->totalloc += size; pool->numget++; /* Increment number of bget() calls */ pool->numdget++; /* Direct bget() call count */ #endif buf = (void *) (bdh + 1); return buf; } } else { /* Try to obtain a new expansion block */ void *newpool; if ((newpool = (*pool->acqfcn)((long) pool->exp_incr)) != NULL) { bpool(newpool, pool->exp_incr, &pool); buf = bget(pool, requested_size); /* This can't, I say, can't get into a loop. */ return buf; } } } /* Still no buffer available */ #endif /* BECtl */ return NULL; }