112 lines
3.6 KiB
C++
112 lines
3.6 KiB
C++
// synchdisk.cc
|
|
// Routines to synchronously access the disk. The physical disk
|
|
// is an asynchronous device (disk requests return immediately, and
|
|
// an interrupt happens later on). This is a layer on top of
|
|
// the disk providing a synchronous interface (requests wait until
|
|
// the request completes).
|
|
//
|
|
// Use a semaphore to synchronize the interrupt handlers with the
|
|
// pending requests. And, because the physical disk can only
|
|
// handle one operation at a time, use a lock to enforce mutual
|
|
// exclusion.
|
|
//
|
|
// Copyright (c) 1992-1993 The Regents of the University of California.
|
|
// All rights reserved. See copyright.h for copyright notice and limitation
|
|
// of liability and disclaimer of warranty provisions.
|
|
|
|
#include "copyright.h"
|
|
#include "synchdisk.h"
|
|
|
|
//----------------------------------------------------------------------
|
|
// DiskRequestDone
|
|
// Disk interrupt handler. Need this to be a C routine, because
|
|
// C++ can't handle pointers to member functions.
|
|
//----------------------------------------------------------------------
|
|
|
|
static void
|
|
DiskRequestDone (void *arg)
|
|
{
|
|
SynchDisk* disk = (SynchDisk *)arg;
|
|
|
|
disk->RequestDone();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SynchDisk::SynchDisk
|
|
// Initialize the synchronous interface to the physical disk, in turn
|
|
// initializing the physical disk.
|
|
//
|
|
// "name" -- UNIX file name to be used as storage for the disk data
|
|
// (usually, "DISK")
|
|
//----------------------------------------------------------------------
|
|
|
|
SynchDisk::SynchDisk(const char* name)
|
|
{
|
|
semaphore = new Semaphore("synch disk", 0);
|
|
lock = new Lock("synch disk lock");
|
|
disk = new Disk(name, DiskRequestDone, this);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SynchDisk::~SynchDisk
|
|
// De-allocate data structures needed for the synchronous disk
|
|
// abstraction.
|
|
//----------------------------------------------------------------------
|
|
|
|
SynchDisk::~SynchDisk()
|
|
{
|
|
delete disk;
|
|
disk = NULL;
|
|
delete lock;
|
|
lock = NULL;
|
|
delete semaphore;
|
|
semaphore = NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SynchDisk::ReadSector
|
|
// Read the contents of a disk sector into a buffer. Return only
|
|
// after the data has been read.
|
|
//
|
|
// "sectorNumber" -- the disk sector to read
|
|
// "data" -- the buffer to hold the contents of the disk sector
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
SynchDisk::ReadSector(int sectorNumber, void* data)
|
|
{
|
|
lock->Acquire(); // only one disk I/O at a time
|
|
disk->ReadRequest(sectorNumber, data);
|
|
semaphore->P(); // wait for interrupt
|
|
lock->Release();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SynchDisk::WriteSector
|
|
// Write the contents of a buffer into a disk sector. Return only
|
|
// after the data has been written.
|
|
//
|
|
// "sectorNumber" -- the disk sector to be written
|
|
// "data" -- the new contents of the disk sector
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
SynchDisk::WriteSector(int sectorNumber, const void* data)
|
|
{
|
|
lock->Acquire(); // only one disk I/O at a time
|
|
disk->WriteRequest(sectorNumber, data);
|
|
semaphore->P(); // wait for interrupt
|
|
lock->Release();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SynchDisk::RequestDone
|
|
// Disk interrupt handler. Wake up any thread waiting for the disk
|
|
// request to finish.
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
SynchDisk::RequestDone()
|
|
{
|
|
semaphore->V();
|
|
}
|