PVOID __KernelReAllocMemory ( PVOID pMem, ULONG ulSize, PCSTR pFileName, ULONG LineNumber ) { void* pOldMemory = (void*)pMem; void* pNewMemory = NULL; ULONG ulOldSize = KernelGetMemorySize(pOldMemory); ULONG ulNewSize = ulSize; ULONG ulCpySize = (ulOldSize >= ulNewSize) ? ulNewSize : ulOldSize; /*DH DEBUG*/ KernelTrace ( "__KernelReAllocMemory -- %s:%lu, old size = %lu, new size = %lu, copy size = %lu ...\n", pFileName, LineNumber, ulOldSize, ulNewSize, ulCpySize ); if ( ulNewSize <= ulOldSize ) { return pOldMemory; } pNewMemory = KernelAllocateMemory(ulNewSize); if ( !pNewMemory ) { KernelFreeMemory(pOldMemory); return NULL; } else { KernelCopyMemory(pNewMemory, pOldMemory, ulCpySize); } KernelFreeMemory(pOldMemory); return pNewMemory; }
PVOID KernelResizeMemory ( PVOID pMem, ULONG ulSize ) { /*DH DEBUG*/ /*KernelTrace("KernelResizeMemory ...\n");*/ KernelFreeMemory(pMem); return KernelAllocateMemory(ulSize); }
void KernelLeaveTask ( void ) { PKERNEL_TASK_MEM_BLOCK pMem = NULL; KernelAcquireSpinLock(&gMemBlockPoolLock); if ( TRUE ) { pMem = gMemBlockPool.Next; while ( pMem ) { gMemBlockPool.Next = pMem->Next; KernelFreeMemory(pMem); pMem = gMemBlockPool.Next; } gMemBlockPool.Prev = NULL; gMemBlockPool.Next = NULL; } if ( TRUE ) { pMem = (PKERNEL_TASK_MEM_BLOCK)cyg_thread_get_data(0); if ( pMem ) { gMemBlockPool.Prev = pMem; gMemBlockPool.Next = pMem; } } KernelReleaseSpinLock(&gMemBlockPoolLock); cyg_thread_exit(); return; }
PVOID KernelResizeMemory ( PVOID pMem, ULONG ulSize ) { BITS critLevel; PVOID pNewMem = NULL; critLevel = atmos_startcritical(); KernelFreeMemory(pMem); pNewMem = KernelAllocateMemory(ulSize); atmos_endcritical(critLevel); return pNewMem; }
PVOID KernelReAllocMemory ( PVOID pMemoryBlock, ULONG ulMemorySize ) { BITS critLevel; void* pOldMemory = (void*)pMemoryBlock; void* pNewMemory = NULL; ULONG ulOldSize = 0; ULONG ulNewSize = 0; ULONG ulCpySize = 0; critLevel = atmos_startcritical(); ulOldSize = KernelGetMemorySize(pOldMemory); ulNewSize = ulMemorySize; ulCpySize = (ulOldSize >= ulNewSize) ? ulNewSize : ulOldSize; pNewMemory = KernelAllocateMemory(ulNewSize); atmos_endcritical(critLevel); if ( !pNewMemory ) { return NULL; } else { KernelCopyMemory(pNewMemory, pOldMemory, ulCpySize); } critLevel = atmos_startcritical(); KernelFreeMemory(pOldMemory); atmos_endcritical(critLevel); return pNewMemory; }
/* * eCos doesn't clean the memory blocks of stack and thread info required to create * a thread, if they are dynamically allocated. Here is how we clean them: * 1) when a thread is created, we allocate a memory block for both stack and thread info. * 2) The memory block pointer is stored into thread data, index 0 * 3) When a thread exits, it retrieves the memory block pointer from thread data, index 0 * and put it into a pool * 4) Next time when another thread exits, it first cleans up the memory block pool. * 5) In step 3) and 4), a spin lock is used to protect the memory block pool. */ KERNEL_HANDLE KernelCreateTask ( cyg_thread_entry_t* startEntry, ULONG stackSize, ULONG priority, KERNEL_HANDLE hContext, char* pName ) { ULONG ulSize = 0; PKERNEL_TASK_MEM_BLOCK pMem = NULL; PUCHAR pStack = NULL; cyg_thread* pThreadInfo = NULL; cyg_handle_t hThread = 0; ulSize = (sizeof(KERNEL_TASK_MEM_BLOCK) + CYGNUM_HAL_STACK_FRAME_SIZE) / CYGNUM_HAL_STACK_FRAME_SIZE * CYGNUM_HAL_STACK_FRAME_SIZE; pMem = (PKERNEL_TASK_MEM_BLOCK)KernelAllocateMemory(ulSize + stackSize); if ( pMem ) { pStack = pMem + ulSize; pThreadInfo = &pMem->ThreadInfo; cyg_thread_create ( priority, startEntry, hContext, pName, pStack, stackSize, &hThread, pThreadInfo ); if ( hThread ) { KernelTrace ( "KernelCreateTask -- memory block pointer for task %s is 0x%lX.\n", pName, pMem ); cyg_thread_set_data(0, pMem); cyg_thread_resume(hThread); return hThread; } } if ( pMem ) { KernelFreeMemory(pMem); } return (KERNEL_HANDLE)NULL; }
VOID KernelPulseEvent ( PKERNEL_EVENT pBaseEvent ) { PKERNEL_EVENT_MSG pEvent = (PKERNEL_EVENT_MSG)pBaseEvent; PKERNEL_TASK_LIST_ENTRY pTaskListEntry; PKERNEL_SLIST_ENTRY pSListEntry; BITS critLevel; KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- Handle = 0x%lX, Task = %s.\n", pEvent, atmos_pcb_current_get_name() ); if ( pEvent == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- NULL Event, Task: %s!!\n", atmos_pcb_current_get_name() ); return; } critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ pSListEntry = KernelSListPopEntry(&pEvent->TaskList); atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ while ( pSListEntry ) { pTaskListEntry = ACCESS_TASK_LIST_ENTRY(pSListEntry); if ( (pTaskListEntry->TaskQid != atmos_qid_get_current()) && bEventMsgInit && pFreeMsgHeader ) { PKERNEL_FREE_MSG pFreeMsg; critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ /* * grab a pre-allocated message buffer */ pFreeMsg = pFreeMsgHeader; if ( pFreeMsg != NULL ) { MSG_D_KTX_AL_SET_EVENT(pSetEvent, &pFreeMsg->Msg); pFreeMsgHeader = pFreeMsg->Next; pSetEvent->EventHandle = (U32*)pEvent; atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- event 0x%lX, send message to qid = 0x%lX, task %s...\n", pEvent, pTaskListEntry->TaskQid, pTaskListEntry->TaskName ); sendmessage ( &pFreeMsg->Msg, MSG_N_KTX_AL_SET_EVENT, pTaskListEntry->TaskQid ); } else { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- event 0x%lX, run out of free msg, %u.\n", pEvent, bEventMsgInit ); atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ } } else { if ( !pFreeMsgHeader || !bEventMsgInit ) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- event 0x%lX, run out of free msg, %u.\n", pEvent, bEventMsgInit ); } } KernelFreeMemory(pTaskListEntry); critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ pSListEntry = KernelSListPopEntry(&pEvent->TaskList); atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ } critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ pEvent->NumberSignaled = 0; atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelPulseEvent -- event 0x%lX, done, task = %s.\n", pEvent, atmos_pcb_current_get_name() ); return; }
VOID KernelFreeEvent ( PKERNEL_EVENT pBaseEvent ) { PKERNEL_EVENT_MSG pEvent = (PKERNEL_EVENT_MSG)pBaseEvent; BITS critLevel; PKERNEL_TASK_LIST_ENTRY pTaskListEntry; PKERNEL_SLIST_ENTRY pSListEntry; KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelFreeEvent -- event: 0x%lX, task = %s.\n", pEvent, atmos_pcb_current_get_name() ); if ( pEvent == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelFreeEvent -- NULL Event, Task: %s!!\n", atmos_pcb_current_get_name() ); return; } critLevel = atmos_startcritical(); /* KernelRealAcquireLock(&EventLock, __FILE__, __LINE__); */ if ( KernelSListGetFirstEntry(&pEvent->TaskList) != NULL ) { KernelTrace2 ( KERNEL_DBG_LEVEL_TEST, KERNEL_DBG_MASK_EVENT, "KernelFreeEvent -- event: 0x%lX, task = %s, there are tasks waiting...\n", pEvent, atmos_pcb_current_get_name() ); atmos_endcritical(critLevel); /* KernelRealReleaseLock(&EventLock, __FILE__, __LINE__); */ KernelPulseEvent(pBaseEvent); critLevel = atmos_startcritical(); /* KernelRealAcquireLock(&EventLock, __FILE__, __LINE__); */ } pSListEntry = KernelSListPopEntry(&pEvent->TaskList); while ( pSListEntry ) { pTaskListEntry = ACCESS_TASK_LIST_ENTRY(pSListEntry); pSListEntry = KernelSListPopEntry(&pEvent->TaskList); KernelTrace2 ( KERNEL_DBG_LEVEL_TEST, KERNEL_DBG_MASK_EVENT, "KernelFreeEvent -- event: 0x%lX, task = %s, throw out the waiting task %s, qid = 0x%lX...\n", pEvent, atmos_pcb_current_get_name(), pTaskListEntry->TaskName, pTaskListEntry->TaskQid ); KernelFreeMemory(pTaskListEntry); } pEvent->NumberSignaled = 0; KernelSListInitializeHeader(&pEvent->TaskList); atmos_endcritical(critLevel); /* KernelRealReleaseLock(&EventLock, __FILE__, __LINE__); */ KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelFreeEvent -- Done, event: 0x%lX, task = %s.\n", pEvent, atmos_pcb_current_get_name() ); return; }
void KernelWaitEvent ( PKERNEL_EVENT pBaseEvent, ULONG ulMilliSeconds ) { PKERNEL_EVENT_MSG pEvent = (PKERNEL_EVENT_MSG)pBaseEvent; PKERNEL_SLIST_ENTRY pSavedSListEntry= (PKERNEL_SLIST_ENTRY)NULL; PKERNEL_TASK_LIST_ENTRY pTaskListEntry; PKERNEL_FREE_MSG pFreeMsg; BITS critLevel; BOOLEAN bInfinite = FALSE; BOOLEAN bLoop = TRUE; CHAR* cTaskName; ATMOS_MESSAGE TimerMsg; ATMOS_MESSAGE* pWaitingMsg; WORD wRtnCode; int iPhase = 0; char NameBuffer[16] = "Insuffient"; char NameBuffer2[16] = "Insuffient"; cTaskName = (char*)atmos_pcb_current_get_name(); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event: 0x%lX, task = %s, time = %u.\n", pEvent, cTaskName, ulMilliSeconds ); if ( ulMilliSeconds == 0 || ulMilliSeconds == 0xFFFFFFFF ) { bInfinite = TRUE; } if ( pEvent == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- NULL Event, Task: %s!!\n", cTaskName ); return; } critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ if ( pEvent->NumberSignaled ) { pEvent->NumberSignaled -= 1; bLoop = FALSE; } else { pTaskListEntry = (PKERNEL_TASK_LIST_ENTRY)KernelAllocateMemory(sizeof(KERNEL_TASK_LIST_ENTRY)); pTaskListEntry->TaskQid = atmos_qid_get_current(); #if defined(KERNEL_CHECKED_BUILD) KernelCopyString(pTaskListEntry->TaskName, cTaskName); #endif KernelSListPushEntry(&pEvent->TaskList, &pTaskListEntry->Linkage); pSavedSListEntry = &pTaskListEntry->Linkage; } atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ if ( bLoop && !bInfinite ) { timer_ms_timeout(&TimerMsg, ulMilliSeconds); } while ( bLoop ) { KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- waiting ..., Event = 0x%lx, Task = %s.\n", pEvent, cTaskName ); pWaitingMsg = awaitmessage(); switch ( pWaitingMsg->code ) { case MSG_N_KTX_AL_SET_EVENT: { MSG_D_KTX_AL_SET_EVENT(pSetEvent, pWaitingMsg); if ( pSetEvent->EventHandle == (U32*)pEvent ) { bLoop = FALSE; if ( !bInfinite ) { bInfinite = TRUE; if ( pollspecificmessage(&TimerMsg) ) { KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, timer message is on the way...\n", pEvent, cTaskName ); awaitspecificmessage(&TimerMsg); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, cleaned the timer message.\n", pEvent, cTaskName ); } else { KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, cancel the timer message...\n", pEvent, cTaskName ); wRtnCode = timer_cancel(&TimerMsg); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, done with the timer message cancellation, error code = %u, %s.\n", pEvent, cTaskName, wRtnCode, pollmessage() ? "new message pending" : "no new messages" ); /* Found or not (wRtnCode == ENOTFOUND), the original message should have come back */ if ( pollspecificmessage(&TimerMsg) ) { awaitspecificmessage(&TimerMsg); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, cleaned the timer message.\n", pEvent, cTaskName ); } else { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, Timer message didn't come back!!!\n", pEvent, cTaskName ); } } } } else { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, qid = 0x%lX, task = %s, received bad SetEvent msg, event handle = 0x%lX, from task %s!!\n", pEvent, atmos_qid_get_current(), cTaskName, pSetEvent->EventHandle, atmos_qid_get_name(pWaitingMsg->src, NameBuffer, sizeof(NameBuffer)) ); } critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ pFreeMsg = ACCESS_FREE_MSG(pWaitingMsg); pFreeMsg->Next = pFreeMsgHeader; pFreeMsgHeader = pFreeMsg; atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ iPhase = 1; break; } case MSG_R_TIMER_MSWAIT: { BOOLEAN bFound; bLoop = FALSE; KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_INFO, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, task = %s, timed-out...\n", pEvent, cTaskName ); critLevel = atmos_startcritical(); /*KernelRealAcquireLock(&EventLock, __FILE__, __LINE__);*/ bFound = KernelSListPopEntryByLink(&pEvent->TaskList, pSavedSListEntry); if ( bFound ) { pTaskListEntry = ACCESS_TASK_LIST_ENTRY(pSavedSListEntry); if ( pTaskListEntry->TaskQid == atmos_qid_get_current() ) { KernelFreeMemory(pTaskListEntry); } else { KernelSListPushEntry(&pEvent->TaskList, pSavedSListEntry); } } atmos_endcritical(critLevel); /*KernelRealReleaseLock(&EventLock, __FILE__, __LINE__);*/ iPhase = 2; break; } default: { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelWaitEvent -- event = 0x%lX, qid = 0x%lX, task = %s, received unknown msg: 0x%X, src: 0x%X(%s), dst: 0x%X(%s)!\n", pEvent, atmos_qid_get_current(), cTaskName, pWaitingMsg->code, pWaitingMsg->src, atmos_qid_get_name(pWaitingMsg->src, NameBuffer, sizeof(NameBuffer)), pWaitingMsg->dest, atmos_qid_get_name(pWaitingMsg->dest, NameBuffer2, sizeof(NameBuffer2)) ); break; } } } return; }