Subversion Repositories programming

Rev

Rev 415 | Rev 417 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
412 ira 1
/*******************************************************************************
415 ira 2
 * Scheduler.java
412 ira 3
 *
4
 * Holds the Scheduler class, which has a generic scheduler class, from which
5
 * all schedulers should be derived.
6
 *
7
 * Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in
17
 * all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25
 * IN THE SOFTWARE.
26
 ******************************************************************************/
27
 
413 ira 28
import java.util.Vector;
29
 
415 ira 30
/**
31
 * Base class for all of the specific Schedulers used in Project #1.
32
 *
33
 * @class CS431 Fall 2006
34
 * @author Ira W. Snyder (devel@irasnyder.com)
35
 */
36
public abstract class Scheduler
412 ira 37
{
415 ira 38
    /** The Processes that can currently be scheduled */
413 ira 39
    protected Vector<Process> run_queue;
415 ira 40
 
41
    /** A log of important transitions in the Scheduler */
413 ira 42
    protected Vector<LogEntry> log;
415 ira 43
 
44
    /** The current time in this scheduler */
413 ira 45
    protected int cur_time = 0;
415 ira 46
 
47
    /** The process that is currently running on the CPU */
413 ira 48
    protected Process cur_proc;
49
 
415 ira 50
    /**
51
     * Constructor of the Scheduler class.
52
     */
53
    public Scheduler ()
54
    {
55
        this.run_queue = new Vector<Process> ();
56
        this.log = new Vector<LogEntry> ();
57
    }
58
 
59
    /**
60
     * This method must be overridden by an implementer of a Scheduler. It
61
     * will implement the specific behaivior of the specific Scheduler that
62
     * is being implemented.
63
     *
64
     * @return true if we have more things to do, false if we are done
65
     */
413 ira 66
    protected abstract boolean step ();
67
 
68
    /**
69
     * Add a new process to the run queue.
415 ira 70
     * <p>
413 ira 71
     * If you need to support time-delayed processes, then you must override
72
     * this method, and handle pulling them into the run_queue yourself.
415 ira 73
     *
74
     * @param proc the Process to add
75
     * @param add_time the time that this process should be added to the run queue
413 ira 76
     */
77
    public void addProcess (Process proc, int add_time)
78
    {
79
        run_queue.add (new Process(proc));
80
    }
81
 
82
    /**
83
     * Expire the currently running process.
415 ira 84
     * <p>
85
     * This removes the current process from the CPU and re-adds it to the
86
     * run_queue. It also logs the expiration.
413 ira 87
     */
88
    protected void expireCurrent ()
89
    {
90
        assert (cur_proc.time_left > 0);
91
 
92
        cur_proc.finished_at = cur_time;
93
 
94
        run_queue.add (cur_proc);
95
        log.add (new LogEntry (cur_proc, cur_time, LogEntry.MsgType.EXPIRE));
96
        cur_proc = null;
97
    }
98
 
415 ira 99
    /**
100
     * Terminate the currently running process.
101
     * <p>
102
     * This should be called if the process has no time left to run.
103
     */
413 ira 104
    protected void completeCurrent ()
105
    {
106
        assert (cur_proc.time_left == 0);
107
 
108
        cur_proc.finished_at = cur_time;
109
 
110
        log.add (new LogEntry (cur_proc, cur_time, LogEntry.MsgType.COMPLETE));
111
        cur_proc = null;
112
    }
113
 
415 ira 114
    /**
115
     * Move a process from the run_queue to the CPU. This removes it from the
116
     * run_queue. Then it adds a log entry.
117
     * 
118
     * @param proc move this process from the run_queue to the CPU
119
     */
413 ira 120
    protected void startProcess (Process proc)
121
    {
122
        cur_proc = proc;
123
        cur_proc.started_at = cur_time;
124
        run_queue.remove (cur_proc);
125
 
126
        log.add (new LogEntry (cur_proc, cur_time, LogEntry.MsgType.START));
127
    }
128
 
415 ira 129
    /**
416 ira 130
     * Run the current process, increment the current time, and update the wait
131
     * times for all of the processes that are waiting.
415 ira 132
     */
413 ira 133
    protected void scheduleCurrent ()
134
    {
416 ira 135
        /* Update the wait times for all waiting processes */
136
        for (Process p : run_queue)
137
            p.time_wait++;
138
 
139
        /* Run the current process for one tick */
413 ira 140
        cur_proc.time_left--;
416 ira 141
 
142
        /* Update the time */
413 ira 143
        cur_time++;
144
    }
145
 
415 ira 146
    /**
147
     * Print a Gantt Chart detailing the results of this scheduler's run.
148
     */
414 ira 149
    protected void printGanttChart ()
150
    {
151
        Vector<String> t = new Vector<String> ();
152
        Vector<String> l = new Vector<String> ();
153
 
154
        String timeline = new String();
155
        String labels = new String();
156
        String add1 = new String();
157
        String add2 = new String();
158
 
159
        int exptime = 0;
160
        int templen;
161
 
162
        for (LogEntry e : log)
163
        {
164
            if (e.msg == LogEntry.MsgType.EXPIRE || e.msg == LogEntry.MsgType.COMPLETE)
165
            {
166
                exptime = e.time;
167
                continue;
168
            }
169
 
170
            add1 = "|---" + e.proc.name + "---";
171
            add2 = "" + e.time;
172
 
173
            for (int i=0; add2.length() < add1.length(); i++)
174
                add2 += " ";
175
 
176
            if (timeline.length() + add1.length() > 79)
177
            {
178
                t.add (timeline + "|");
179
                templen = labels.length() - String.valueOf(exptime).length();
180
                labels = labels.substring (0, templen+1) + String.valueOf(exptime);
181
                l.add (labels);
415 ira 182
 
183
                /* Clear the current timeline and labels */
414 ira 184
                timeline = new String();
185
                labels = new String();
186
            }
187
 
188
            timeline += add1;
189
            labels += add2;
190
        }
191
 
192
        /* Done, add the last values of timeline and labels to the Vectors */
193
        t.add (timeline + "|");
194
        templen = labels.length() - String.valueOf(exptime).length();
195
        labels = labels.substring (0, templen+1) + String.valueOf(exptime);
196
        l.add (labels);
197
 
198
        assert (l.size() == t.size());
199
 
200
        for (int i=0; i<l.size(); i++)
201
        {
202
            System.out.println (t.elementAt (i));
203
            System.out.println (l.elementAt (i));
204
            System.out.println ();
205
        }
206
    }
207
 
415 ira 208
    /**
416 ira 209
     * Find the average wait time of processes.
210
     */
211
    protected void printWaitTimes ()
212
    {
213
        int numprocs = 0;
214
        int totalwait = 0;
215
 
216
        for (LogEntry e : log)
217
        {
218
            if (e.msg == LogEntry.MsgType.COMPLETE)
219
            {
220
                numprocs++;
221
                totalwait += e.proc.time_wait;
222
            }
223
        }
224
 
225
        System.out.printf ("Average wait time: %d wait time / %d procs = %.2f\n",
226
                totalwait, numprocs, (float)totalwait / (float)numprocs);
227
    }
228
 
229
    /**
415 ira 230
     * Run the simulation of the scheduler. Note that this only works once,
231
     * if you try to run it twice, it is unlikely that it will work.
232
     */
413 ira 233
    public void run ()
234
    {
235
        /* Keep step()ing until we're done */
236
        while (step ())
237
            ; // do nothing
238
 
414 ira 239
        /* Verbose print of each log entry */
240
        //for (LogEntry e : log)
241
        //   System.out.println (e);
413 ira 242
 
414 ira 243
        /* Gantt Chart */
244
        printGanttChart ();
245
 
413 ira 246
        /* Print time taken */
416 ira 247
        printWaitTimes ();
248
        System.out.println ("Simulation took " + cur_time + " time units to complete!");
413 ira 249
    }
412 ira 250
}
251
 
252
/* vim: set ts=4 sts=4 sw=4 expandtab: */
253