📄 richards.js.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// This is a JavaScript implementation of the Richards// benchmark from://// http://www.cl.cam.ac.uk/~mr10/Bench.html// // The benchmark was originally implemented in BCPL by// Martin Richards.var Richards = new BenchmarkSuite('Richards', 34886, [ new Benchmark("Richards", runRichards)]);/** * The Richards benchmark simulates the task dispatcher of an * operating system. **/function runRichards() { var scheduler = new Scheduler(); scheduler.addIdleTask(ID_IDLE, 0, null, COUNT); var queue = new Packet(null, ID_WORKER, KIND_WORK); queue = new Packet(queue, ID_WORKER, KIND_WORK); scheduler.addWorkerTask(ID_WORKER, 1000, queue); queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE); queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE); queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE); scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue); queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE); queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE); queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE); scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue); scheduler.addDeviceTask(ID_DEVICE_A, 4000, null); scheduler.addDeviceTask(ID_DEVICE_B, 5000, null); scheduler.schedule(); if (scheduler.queueCount != EXPECTED_QUEUE_COUNT || scheduler.holdCount != EXPECTED_HOLD_COUNT) { var msg = "Error during execution: queueCount = " + scheduler.queueCount + ", holdCount = " + scheduler.holdCount + "."; print(msg); }}var COUNT = 1000;/** * These two constants specify how many times a packet is queued and * how many times a task is put on hold in a correct run of richards. * They don't have any meaning a such but are characteristic of a * correct run so if the actual queue or hold count is different from * the expected there must be a bug in the implementation. **/var EXPECTED_QUEUE_COUNT = 2322;var EXPECTED_HOLD_COUNT = 928;/** * A scheduler can be used to schedule a set of tasks based on their relative * priorities. Scheduling is done by maintaining a list of task control blocks * which holds tasks and the data queue they are processing. * @constructor */function Scheduler() { this.queueCount = 0; this.holdCount = 0; this.blocks = new Array(NUMBER_OF_IDS); this.list = null; this.currentTcb = null; this.currentId = null;}var ID_IDLE = 0;var ID_WORKER = 1;var ID_HANDLER_A = 2;var ID_HANDLER_B = 3;var ID_DEVICE_A = 4;var ID_DEVICE_B = 5;var NUMBER_OF_IDS = 6;var KIND_DEVICE = 0;var KIND_WORK = 1;/** * Add an idle task to this scheduler. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task * @param {int} count the number of times to schedule the task */Scheduler.prototype.addIdleTask = function (id, priority, queue, count) { this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count));};/** * Add a work task to this scheduler. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task */Scheduler.prototype.addWorkerTask = function (id, priority, queue) { this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));};/** * Add a handler task to this scheduler. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task */Scheduler.prototype.addHandlerTask = function (id, priority, queue) { this.addTask(id, priority, queue, new HandlerTask(this));};/** * Add a handler task to this scheduler. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task */Scheduler.prototype.addDeviceTask = function (id, priority, queue) { this.addTask(id, priority, queue, new DeviceTask(this))};/** * Add the specified task and mark it as running. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task * @param {Task} task the task to add */Scheduler.prototype.addRunningTask = function (id, priority, queue, task) { this.addTask(id, priority, queue, task); this.currentTcb.setRunning();};/** * Add the specified task to this scheduler. * @param {int} id the identity of the task * @param {int} priority the task's priority * @param {Packet} queue the queue of work to be processed by the task * @param {Task} task the task to add */Scheduler.prototype.addTask = function (id, priority, queue, task) { this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task); this.list = this.currentTcb; this.blocks[id] = this.currentTcb;};/** * Execute the tasks managed by this scheduler. */Scheduler.prototype.schedule = function () { this.currentTcb = this.list; while (this.currentTcb != null) { if (this.currentTcb.isHeldOrSuspended()) { this.currentTcb = this.currentTcb.link; } else { this.currentId = this.currentTcb.id; this.currentTcb = this.currentTcb.run(); } }};/** * Release a task that is currently blocked and return the next block to run. * @param {int} id the id of the task to suspend */Scheduler.prototype.release = function (id) { var tcb = this.blocks[id]; if (tcb == null) return tcb; tcb.markAsNotHeld(); if (tcb.priority > this.currentTcb.priority) { return tcb; } else { return this.currentTcb; }};/** * Block the currently executing task and return the next task control block * to run. The blocked task will not be made runnable until it is explicitly * released, even if new work is added to it. */Scheduler.prototype.holdCurrent = function () { this.holdCount++; this.currentTcb.markAsHeld(); return this.currentTcb.link;};/** * Suspend the currently executing task and return the next task control block * to run. If new work is added to the suspended task it will be made runnable. */Scheduler.prototype.suspendCurrent = function () { this.currentTcb.markAsSuspended(); return this.currentTcb;};/** * Add the specified packet to the end of the worklist used by the task * associated with the packet and make the task runnable if it is currently * suspended. * @param {Packet} packet the packet to add */Scheduler.prototype.queue = function (packet) { var t = this.blocks[packet.id]; if (t == null) return t; this.queueCount++; packet.link = null; packet.id = this.currentId; return t.checkPriorityAdd(this.currentTcb, packet);};/** * A task control block manages a task and the queue of work packages associated * with it. * @param {TaskControlBlock} link the preceding block in the linked block list * @param {int} id the id of this block * @param {int} priority the priority of this block * @param {Packet} queue the queue of packages to be processed by the task * @param {Task} task the task * @constructor */function TaskControlBlock(link, id, priority, queue, task) { this.link = link; this.id = id; this.priority = priority; this.queue = queue; this.task = task; if (queue == null) { this.state = STATE_SUSPENDED; } else { this.state = STATE_SUSPENDED_RUNNABLE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -