class Disk; // // DiskArm // // Represents the arm on a disk, which holds the heads that // can scan across platters. // class DiskArm { public: // The number of milliseconds it takes to warm up the arm. static const int ARM_START = 4; // The number of milliseconds it takes for the arm to move from // the first to the last cylinder after it has begun. This // represents the arm's velocity. static const int ARM_SCAN = 14; // Returns the disk in which the arm is. Disk *getDisk() { return disk; } // Returns the index of the arm among the arms on the disk. int getIndex() { return index; } // Returns the total time spent by the disk arm thus far. double getTimeElapsed() { return time_elapse; } // Returns the index of the current cylinder where the arm points. int getCurCylinder() { return cur_pos; } private: Disk *disk; int cur_pos; int index; double time_elapse; DiskArm(Disk *disk, int index); // Moves the arm to cylinder !cylinder!. (Should only be accessed // within RequestQueue::serveRequest().) void moveTo(int cylinder); void reset(); friend class Disk; friend class RequestQueue; }; // // Disk // // Represents a disk, which can hold many arms and any number of // cylinders. Both are parameters specified in the constructor method. // class Disk { public: // Creates a disk with !num_arms! arms and !num_cyls! cylinders. Disk(int num_arms, int num_cyls); // Returns the number of arms in the disk. int getNumArms() { return num_arms; } // Returns the number of cylinders in the disk. int getNumCylinders() { return num_cyls; } // Returns the arm with index !index!. (Arms are indexed beginning // at 0 and going up to getNumArms() - 1.) DiskArm *getArm(int index); // Returns the arm which is first ready to handle a new request // among those who are ready at time !time!. // This will be the arm for which the least time has elapsed. DiskArm *getReadyArm(double time); // Resets the disk to the initial state. void reset(); private: int num_arms; int num_cyls; DiskArm **arms; }; // // Process // // Represents a process that generates a sequence of NUM_REQS // random disk requests. // class Process { public: // Returns the cylinder number of the current disk request // by the process, or -1 if all the requests of the process have // been fulfilled. int getCurRequest() { return suspended ? -1 : req[num_reqs]; } private: static const int NUM_REQS = 1000; int *req; int num_reqs; bool suspended; Process(int num_cyls); // Suspends or releases the process. void setSuspended(bool value) { suspended = value; } // Steps to the next request. void nextRequest() { if(num_reqs < NUM_REQS) ++num_reqs; } // Returns true if the process has completed all requests. int isComplete() { return num_reqs == NUM_REQS; } friend class RequestQueue; }; // // RequestQueue // // Represents a set of processes vying for a disk. As you're going // through the simulation, you can use such an object to get any of the // processes, and you can use the object to actually service a request. // class RequestQueue { public: static const int MAX_PROCS = 4096; // Creates a RequestQueue representing !num_proc! processes // vying for a disk with !num_cyls! cylinders. RequestQueue(int num_proc, int num_cyls); // Returns the total number of processes that this RequestQueue // is handling. int getNumProcesses() { return num_proc; } // Returns the specific process whose index is !which!. (The // processes are indexed beginning at 0, going up to // getNumProcesses() - 1.) Process* getProcess(int which); // Returns the number of requests that have been completed so far. int getNumServices() { return num_served; } // Returns the average square of the waiting time for the requests // that have been completed so far. double getTimeElapsed() { return now; } // Returns the average square of the waiting time for the requests // that have been completed so far. double getMeanSquareWait(); // Returns true if any of the processes have requests still to // complete. bool hasRequestsPending(); // Serves the current request of process with index !which! // using the disk arm !arm!. void serveRequest(DiskArm *arm, int which); private: int num_proc; Process **proc; double *time_begun; double sum_square_wait; int num_served; double now; };