📄 iosys
字号:
caused them to sleep no longer hold..PPPriorities can range from 0 to 127;a higher numerical value indicates a less-favoredscheduling situation.A distinction is made between processes sleepingat priority less than the parameter.I PZEROand those at numerically larger priorities.The former cannotbe interrupted by signals, although itis conceivable that it may be swapped out.Thus it is a bad idea to sleep withpriority less than PZERO on an event which might never occur.On the other hand, calls to.I sleepwith larger prioritymay never return if the process is terminated bysome signal in the meantime.Incidentally, it is a gross error to call.I sleepin a routine called at interrupt time, since the processwhich is running is almost certainly not theprocess which should go to sleep.Likewise, none of the variables in the user area``\fIu\fB.\fR''should be touched, let alone changed, by an interrupt routine..PPIf a device driverwishes to wait for some event for which it is inconvenientor impossible to supply a.I wakeup,(for example, a device going on-line, which does notgenerally cause an interrupt),the call.I "sleep(&lbolt, priority)may be given..I Lboltis an external cell whose address is awakened once every 4 secondsby the clock interrupt routine..PPThe routines.I "spl4( ), spl5( ), spl6( ), spl7( )"are available toset the processor priority level as indicated to avoidinconvenient interrupts from the device..PPIf a device needs to know about real-time intervals,then.I "timeout(func, arg, interval)will be useful.This routine arranges that after.I intervalsixtieths of a second, the.I funcwill be called with.I argas argument, in the style.I "(*func)(arg).Timeouts are used, for example,to provide real-time delays after function characterslike new-line and tab in typewriter output,and to terminate an attempt toread the 201 Dataphone.I dpif there is no response within a specified numberof seconds.Notice that the number of sixtieths of a second is limited to 32767,since it must appear to be positive,and that only a bounded number of timeoutscan be going on at once.Also, the specified.I funcis called at clock-interrupt time, so it shouldconform to the requirements of interrupt routinesin general..SHThe Block-device Interface.PPHandling of block devices is mediated by a collectionof routines that manage a set of buffers containingthe images of blocks of data on the various devices.The most important purpose of these routines is to assurethat several processes that access the same block of the samedevice in multiprogrammed fashion maintain a consistentview of the data in the block.A secondary but still important purpose is to increasethe efficiency of the system bykeeping in-core copies of blocks that are beingaccessed frequently.The main data base for this mechanism is thetable of buffers.I buf.Each buffer header contains a pair of pointers.I "(b_forw, b_back)"which maintain a doubly-linked listof the buffers associated with a particularblock device, and apair of pointers.I "(av_forw, av_back)"which generally maintain a doubly-linked list of blockswhich are ``free,'' that is,eligible to be reallocated for another transaction.Buffers that have I/O in progressor are busy for other purposes do not appear in this list.The buffer headeralso contains the device and block number to which thebuffer refers, and a pointer to the actual storage associated withthe buffer.There is a word countwhich is the negative of the number of wordsto be transferred to or from the buffer;there is also an error byte and a residual wordcount used to communicate informationfrom an I/O routine to its caller.Finally, there is a flag wordwith bits indicating the status of the buffer.These flags will be discussed below..PPSeven routines constitutethe most important part of the interface with therest of the system.Given a device and block number,both.I breadand.I getblkreturn a pointer to a buffer header for the block;the difference is that.I breadis guaranteed to return a buffer actually containing thecurrent data for the block,while.I getblkreturns a buffer which contains the data in theblock only if it is already in core (whether it isor not is indicated by the.I B_DONEbit; see below).In either case the buffer, and the correspondingdevice block, is made ``busy,''so that other processes referring to itare obliged to wait until it becomes free..I Getblkis used, for example,when a block is about to be totally rewritten,so that its previous contents arenot useful;still, no other process can be allowed to refer to the blockuntil the new data is placed into it..PPThe.I breadaroutine is used to implement read-ahead.it is logically similar to.I bread,but takes as an additional argument the number ofa block (on the same device) to be read asynchronouslyafter the specifically requested block is available..PPGiven a pointer to a buffer,the.I brelseroutinemakes the buffer again available to other processes.It is called, for example, afterdata has been extracted following a.I bread.There are three subtly-different write routines,all of which take a buffer pointer as argument,and all of which logically release the buffer foruse by others and place it on the free list..I Bwriteputs thebuffer on the appropriate device queue,waits for the write to be done,and sets the user's error flag if required..I Bawriteplaces the buffer on the device's queue, but does not waitfor completion, so that errors cannot be reflected directly tothe user..I Bdwritedoes not start any I/O operation at all,but merely marksthe buffer so that if it happensto be grabbed from the free list to containdata from some other block, the data in it willfirst be writtenout..PP.I Bwriteis used when one wants to be sure thatI/O takes place correctly, and thaterrors are reflected to the proper user;it is used, for example, when updating i-nodes..I Bawriteis useful when more overlap is desired(because no wait is required for I/O to finish)but when it is reasonably certain that thewrite is really required..I Bdwriteis used when there is doubt that the write isneeded at the moment.For example,.I bdwriteis called when the last byte of a.I writesystem call falls short of the end of ablock, on the assumption thatanother.I writewill be given soon which will re-use the same block.On the other hand,as the end of a block is passed,.I bawriteis called, since probably the block willnot be accessed again soon and one might aswell start the writing process as soon as possible..PPIn any event, notice that the routines.I "getblk"and.I breaddedicate the given block exclusively to theuse of the caller, and make others wait,while one of.I "brelse, bwrite, bawrite,"or.I bdwritemust eventually be called to free the block for use by others..PPAs mentioned, each buffer header contains a flagword which indicates the status of the buffer.Since they provideone important channel for information between the drivers and theblock I/O system, it is important to understand these flags.The following names are manifest constants whichselect the associated flag bits..IP B_READ 10This bit is set when the buffer is handed to the device strategy routine(see below) to indicate a read operation.The symbol.I B_WRITEis defined as 0 and does not define a flag; it is providedas a mnemonic convenience to callers of routines like.I swapwhich have a separate argumentwhich indicates read or write..IP B_DONE 10This bit is setto 0 when a block is handed to the the device strategyroutine and is turned on when the operation completes,whether normally as the result of an error.It is also used as part of the return argument of.I getblkto indicate if 1 that the returnedbuffer actually contains the data in the requested block..IP B_ERROR 10This bit may be set to 1 when.I B_DONEis set to indicate that an I/O or other error occurred.If it is set the.I b_errorbyte of the buffer header may contain an error codeif it is non-zero.If.I b_erroris 0 the nature of the error is not specified.Actually no driver at present sets.I b_error;the latter is provided for a future improvementwhereby a more detailed error-reportingscheme may be implemented..IP B_BUSY 10This bit indicates that the buffer header is not onthe free list, i.e. isdedicated to someone's exclusive use.The buffer still remains attached to the list ofblocks associated with its device, however.When.I getblk(or.I bread,which calls it) searches the buffer listfor a given device and finds the requestedblock with this bit on, it sleeps until the bitclears..IP B_PHYS 10This bit is set for raw I/O transactions thatneed to allocate the Unibus map on an 11/70..IP B_MAP 10This bit is set on buffers that have the Unibus map allocated,so that the.I iodoneroutine knows to deallocate the map..IP B_WANTED 10This flag is used in conjunction with the.I B_BUSYbit.Before sleeping as describedjust above,.I getblksets this flag.Conversely, when the block is freed and the busy bitgoes down (in.I brelse)a.I wakeupis given for the block header whenever.I B_WANTEDis on.This strategem avoids the overheadof having to call.I wakeupevery time a buffer is freed on the chance that someonemight want it..IP B_AGEThis bit may be set on buffers just before releasing them; if itis on,the buffer is placed at the head of the free list, rather than at thetail.It is a performance heuristicused when the caller judges that the same block will not soon be used again..IP B_ASYNC 10This bit is set by.I bawriteto indicate to the appropriate device driverthat the buffer should be released when thewrite has been finished, usually at interrupt time.The difference between.I bwriteand.I bawriteis that the former starts I/O, waits until it is done, andfrees the buffer.The latter merely sets this bit and starts I/O.The bit indicates that.I relseshould be called for the buffer on completion..IP B_DELWRI 10This bit is set by.I bdwritebefore releasing the buffer.When.I getblk,while searching for a free block,discovers the bit is 1 in a buffer it would otherwise grab,it causes the block to be written out before reusing it..SHBlock Device Drivers.PPThe.I bdevswtable contains the names of the interface routinesand that of a table for each block device..PPJust as for character devices, block device drivers may supplyan.I openand a.I closeroutinecalled respectively on each open and on the final closeof the device.Instead of separate read and write routines,each block device driver has a.I strategyroutine which is called with a pointer to a bufferheader as argument.As discussed, the buffer header containsa read/write flag, the core address,the block number, a (negative) word count,and the major and minor device number.The role of the strategy routineis to carry out the operation as requested by theinformation in the buffer header.When the transaction is complete the.I B_DONE(and possibly the.I B_ERROR)bits should be set.Then if the.I B_ASYNCbit is set,.I brelseshould be called;otherwise,.I wakeup.In cases where the deviceis capable, under error-free operation,of transferring fewer words than requested,the device's word-count register should be placedin the residual count slot ofthe buffer header;otherwise, the residual count should be set to 0.This particular mechanism is really for the benefitof the magtape driver;when reading this devicerecords shorter than requested are quite normal,and the user should be told the actual length of the record..PPAlthough the most usual argumentto the strategy routinesis a genuine buffer header allocated as discussed above,all that is actually requiredis that the argument be a pointer to a place containing theappropriate information.For example the.I swaproutine, which manages movementof core images to and from the swapping device,uses the strategy routinefor this device.Care has to be taken thatno extraneous bits get turned on in theflag word..PPThe device's table specified by.I bdevswhas abyte to contain an active flag and an error count,a pair of links which constitute thehead of the chain of buffers for the device.I "(b_forw, b_back),"and a first and last pointer for a device queue.Of these things, all are used solely by the device driveritselfexcept for the buffer-chain pointers.Typically the flag encodes the state of thedevice, and is used at a minimum toindicate that the device is currently engaged intransferring information and no new command should be issued.The error count is useful for counting retrieswhen errors occur.The device queue is used to remember stacked requests;in the simplest case it may be maintained as a first-infirst-out list.Since buffers which have been handed over tothe strategy routines are neveron the list of free buffers,the pointers in the buffer which maintain the free list.I "(av_forw, av_back)"are also used to contain the pointerswhich maintain the device queues..PPA couple of routinesare provided which are useful to block device drivers..I "iodone(bp)"arranges that the buffer to which.I bppoints be released or awakened,as appropriate,when thestrategy module has finished with the buffer,either normally or after an error.(In the latter case the.I B_ERRORbit has presumably been set.).PPThe routine.I "geterror(bp)"can be used to examine the error bit in a buffer headerand arrange that any error indication found therein isreflected to the user.It may be called only in the non-interruptpart of a driver when I/O has completed.I (B_DONEhas been set)..SHRaw Block-device I/O.PPA scheme has been set up whereby block device drivers mayprovide the ability to transfer informationdirectly between the user's core image and the devicewithout the use of buffers and in blocks as large asthe caller requests.The method involves setting up a character-type special filecorresponding to the raw deviceand providing.I readand.I writeroutines which set up what is usually a private,non-shared buffer header with the appropriate informationand call the device's strategy routine.If desired, separate.I openand.I closeroutines may be provided but this is usually unnecessary.A special-function routine might come in handy, especially formagtape..PPA great deal of work has to be done to generate the``appropriate information''to put in the argument buffer forthe strategy module;the worst part is to map relocated user addresses to physical addresses.Most of this work is done by.I "physio(strat, bp, dev, rw)whose arguments are the name of thestrategy routine.I strat,the buffer pointer.I bp,the device number.I dev,and a read-write flag.I rwwhose value is either.I B_READor.I B_WRITE..I Physiomakes sure that the user's base address and count areeven (because most devices work in words)and that the core area affected is contiguousin physical space;it delays until the buffer is not busy, and makes itbusy while the operation is in progress;and it sets up user error return information.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -