home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / os / vms / 19286 < prev    next >
Encoding:
Internet Message Format  |  1992-12-15  |  7.5 KB

  1. Path: sparky!uunet!olivea!spool.mu.edu!agate!dog.ee.lbl.gov!news!nosc!crash!cmkrnl!jeh
  2. From: jeh@cmkrnl.com
  3. Newsgroups: comp.os.vms
  4. Subject: Re: $QIO: What happens within?
  5. Message-ID: <1992Dec14.220506.963@cmkrnl.com>
  6. Date: 15 Dec 92 06:05:05 GMT
  7. References: <1992Dec14.164552.28939@bnlux1.bnl.gov>
  8. Distribution: na
  9. Organization: Kernel Mode Consulting, San Diego, CA
  10. Lines: 142
  11.  
  12. In article <1992Dec14.164552.28939@bnlux1.bnl.gov>, kushmer@bnlux1.bnl.gov 
  13. (christopher kushmerick) writes:
  14. > What is the sequence of events when a qio is executed? In particular:
  15. > I am using a $QIO to send data between mail boxes. I have a global structure
  16. > which is updated at AST level by various tasks. When I get a request from 
  17. > another program, I send the structure by qio, specifying the address of the
  18. > actual global structure, rather than first making a copy.
  19. > This is in FORTRAN so both the global structure and any local copies would be
  20. > at some fixed location in memory and _NOT_ on the stack.
  21. > Here is the question: Does $qio (not $qiow) make its own copy of the data 
  22. > prior to returning, or does it just use the data at the memory location speced?
  23.  
  24. It depends on the device driver.  The difference lies in the difference between
  25. "buffered" and "direct" I/O.  
  26.  
  27. In buffered writes, the driver makes a copy of the user's data, and the actual
  28. transfer is from the copy, which is in system address space.  For buffered
  29. reads, the driver allocates a system-space buffer and the transfer is done into
  30. the buffer, and the system buffer is copied to the user's buffer by the IPL 2
  31. I/O post-processing AST routine. 
  32.  
  33. In direct I/O, the actual transfer is done to or from the user's buffer in 
  34. process address space.  The pages containing the buffer are locked into 
  35. the process working set and into physical memory for the duration of the I/O
  36. request, so that pager and swapper activity can't reassign them to some other
  37. process.  
  38.  
  39. In general, buffered I/O is associated with programmed I/O devices, and direct
  40. I/O with DMA devices, but there are many exceptions to this.  Another general
  41. rule is that buffered I/O is used when the driver needs to "touch" the data
  42. in some way -- for example, expanding tabs to spaces when writing to a terminal
  43. or line printer, or adding protocol headers "around" user data for transmission
  44. via DECnet logical link -- but there are exceptions to this too.  
  45.  
  46. Ultimately, the selection of buffered vs. direct I/O is made by the person who 
  47. writes the driver for the device.  It can vary with different types of I/O 
  48. function codes and can even vary from one use to another of the same function
  49. code to the same device (although this requires some non-standard coding in
  50. the driver, and is quite rare).  Nor can you request buffered or direct I/O
  51. via a parameter on the $QIO (or any other) system service call.  (I suppose it
  52. would be possible to allow this, but it would take some bizarre coding in the
  53. driver; I've never seen it done.)
  54.  
  55. For the specific question re the mailbox driver, writes are (in all versions of
  56. VMS that I've looked at) buffered I/O.  This means that $QIO (both $QIO and
  57. $QIOW, by the way) grabs a copy of your buffer before the procedure call
  58. returns to you, whether or not the write has actually completed yet. 
  59.  
  60. About now you are probably wondering which type of I/O the various devices use.
  61. Well, in general:
  62.  
  63.     device type    I/O type
  64.     ---------------    --------
  65.     disk        direct
  66.     tape        direct
  67.     mailbox        buffered
  68.     terminal    buffered, except unformatted writes to devices like the
  69.              DMF32, DH series, CX series, etc., with DMA output
  70.              enabled
  71.     DECnet logical    buffered, except when the "other node" is the 
  72.      link (task-to-  local node, in which case it's direct I/O
  73.      task comm.)
  74.  
  75. For more information, see the _VMS Device Support Manual_.  For even more
  76. information, see _VMS Advanced Device Driver Techniques_, by myself and Lee
  77. Leahy.  
  78.  
  79. Note well:  The VMS documentation does not state whether a particular I/O
  80. function to a particular device is buffered or direct.  This means that (like
  81. any other undocumented details of VMS's behavior) it may change in a future
  82. release, and so you shouldn't write code that counts on it being one way or the
  83. other. 
  84.  
  85. (In fact, when the DMF32 was introduced, the driver's use of direct I/O writes
  86. when possible broke some application code.) 
  87.  
  88. > 1) Stack frames: If I were doing this in Pascal or C and sent a local
  89. > variable via qio. By the time the qio got around to actually sending the data,
  90. > the routine that called the qio may have returned, the stack frame would no
  91. > longed be valid and who knows what might be in the (stack) memory location that
  92. > used to contain the data.
  93.  
  94. This is indeed a valid concern for operations that happen to be direct I/O.
  95.  
  96. It is also a concern for buffered reads:  The fact that the actual transfer is
  97. done to a system buffer, which is then copied to your buffer, won't help you
  98. if you redefine the virtual address space that includes your buffer between
  99. the time you issue the $QIO and the time the system tries to copy the data back
  100. to your buffer.
  101.  
  102. The same concern applies to the I/O status block.  It's zeroed when the request
  103. is successfully queued to the device, and filled in later when the request
  104. completes.  
  105.  
  106. > 2) The data in my case is updated by ast-level interrupt routines. What if
  107. > the updating routine is executing when the $qio is ready to start shipping the 
  108. > data. Will the qio interrupt the ast routine to ship the data? 
  109.  
  110. In the case of a buffered write, there is nothing to worry about.  The $QIO
  111. write grabs a copy of the data while running in the context of your process,
  112. but at IPL 2; this blocks the delivery of any ASTs to your process.  This is
  113. really done to prevent things like process deletion from happening while the
  114. record of the I/O operation isn't complete, but it also handily prevents user
  115. ASTs from interrupting $QIO's buffer copy. 
  116.  
  117. > Does it
  118. > matter if the qio was called at AST level or at "normal" level? 
  119.  
  120. No.
  121.  
  122. > Is it possible
  123. > that the data will be corrupt due to incomplete updating of the data?
  124.  
  125. In the case of direct I/O, yes,  it would be possible, since the actual 
  126. transfer may happen after $QIO returns control to you, especially if you are
  127. queueing multiple write requests to the same device and one or more earlier
  128. requests aren't done yet.  It isn't a problem when writing to a mailbox. 
  129.  
  130. > Perhaps a mailbox is a bad example because it is all memory. what if I was 
  131. > sending large amounts of data down a slow serial line, using local 
  132. > variables in a stack-frame language like pascal.
  133.  
  134. If by a serial line you mean either a terminal port or a DECnet logical link,
  135. all such I/O is buffered in the current implementation, so you have nothing to
  136. worry about.  Unless, that is, you are doing unformatted writes to a terminal
  137. device that supports and is enabled for DMA. 
  138.  
  139. For direct I/O, and for buffered reads, with async (no-wait) $QIO, and for the
  140. IOSB with *all* types of no-wait $QIO, you must indeed take some pains to
  141. ensure that your buffer will stay around until the write is done.  This usually
  142. means allocating it explicitly or using "own" or "static" storage.  In C, 
  143. declaring it outside of any function declaration will also work. 
  144.  
  145.     --- Jamie Hanrahan, Kernel Mode Consulting, San Diego CA
  146. drivers, internals, networks, applications, and training for VMS and Windows-NT
  147. uucp 'g' protocol guru and release coordinator, VMSnet (DECUS uucp) W.G., and 
  148. Chair, Programming and Internals Working Group, U.S. DECUS VMS Systems SIG 
  149. Internet:  jeh@cmkrnl.com, hanrahan@eisner.decus.org, or jeh@crash.cts.com
  150. Uucp:  ...{crash,eisner,uunet}!cmkrnl!jeh
  151.