/* Use this function to see what happens when your malloc and free * implementations are called. Run "mem -try <args>" to call this function. * We have given you a simple example to start. */ void try_mymem(int argc, char **argv) { strategies strat; void *a, *b, *c, *d, *e; if(argc > 1) strat = strategyFromString(argv[1]); else strat = First; /* A simple example. Each algorithm should produce a different layout. */ initmem(strat,500); a = mymalloc(100); b = mymalloc(100); c = mymalloc(100); myfree(b); d = mymalloc(50); myfree(a); e = mymalloc(25); print_memory(); print_memory_status(); }
void Scheduler_InitAndSetKernelTask(Scheduler * scheduler, KernelState * k_state) { TD * task_descriptor = &(scheduler->task_descriptors[0]); /* Initialize so it does not point at garbage, will be set again later. */ scheduler->current_task_descriptor = task_descriptor; int task_priority = LOWEST; int task_id = 0; /* TODO: add define special case for partent of first task */ TD_Initialize(task_descriptor, task_id, task_priority, 99, get_stack_base(task_id), (void *)&KernelTask_Start); scheduler->num_ready += 1; scheduler->num_tasks++; safely_add_task_to_priority_queue(&scheduler->task_queue, task_descriptor, task_priority); Scheduler_ScheduleAndSetNextTaskState(scheduler, k_state); print_memory_status(); }
TD * Scheduler_ScheduleNextTask(Scheduler * scheduler, KernelState * k_state){ int times = 0; int min_priority = 0; while (min_priority < NUM_PRIORITIES) { int i; for (i = 0; i < MAX_TASKS + 2; i++) { TD * td = PriorityQueue_GetLower(&(scheduler->task_queue), min_priority, (void*)&min_priority); if (td == 0) { // There are no ready tasks found. break; } else if (td->state == READY) { Scheduler_ChangeTDState(scheduler, td, ACTIVE); return td; } else if (td->state == RECEIVE_BLOCKED || td->state == SEND_BLOCKED || td->state == REPLY_BLOCKED || td->state == EVENT_BLOCKED) { assertf(0, "Task %d is %s but it is in the ready queue.\n", td->id, TASK_STATE_NAMES[td->state]); } else if (td->state == ZOMBIE) { // TODO: // Destroy the zombie task Scheduler_ChangeTDState(scheduler, td, ZOMBIE); } else { assertf(0,"Unknown task state: %d for tid=%d.",td->state, td->id); } times++; assertf(times < (MAX_TASKS + 2) * NUM_PRIORITIES,"Scheduler ran more than %d times, probably a bug.", (MAX_TASKS + 2) * NUM_PRIORITIES); } min_priority++; } robprintfbusy((const unsigned char *)"\033[44;37mNo tasks in queue!\033[0m\n"); if(TIMER_INTERRUPTS_ENABLED){ IRQ_ClearTimerInterrupt(); IRQ_DisableTimerVIC2(); IRQ_DisableUARTInterrupts(); } Scheduler_PrintTDCounts(scheduler); // TODO: don't ignore this assertf(scheduler->num_ready == 0, "Number of ready tasks is not zero. Count=%d", scheduler->num_ready); assertf(scheduler->num_active == 0, "Number of active tasks is not zero. Count=%d", scheduler->num_active); /* assertf(scheduler->num_send_blocked == 0, "Number of send_blocked tasks is not zero. Count=%d", scheduler->num_send_blocked); assertf(scheduler->num_reply_blocked == 0, "Number of reply_blocked tasks is not zero. Count=%d", scheduler->num_reply_blocked); assertf(scheduler->num_receive_blocked == 0, "Number of recive_blocked tasks is not zero. Count=%d", scheduler->num_receive_blocked); */ /* * After careful consideration, I've concluded that it is acceptable for a task * to terminate in the event blocked state. This is necessary for some events such * as waiting on keyboard input, which may never happen. assertf(scheduler->num_event_blocked == 0, "Number of event_blocked tasks is not zero. Count=%d", scheduler->num_event_blocked); */ print_memory_status(); robprintfbusy((const unsigned char *)"Finished in scheduler.... \n"); return 0; assert(0, "Shouldn't get here"); }