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 // DiskRequestDone 00022 // Disk interrupt handler. Need this to be a C routine, because 00023 // C++ can't handle pointers to member functions. 00024 //---------------------------------------------------------------------- 00025 00026 static void 00027 DiskRequestDone (int arg) 00028 { 00029 SynchDisk* disk1 = (SynchDisk *)arg; 00030 00031 disk1->RequestDone(); 00032 } 00033 00034 //---------------------------------------------------------------------- 00035 // SynchDisk::SynchDisk 00036 // Initialize the synchronous interface to the physical disk, in turn 00037 // initializing the physical disk. 00038 // 00039 // "name" -- UNIX file name to be used as storage for the disk data 00040 // (usually, "DISK") 00041 //---------------------------------------------------------------------- 00042 00043 SynchDisk::SynchDisk(char* name) 00044 { 00045 semaphore = new Semaphore("synch disk", 0); 00046 lock = new Lock("synch disk lock"); 00047 disk = new Disk(name, DiskRequestDone, (int) this); 00048 } 00049 00050 //---------------------------------------------------------------------- 00051 // SynchDisk::~SynchDisk 00052 // De-allocate data structures needed for the synchronous disk 00053 // abstraction. 00054 //---------------------------------------------------------------------- 00055 00056 SynchDisk::~SynchDisk() 00057 { 00058 delete disk; 00059 delete lock; 00060 delete semaphore; 00061 } 00062 00063 //---------------------------------------------------------------------- 00064 // SynchDisk::ReadSector 00065 // Read the contents of a disk sector into a buffer. Return only 00066 // after the data has been read. 00067 // 00068 // "sectorNumber" -- the disk sector to read 00069 // "data" -- the buffer to hold the contents of the disk sector 00070 //---------------------------------------------------------------------- 00071 00072 void 00073 SynchDisk::ReadSector(int sectorNumber, char* data) 00074 { 00075 lock->Acquire(); // only one disk I/O at a time 00076 disk->ReadRequest(sectorNumber, data); 00077 semaphore->P(); // wait for interrupt 00078 lock->Release(); 00079 } 00080 00081 //---------------------------------------------------------------------- 00082 // SynchDisk::WriteSector 00083 // Write the contents of a buffer into a disk sector. Return only 00084 // after the data has been written. 00085 // 00086 // "sectorNumber" -- the disk sector to be written 00087 // "data" -- the new contents of the disk sector 00088 //---------------------------------------------------------------------- 00089 00090 void 00091 SynchDisk::WriteSector(int sectorNumber, char* data) 00092 { 00093 lock->Acquire(); // only one disk I/O at a time 00094 disk->WriteRequest(sectorNumber, data); 00095 semaphore->P(); // wait for interrupt 00096 lock->Release(); 00097 } 00098 00099 //---------------------------------------------------------------------- 00100 // SynchDisk::RequestDone 00101 // Disk interrupt handler. Wake up any thread waiting for the disk 00102 // request to finish. 00103 //---------------------------------------------------------------------- 00104 00105 void 00106 SynchDisk::RequestDone() 00107 { 00108 semaphore->V(); 00109 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002