⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iosys

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻
📖 第 1 页 / 共 3 页
字号:
which deal with multiple similar devicesto encode the minor device number.After the interrupt has been processed,a return from the interrupt handler willreturn from the interrupt itself..pgA number of subroutines are available which are usefulto character device drivers.Most of these handlers, for example, need a placeto buffer characters in the internal interfacebetween their ``top half'' (read/write)and ``bottom half'' (interrupt) routines.For relatively low data-rate devices, the best mechanismis the character queue maintained by theroutines.it getcand.it putc.A queue header has the structure.pg.in 5.ft I.nfstruct {	int	c_cc;	/* character count */	char	*c_cf;	/* first character */	char	*c_cl;	/* last character */} queue;.pg.ft R.in 0.fiA character is placed on the end of a queue by.pg.ti 5.it "putc(c, &queue)".pgwhere.it cis the character and.it queueis the queue header.The routine returns \(mi1 if there is no spaceto put the character, 0 otherwise.The first character on the queue may be retrievedby.pg.ti 5.it "getc(&queue)".pgwhich returns either the (non-negative) characteror \(mi1 if the queue is empty..pgNotice that the space for characters in queues isshared among all devices in the systemand in the standard system there are only some 600character slots available.Thus device handlers,especially write routines, must takecare to avoid gobbling up excessive numbers of characters..pgThe other major help availableto device handlers is the sleep-wakeup mechanism.The call.pg.ti 5.it "sleep(event, priority)".pgcauses the process to wait (allowing other processes to run)until the.it eventoccurs;at that time, the process is marked ready-to-runand the call will return when there is noprocess with higher.it priority..pgThe call.pg.ti 5.it "wakeup(event)".pgindicates that the.it eventhas happened, that is, causes processes sleepingon the event to be awakened.The.it eventis an arbitrary quantity agreed uponby the sleeper and the waker-up.By convention, it is the address of some data area usedby the driver, which guarantees that eventsare unique..pgProcesses sleeping on an event should not assumethat the event has really happened;they should check that the conditions whichcaused them to sleep no longer hold..pgPriorities can range from 127 to \(mi127;a higher numerical value indicates a less-favoredscheduling situation.A process sleeping at negative priority cannotbe terminated for any reason, although itis conceivable that it may be swapped out.Thus it is a bad idea to sleep with negativepriority on an event which might never occur.On the other hand, calls to.it sleepwith non-negative prioritymay never return if the process is terminated bysome signal in the meantime.Incidentally, it is a gross error to call.it 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..pgIf a device driverwishes to wait for some event for which it is inconvenientor impossible to supply a.it wakeup,(for example, a device going on-line, which does notgenerally cause an interrupt),the call.pg.ti 5.it "sleep(&lbolt, priority).pgmay be given..it Lboltis an external cell whose address is awakened once every 4 secondsby the clock interrupt routine..pgThe routines.pg.ti 5.it "spl4( ), spl5( ), spl6( ), spl7( )".pgare available toset the processor priority level as indicated to avoidinconvenient interrupts from the device..pgIf a device needs to know about real-time intervals,then.pg.ti 5.it "timeout(func, arg, interval).pgwill be useful.This routine arranges that after.it intervalsixtieths of a second, the.it funcwill be called with.it argas argument, in the style.pg.ti 5.it "(*func)(arg).pgTimeouts 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.it 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.it funcis called at clock-interrupt time, so it shouldconform to the requirements of interrupt routinesin general..ms "An example"The driver for the paper-tapereader/punch is worth examiningas a fairly simple example ofmany of the techniques used in writingcharacter device handlers.The.it pc11structure contains a state (used for the reader),an input queue, and an output queue.A structure, rather than threeindividual variables,was used to cut down on the number ofexternal symbols which might be confusedwith symbols in other routines..pgWhen the file is opened for reading,the.it openroutine checks to see if its state is not.it CLOSED;if so an error is returned since it is considereda bad idea to let several people read one tapesimultaneously.The state is set to.it WAITING,the interrupt is enabled, and a character is requested.The reason for this gambit is that there is no direct way todetermine if there is any tape in the readeror if the reader is on-line.In these situations an interrupt will occurimmediately and an error indicated.As will be seen, the interrupt routineignores errors if the state is.it WAITING,but if a good character comes in whilein the.it WAITINGstate the interrupt routine sets the state to.it READING.Thus.it openloops until the state changes, meanwhilesleeping on the``lightning bolt''.it lbolt.If it did not sleep at all, it would preventany other process from running until the reader came on-line;if it depended on the interrupt routine to wake it up,the effect would be the same, since the errorinterrupt is almost instantaneous..pgThe open-write case is much simpler; thepunch is enabled and a 100-character leader is punchedusing.it pcleader..pgThe.it closeroutine is also simple; if the reader was open,any uncollected characters are flushed,the interrupt is turned off, andthe state is set to.it CLOSED.In the write case a 100-character traileris punched.The routine has a bug in thatif both the reader and punch are open.it closewill be called only once, so that either theleftover characters are flushedor the trailer is punched,but not both.It is hard to see how to fix this problemexcept by making the reader and punch separate devices..pgThe.it pcreadroutinetries to pick up characters from the input queueand passes them back until the user's read callis satisfied.If thereare no characters it checkswhether the state has gone to.it EOF,which means that the interrupt routinedetected an error in the.it READstate (assumed to indicate the end of the tape).If so,.it pcreadreturns;either during this call or the next one no characters willbe passed back, indicating an end-of-file.If the state is still.it READINGthe routine enables another character by fiddling thedevice's reader control register,provided it is not active,and goes to sleep..pgWhen a reader interrupt occursand the state is.it WAITING,and the device's error bit is set,the interrupt is ignored;if there is no error the state is set to.it READING,as indicated in the discussionof.it pcread.If the state is.it READINGand there is an error, the state is set to.it EOF;it is assumed that the error representsthe end of the tape.If there is no error, the character is picked up andstored in the input queue.Then, provided the number of charactersalready in the queue is less than thehigh-water mark.it PCIHWAT,the reader is enabled again to read another character.This strategy keeps the tape movingwithout flooding the input queue with unread characters.Finally, the top half is awakened..pgLooking again at.it pcread,notice thatthe priority  level is raisedby.it "spl4( )"to prevent interrupts during the loop.This is done because of thepossibility that the input queue is empty,and just after the EOF test is madean error interrupt occurs because thetape runs out.Then.it sleepwill be called with no possibility ofa.it wakeup.In general the processor priorityshould be raisedwhen a routine is aboutto sleep awaiting some condition where thepresence of the condition, and the consequent.it wakeup,is indicated by an interrupt.The danger is thatthe interrupt might occur betweenthe test for the condition and the call to.it sleep,so that the.it wakeupapparently never happens..pgAt the same time it is a bad idea toraise the processor priority levelfor an extended period of time,since devices with real-timerequirements may be shut out so long as to cause anerror.The.it pcreadroutine is perhaps overzealousin this respect, although since mostdevices have a priority level higher than 4this difficulty is not very important..pgThe.it pcwriteroutine simply gets characters from the userand passes them to.it pcoutput,which is separated out so that.it pcleadercan call it also..it Pcoutputchecks for errors (like out-of-tape)and if none are presentmakes sure thatthe number of characters in the output queuedoes not exceed.it PCOHWAT;if it does,.it sleepis called.Then the character is placed on the output queue.There is a small bug here in that.it pcoutputdoes not check thatthe character was successfully put on the queue(all character-queue space might be empty);perhaps in this case it might be a good idea tosleep on the lightning-boltuntil things quiet down.Finally.it pcstartis called,which checks to see if the punch is currently busy,and if not starts the punching of thefirst character on the output queue..pgWhen punch interrupts occur,.it pcpintis called;it starts the punching of the next character on the outputqueue,and if the number of characters remaining on the queue isless than the low-water mark.it PCOLWATitwakes up the write routine,which is presumably waiting for the queue toempty..MS "The Block-device Interface"Handling of block devices is mediated by a collectionof routines which 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 which 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 which are beingaccessed frequently.The main data base for this mechanism is thetable of buffers.it buf.Each buffer header contains a pair of pointers.it "(b_forw, b_back)"which maintain a doubly-linked listof the buffers associated with a particularblock device, and apair of pointers.it "(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 which 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..pgSix routines constitutethe most important part of the interface with therest of the system.Given a device and block number,both.it breadand.it getblkreturn a pointer to a buffer header for the block;the difference is that.it breadis guaranteed to return a buffer actually containing thecurrent data for the block,while.it getblkreturns a buffer which contains the data in theblock only if it is already in core (whether it isor not is indicated by the.it 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..it Getblkis used, for example,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -