void FMTest1Thread(TAny* a) { SFMTest1Info& info = *(SFMTest1Info*)a; NThread* pC = NKern::CurrentThread(); TUint32 seed[2] = {(TUint32)pC, 0}; TBool wait = (pC->iPriority > info.iPriorityThreshold); TBool thread0 = (pC==info.iThreads[0]); TInt n = 0; while (!info.iStop) { if (thread0) NKern::ThreadSetPriority(pC, 11); NKern::FMWait(&info.iMutex); TBool ok = verify_block((TUint32*)info.iBlock, info.iBlockSize); TEST_RESULT(ok, "Block corrupt"); ++info.iBlock[0]; setup_block((TUint32*)info.iBlock, info.iBlockSize); ++n; NKern::FMSignal(&info.iMutex); if (wait) { TUint32 x = random(seed) & 1; NKern::Sleep(x+1); } } TEST_PRINT2("Thread %T ran %d times", pC, n); }
void kfree(void* address) { kdebug("< kfree %d", address); // start of block malloc_block_t* block = address - (uint32_t)&(((malloc_block_t*)0)->data); check_block(block); int size = block->size; int flags = block->flags & ~MALLOC_USED; // if next block is free, merge with it if ((block->flags&MALLOC_LAST)==0) { malloc_block_t* next = BLOCK_NEXT(block); if ((next->flags&MALLOC_USED)==0) { size += next->size; flags |= (next->flags&MALLOC_LAST); } } // if previous block is free, merge with it if ((block->flags&MALLOC_FIRST)==0) { malloc_block_t* prev = BLOCK_PREVIOUS(block); if ((prev->flags&MALLOC_USED)==0) { size += prev->size; flags |= (prev->flags&MALLOC_FIRST); block = prev; } } setup_block(block, flags, size); kmalloc_print(); kdebug(">"); }
void kmalloc_init(void* base, size_t size) { kdebug("< kmalloc_init %d, %d", base, size); first_block = (malloc_block_t*)base; setup_block(first_block, MALLOC_FIRST|MALLOC_LAST, size); kmalloc_print(); kdebug(">"); }
void* kmalloc(size_t payload) { malloc_block_t* block; malloc_block_t* ptr; kdebug("< kmalloc %d", payload); block = 0; ptr = first_block; while (1) { check_block(ptr); // free and big enough ? if (((ptr->flags&MALLOC_USED)==0) && (PAYLOAD_SIZE(ptr)>=payload)) { // better than the current fit (if any) ? if ((block==0) || (ptr->size<block->size)) { block = ptr; } } if (ptr->flags&MALLOC_LAST) { break; } ptr = BLOCK_NEXT(ptr); } if (ptr==0) { kpanic("could not allocate %d", payload); return 0; } int split_block = (block->size > (payload+BLOCK_OVERHEAD)); if (split_block) { int last = block->flags&MALLOC_LAST; size_t size = payload + BLOCK_OVERHEAD; size_t rem_size = block->size - size; setup_block(block, (block->flags&~MALLOC_LAST)|MALLOC_USED, size); setup_block(BLOCK_NEXT(block), last, rem_size); } else { block->flags |= MALLOC_USED; } kmalloc_print(); kdebug(">"); return (void*)block->data; }
void FMTest1P() { TEST_PRINT("Testing priority change"); if (NKern::NumberOfCpus()==1) return; NFastSemaphore exitSem(0); SFMTest1Info* pI = new SFMTest1Info; TEST_OOM(pI); memclr(pI, sizeof(SFMTest1Info)); TEST_PRINT1("Info@0x%08x", pI); pI->iBlockSize = 256; pI->iBlock = (TUint32*)malloc(pI->iBlockSize*sizeof(TUint32)); TEST_OOM(pI->iBlock); pI->iPriorityThreshold = 9; pI->iBlock[0] = 0; setup_block((TUint32*)pI->iBlock, pI->iBlockSize); pI->iStop = FALSE; TInt cpu; TInt threadCount = 0; TInt pri = 9; char name[16] = "FMTest1P.0"; for_each_cpu(cpu) { name[9] = (char)(threadCount + '0'); if (cpu==1) pI->iThreads[threadCount] = CreateThreadSignalOnExit("FMTest1PInterferer", &FMTest1PInterfererThread, 12, pI, 0, KSmallTimeslice, &exitSem, 1); else pI->iThreads[threadCount] = CreateThreadSignalOnExit(name, &FMTest1Thread, pri, pI, 0, KSmallTimeslice, &exitSem, cpu); pri = 10; threadCount++; } TUint32 b0 = 0xffffffffu; FOREVER { NKern::Sleep(1000); TUint32 b = pI->iBlock[0]; TEST_PRINT1("%d", b); if (b > 1048576) { pI->iStop = TRUE; break; } if (b == b0) { __crash(); } b0 = b; } while (threadCount--) NKern::FSWait(&exitSem); TEST_PRINT1("Total iterations %d", pI->iBlock[0]); free((TAny*)pI->iBlock); free(pI); }
void DisassemblerContext::run_term(const ValuePtr<>& term) { switch (term->term_type()) { case term_function: { ValuePtr<Function> function = value_cast<Function>(term); setup_term_name(function); setup_function(function); build_unique_names(); print_definitions(m_global_definitions, "", true); print_function(function); break; } case term_block: { ValuePtr<Block> block = value_cast<Block>(term); m_in_function_mode = true; setup_term_name(block); setup_block(block); build_unique_names(); print_block(block, m_global_definitions); break; } default: m_in_function_mode = true; setup_term_definition(term); build_unique_names(); print_definitions(m_global_definitions); switch (term->term_type()) { case term_instruction: case term_phi: case term_function_parameter: case term_recursive: print_term_definition(term, true); break; default: break; } break; } }
void FMTest1() { TEST_PRINT("Testing mutual exclusion"); NFastSemaphore exitSem(0); SFMTest1Info* pI = new SFMTest1Info; TEST_OOM(pI); memclr(pI, sizeof(SFMTest1Info)); pI->iBlockSize = 256; pI->iBlock = (TUint32*)malloc(pI->iBlockSize*sizeof(TUint32)); TEST_OOM(pI->iBlock); pI->iPriorityThreshold = 10; pI->iBlock[0] = 0; setup_block((TUint32*)pI->iBlock, pI->iBlockSize); pI->iStop = FALSE; TInt cpu; TInt threads = 0; for_each_cpu(cpu) { CreateThreadSignalOnExit("FMTest1H", &FMTest1Thread, 11, pI, 0, KSmallTimeslice, &exitSem, cpu); CreateThreadSignalOnExit("FMTest1L0", &FMTest1Thread, 10, pI, 0, KSmallTimeslice, &exitSem, cpu); CreateThreadSignalOnExit("FMTest1L1", &FMTest1Thread, 10, pI, 0, KSmallTimeslice, &exitSem, cpu); threads += 3; } FOREVER { NKern::Sleep(1000); TEST_PRINT1("%d", pI->iBlock[0]); if (pI->iBlock[0] > 65536) { pI->iStop = TRUE; break; } } while (threads--) NKern::FSWait(&exitSem); TEST_PRINT1("Total iterations %d", pI->iBlock[0]); free((TAny*)pI->iBlock); free(pI); }
void DisassemblerContext::setup_function(const ValuePtr<Function>& function) { for (Function::ParameterList::const_iterator ii = function->parameters().begin(), ie = function->parameters().end(); ii != ie; ++ii) setup_term_definition(*ii); setup_term(function->result_type()); for (Function::BlockList::const_iterator ii = function->blocks().begin(), ie = function->blocks().end(); ii != ie; ++ii) { const ValuePtr<Block>& block = *ii; setup_term_name(block); for (Block::PhiList::const_iterator ji = block->phi_nodes().begin(), je = block->phi_nodes().end(); ji != je; ++ji) m_names.insert(std::make_pair(*ji, make_term_name(*ji, function))); for (Block::InstructionList::const_iterator ji = block->instructions().begin(), je = block->instructions().end(); ji != je; ++ji) m_names.insert(std::make_pair(*ji, make_term_name(*ji, function))); for (Function::BlockList::const_iterator ji = function->blocks().begin(), je = function->blocks().end(); ji != je; ++ji) { setup_term_name(*ji); setup_block(*ji); } } }
void init(struct toys *t) { setup_block(&(t->rubix)); setup_doll(&(t->barbie)); }