PVOID KernelResizeMemory ( PVOID pMem, ULONG ulSize ) { /*DH DEBUG*/ /*KernelTrace("KernelResizeMemory ...\n");*/ KernelFreeMemory(pMem); return KernelAllocateMemory(ulSize); }
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 ) { 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; }
KERNEL_HANDLE KernelCreateTask ( KERNEL_TASK_START_ENTRY startEntry, ULONG stackSize, ULONG priority, KERNEL_HANDLE hContext, char* taskName ) { static ULONG taskNo = 0; PKERNEL_TASK_CONTEXT pTaskContext = NULL; PROCESS pProc; wait_sem(&gSerializeSem); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_GENERIC, "KernelCreateTask -- taskName = %s, startEntry = 0x%X, stackSize = %d, priority = %d, context = 0x%X.\n", taskName, startEntry, stackSize, priority, hContext ); pTaskContext = KernelAllocateMemory(sizeof(KERNEL_TASK_CONTEXT)); if (pTaskContext == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_GENERIC, "KernelCreateTask -- cannot allocate memory for the task context, size = %d.\n", sizeof(KERNEL_TASK_CONTEXT) ); signal_sem(&gSerializeSem); return KERNEL_HANDLE_NULL; } pTaskContext->StartEntry = startEntry; pTaskContext->hContext = hContext; KernelAssert(gpTaskContext == NULL); gpTaskContext = pTaskContext; pProc = create_process ( priority - (priority % 64), taskName, KernelTaskRoutineEntry, stackSize, priority % 64, 0, (PROCESS)0, (struct OS_redir_entry *)0, 0x0000, (OSUSER)0 ); if (!pProc) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_GENERIC, "KernelCreateTask -- failed to create the process %s!\n", taskName ); /* * capture this exception */ KernelAssert(FALSE); signal_sem(&gSerializeSem); return KERNEL_HANDLE_NULL; } /* * start the process */ start(pProc); /* * wait for the process complete access to the global task context */ wait_sem(&gCompletionSem); KernelAssert(gpTaskContext == NULL); signal_sem(&gSerializeSem); return (KERNEL_HANDLE)pProc; }
BOOLEAN KernelInitializeEvent ( PKERNEL_EVENT pBaseEvent ) { PKERNEL_EVENT_MSG pEvent = (PKERNEL_EVENT_MSG)pBaseEvent; BITS critLevel; BOOLEAN retStatus = TRUE; KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelInitializeEvent -- Handle: 0x%lX, Task: %s.\n", pEvent, atmos_pcb_current_get_name() ); critLevel = atmos_startcritical(); if ( !bEventMsgInit ) { int i; PKERNEL_FREE_MSG pTmpMsg; pFreeMsgHeader = NULL; for (i = 0; i < KERNEL_MAX_MESSAGE_NUM; i++) { pTmpMsg = (PKERNEL_FREE_MSG)KernelAllocateMemory(sizeof(KERNEL_FREE_MSG)); pTmpMsg->Next = pFreeMsgHeader; pFreeMsgHeader = pTmpMsg; } /* KernelRealInitializeLock(&EventLock, __FILE__, __LINE__); */ bEventMsgInit = TRUE; } if ( pEvent == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_EVENT, "KernelInitializeEvent -- NULL Event!!\n" ); retStatus = FALSE; goto EXIT1; } pEvent->NumberSignaled = 0; KernelSListInitializeHeader(&pEvent->TaskList); EXIT1: atmos_endcritical(critLevel); KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_EVENT, "KernelInitializeEvent -- done, Handle: 0x%lX, Task: %s.\n", pEvent, atmos_pcb_current_get_name() ); return retStatus; }
BOOLEAN KernelRealInitializeLock ( PKERNEL_LOCK pLock, const char* pFileName, ULONG ulLineNumber ) { BITS critLevel; BOOLEAN retStatus = TRUE; tASErr err; char cSemaName[32]; if ( !bEnableLock ) { return retStatus; } critLevel = atmos_startcritical(); if ( !bSemaphoreInit ) { int i; PKERNEL_FREE_LOCK pFreeSema; pFreeLockHeader = NULL; for ( i = 0; i < KERNEL_MAX_SEMAPHORE_NUM; i++ ) { if ( i % (KERNEL_MAX_SEMAPHORE_NUM / 10) == 0 ) { KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- %03d%% finished!!\n", (i * 100 / KERNEL_MAX_SEMAPHORE_NUM) ); } pFreeSema = (PKERNEL_FREE_LOCK)KernelAllocateMemory(sizeof(KERNEL_FREE_LOCK)); if ( pFreeSema == NULL ) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- run out of memory!!\n" ); retStatus = FALSE; goto EXIT1; } pFreeSema->semaLock = NULL; pFreeSema->Next = pFreeLockHeader; pFreeLockHeader = pFreeSema; } KernelTrace2 ( KERNEL_DBG_LEVEL_TRACE_FLOW, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- %03d%% finished!!\n", (i * 100 / KERNEL_MAX_SEMAPHORE_NUM) ); bSemaphoreInit = TRUE; } if ( pLock == NULL) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- NULL lock, file -- %s, line %lu!!\n", (pFileName ? pFileName : "No file name"), ulLineNumber ); retStatus = FALSE; goto EXIT1; } if ( !bSemaphoreInit || pFreeLockHeader == NULL ) { KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- run out of FREE LOCK, %u, task: %s!!\n", bSemaphoreInit, atmos_pcb_current_get_name() ); retStatus = FALSE; goto EXIT1; } gulLockCount += 1; *pLock = pFreeLockHeader; pFreeLockHeader = (*pLock)->Next; (*pLock)->Next = NULL; atmos_endcritical(critLevel); if ( (*pLock)->semaLock == NULL ) { sprintf(cSemaName, "%s%05u", semaphore_name, gulSemaphoreId); gulSemaphoreId += 1; err = as_SemaphoreNew ( &(*pLock)->semaLock, (const char*)cSemaName, "" ); if (kASEOK != err) { retStatus = FALSE; KernelTrace2 ( KERNEL_DBG_LEVEL_WARNING, KERNEL_DBG_MASK_LOCK, "KernelRealInitializeLock -- new semaphore failed!!\n" ); return retStatus; } as_SemaphorePost((*pLock)->semaLock); } EXIT1: atmos_endcritical(critLevel); return retStatus; }
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; }