/* * Create a thread object using the default constructor ThreadCB() and * associate this newly created thread with a task (provided as an * argument to the do create() method). * */ public static ThreadCB do_create(TaskCB task) { // It is important to keep in mind that each time control is transferred to // the operating system, it is seen as an opportunity to schedule a thread // to run. Therefore, regardless of whether the new thread was created // successfully, the dispatcher must be called (or else a warning will be issued) // There is a global constant (in IflThreadCB), called MaxThreadsPerTask. // If this number of threads per task is exceeded, no new thread should be // created for that task, and null should be returned. if (MaxThreadsPerTask <= task.getThreadCount()) { dispatch(); return null; } // To link a thread to its task, the method addThread() of class // IflTaskCB should be used and the thread’s task must be set using // the method setTask() of IflThreadCB.*/ ThreadCB thread = new ThreadCB(); // null should also be returned if addThread() returns FAILURE. You can // find out the number of threads a task currently has by calling the // method getThreadCount() on that task. if (task.addThread(thread) == FAILURE) { dispatch(); return null; } // Apparently I needed to add this after testing. 2 hours of debugging. Wow task.addThread(thread); thread.setTask(task); // If priority scheduling needs to be implemented, the do create() method must cor- // rectly assign the thread’s initial priority. The actual value of the priority depends // on the particular scheduling policy used. OSP 2 provides methods for setting and // querying the priority of both tasks and threads. The methods are setPriority() and // getPriority() in classes TaskCB and ThreadCB, respectively. thread.setPriority(randomGeneratedNumber.nextInt((10 - 1) + 1)); // Finally, the status of the new thread should be set to ThreadReady // and it should be placed in the ready queue. thread.setStatus(ThreadReady); // If priority is above below 10% or equal to move into the low priority thread. if (task.getPriority() <= 1) ThreadCB.lowPriorityQueue.addElement(thread); else ThreadCB.highPriorityQueue.addElement(thread); // If all is well, the thread object created by this method should be returned. dispatch(); return thread; }
/** * Sets the properties of a new task, passed as an argument. * * <p>Creates a new thread list, sets TaskLive status and creation time, creates and opens the * task's swap file of the size equal to the size (in bytes) of the addressable virtual memory. * * @return task or null @OSPProject Tasks */ public static TaskCB do_create() { TaskCB new_task = new TaskCB(); // criação da nova task HClock new_clock = new HClock(); // instância do relógio do sistema String path = SwapDeviceMountPoint + String.valueOf(new_task.getID()); // path do swap file new_task.new_thread = new ArrayList<ThreadCB>(); new_task.new_port = new ArrayList<PortCB>(); new_task.new_file = new ArrayList<OpenFile>(); new_task.setPageTable(new PageTable(new_task)); new_task.setCreationTime( new_clock.get()); // usa a instância do relógio, para setar o horário de criação da task new_task.setStatus(TaskLive); // seta o estado atual da task (TaskLive) new_task.setPriority(1); // como não foi especificado nenhuma prioridade na descrição, usamos 1 new_task.new_swap.create( path, (int) Math.pow( 2.0D, MMU.getVirtualAddressBits())); // tamanho da página deve ser 2^(número de bits do // ambiente) OpenFile save_swap = OpenFile.open(path, new_task); // abrimos o swap file new_task.setSwapFile( save_swap); // dizemos que o swap criado acima deve ser alocado a nossa task ThreadCB.create(new_task); // criamos a thread inicial if (save_swap == null) { // verificamos se o swap foi criado com sucesso new_task .new_thread .get(0) .dispatch(); // caso não tenha, dispachamos a thread criada acima (posição 0 do vetor) return null; // e retornamos uma task nula } return new_task; // se tudo ocorreu como esperado, retornamos a task criada inicialmente }