00001 // synchdisk.cc 00002 // Routines to synchronously access the disk. The physical disk 00003 // is an asynchronous device (disk requests return immediately, and 00004 // an interrupt happens later on). This is a layer on top of 00005 // the disk providing a synchronous interface (requests wait until 00006 // the request completes). 00007 // 00008 // Use a semaphore to synchronize the interrupt handlers with the 00009 // pending requests. And, because the physical disk can only 00010 // handle one operation at a time, use a lock to enforce mutual 00011 // exclusion. 00012 // 00013 // Copyright (c) 1992-1993 The Regents of the University of California. 00014 // All rights reserved. See copyright.h for copyright notice and limitation 00015 // of liability and disclaimer of warranty provisions. 00016 00017 #include "copyright.h" 00018 #include "synchdisk.h" 00019 00020 00021 //---------------------------------------------------------------------- 00022 // SynchDisk::SynchDisk 00023 // Initialize the synchronous interface to the physical disk, in turn 00024 // initializing the physical disk. 00025 // 00026 //---------------------------------------------------------------------- 00027 00028 SynchDisk::SynchDisk() 00029 { 00030 semaphore = new Semaphore("synch disk", 0); 00031 lock = new Lock("synch disk lock"); 00032 disk = new Disk(this); 00033 } 00034 00035 //---------------------------------------------------------------------- 00036 // SynchDisk::~SynchDisk 00037 // De-allocate data structures needed for the synchronous disk 00038 // abstraction. 00039 //---------------------------------------------------------------------- 00040 00041 SynchDisk::~SynchDisk() 00042 { 00043 delete disk; 00044 delete lock; 00045 delete semaphore; 00046 } 00047 00048 //---------------------------------------------------------------------- 00049 // SynchDisk::ReadSector 00050 // Read the contents of a disk sector into a buffer. Return only 00051 // after the data has been read. 00052 // 00053 // "sectorNumber" -- the disk sector to read 00054 // "data" -- the buffer to hold the contents of the disk sector 00055 //---------------------------------------------------------------------- 00056 00057 void 00058 SynchDisk::ReadSector(int sectorNumber, char* data) 00059 { 00060 lock->Acquire(); // only one disk I/O at a time 00061 disk->ReadRequest(sectorNumber, data); 00062 semaphore->P(); // wait for interrupt 00063 lock->Release(); 00064 } 00065 00066 //---------------------------------------------------------------------- 00067 // SynchDisk::WriteSector 00068 // Write the contents of a buffer into a disk sector. Return only 00069 // after the data has been written. 00070 // 00071 // "sectorNumber" -- the disk sector to be written 00072 // "data" -- the new contents of the disk sector 00073 //---------------------------------------------------------------------- 00074 00075 void 00076 SynchDisk::WriteSector(int sectorNumber, char* data) 00077 { 00078 lock->Acquire(); // only one disk I/O at a time 00079 disk->WriteRequest(sectorNumber, data); 00080 semaphore->P(); // wait for interrupt 00081 lock->Release(); 00082 } 00083 00084 //---------------------------------------------------------------------- 00085 // SynchDisk::CallBack 00086 // Disk interrupt handler. Wake up any thread waiting for the disk 00087 // request to finish. 00088 //---------------------------------------------------------------------- 00089 00090 void 00091 SynchDisk::CallBack() 00092 { 00093 semaphore->V(); 00094 }