/*
   *  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;
  }
Esempio n. 2
0
  /**
   * 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
  }