home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Examples / AsynchIO / asyncio.doc < prev    next >
Encoding:
Text File  |  1994-03-22  |  12.1 KB  |  349 lines

  1. TABLE OF CONTENTS
  2.  
  3. asyncio/--background--
  4. asyncio/--history--
  5. asyncio/CloseAsync
  6. asyncio/OpenAsync
  7. asyncio/ReadAsync
  8. asyncio/ReadCharAsync
  9. asyncio/SeekAsync
  10. asyncio/WriteAsync
  11. asyncio/WriteCharAsync
  12. asyncio/--background--                                 asyncio/--background--
  13.  
  14. This documentation and source code was written by Martin Taillefer.
  15.  
  16. Reading and writing data is crucial to most applications and is in many cases
  17. a major bottleneck. Using AmigaDOS' sophisticated file system architecture
  18. can help reduce, and sometimes eliminate, the time spent waiting for IO to
  19. complete. This package offers a few small routines that can greatly improve
  20. an application's IO performance.
  21.  
  22. Normally, an application processes a file in a manner similar to the following:
  23.  
  24.   1 - Open the file
  25.  
  26.   2 - Read some data
  27.  
  28.   3 - Process data just read
  29.  
  30.   4 - Repeat steps 2 and 3 until all data is processed
  31.  
  32.   5 - Close file
  33.  
  34. Although the above sequence works fine, it doesn't make full use of the Amiga's
  35. multitasking abilities. Step 2 in the above can become a serious bottleneck.
  36. Whenever the application needs some data by using the DOS Read() function,
  37. AmigaDOS has to put that task to sleep, and initiate a request to the file
  38. system to have it fetch the data. The file system then starts up the disk
  39. hardware and reads the data. Once the data is read, the application is woken up
  40. and can start processing the data just read.
  41.  
  42. The point to note in the above paragraph is that when the file system is
  43. reading data from disk, the application is asleep. Wouldn't it be nice if the
  44. application could keep running while data is being fetched for it?
  45.  
  46. Most Amiga hard drives make use of DMA (Direct Memory Access). DMA enables a
  47. hard drive to transfer data to memory _at the same time_ as the CPU does some
  48. work. This parallelism is what makes the set of accompanying routines so
  49. efficient. They exploit the fact that data can be transfered to memory while
  50. the application is busy processing other data.
  51.  
  52. Using the asynchronous IO routines, an application's IO happens like this:
  53.  
  54.   1 - Open the file, ask the file system to start reading ahead
  55.  
  56.   2 - Read some data, ask the file system to read more data
  57.  
  58.   3 - Process data
  59.  
  60.   4 - Repeat steps 2 and 3 until all data is processed
  61.  
  62.   5 - Close file
  63.  
  64. Immediately after opening the file, a request is sent to the file system to get
  65. it reading data in the background. By the time the application gets around to
  66. reading the first byte of data, it is likely already in memory. That means the
  67. application doesn't need to wait and can start processing the data. As soon as
  68. the application starts processing data from the file, a second request is sent
  69. out to the file system to fill up a second buffer. Once the application is done
  70. processing the first buffer, it starts processing the second one. When this
  71. happens, the file system starts filling up the first buffer again with new
  72. data. This process continues until all data has been read.
  73.  
  74. The whole technique is known as "double-buffered asynchronous IO" since it uses
  75. two buffers, and happens in the background (asynchronously).
  76.  
  77. The set of functions presented below offers high-performance IO using the
  78. technique described above. The interface is very similar to standard AmigaDOS
  79. files. These routines enable full asynchronous read/write of any file.
  80.  
  81. asyncio/--history--                                       asyncio/--history--
  82.  
  83. 23-Mar-94
  84. ---------
  85.  
  86.   - When seeking within the current read buffer, the wrong packet would be
  87.     sent out to be filled asynchronously. Depending on the data read from
  88.     the buffer, and how fast it was read, you could end up getting incorrect
  89.     data on subsequent ReadAsync() calls.
  90.  
  91.   - There was actually bufferSize*2 bytes allocated for IO buffers instead
  92.     of just bufferSize. This is fixed. So if you want the same effective
  93.     buffer size as before, you must double the value of the bufferSize
  94.     argument supplied to OpenAsync().
  95.  
  96.   - MEMF_PUBLIC is now specified for the IO buffers. This is in support
  97.     of VM hacks such as GigaMem.
  98.  
  99.   - A Seek() call had the mode and offset parameters reversed. The code worked,
  100.     because both values were luckily always 0, but it was not very clean.
  101.  
  102.   - Now uses a typedef for the AsyncFile structure, and enums for the
  103.     open modes and seek modes.
  104.  
  105. 16-Feb-94
  106. ---------
  107.  
  108.   - SeekAsync() now consistently works. It was getting confused when called
  109.     multiple times in a row with no intervening IO.
  110.  
  111.   - WriteAsync() would produce garbage in the destination file if it had
  112.     to bring up a "Disk is full" requester, and the user freed some room on
  113.     the disk and selected "Retry".
  114.  
  115. asyncio/CloseAsync                                         asyncio/CloseAsync
  116.  
  117.    NAME
  118.     CloseAsync -- close an async file.
  119.  
  120.    SYNOPSIS
  121.     success = CloseAsync(file);
  122.  
  123.     LONG CloseAsync(struct AsyncFile *);
  124.  
  125.    FUNCTION
  126.     Closes a file, flushing any pending writes. Once this call has been
  127.     made, the file can no longer be accessed.
  128.  
  129.    INPUTS
  130.     file - the file to close. May be NULL, in which case this function
  131.            returns -1 and sets the IoErr() code to ERROR_INVALID_LOCk.
  132.  
  133.    RESULT
  134.     result - < 0 for an error, >= 0 for success. Indicates whether closing
  135.          the file worked or not. If the file was opened in read-mode,
  136.              then this call will always work. In case of error,
  137.              dos.library/IoErr() can give more information.
  138.  
  139.    SEE ALSO
  140.     OpenAsync(), dos.library/Close()
  141.  
  142. asyncio/OpenAsync                                           asyncio/OpenAsync
  143.  
  144.    NAME
  145.     OpenAsync -- open a file for asynchronous IO.
  146.  
  147.    SYNOPSIS
  148.     file = OpenAsync(fileName, accessMode, bufferSize);
  149.  
  150.     struct AsyncFile OpenAsync(const STRPTR, UBYTE, LONG);
  151.  
  152.    FUNCTION
  153.     The named file is opened and an async file handle returned. If the
  154.     accessMode is MODE_READ, an existing file is opened for reading.
  155.     If accessMode is MODE_WRITE, a new file is created for writing. If
  156.     a file of the same name already exists, it is first deleted. If
  157.     accessMode is MODE_APPEND, an existing file is prepared for writing.
  158.     Data written is added to the end of the file. If the file does not
  159.     exists, it is created.
  160.  
  161.     'fileName' is a filename and CANNOT be a window specification such as
  162.     CON: or RAW:, or "*"
  163.  
  164.     'bufferSize' specifies the size of the IO buffer to use. There are
  165.     in fact two buffers allocated, each of roughly (bufferSize/2) bytes
  166.     in size. The actual buffer size use can vary slightly as the size
  167.     is rounded to speed up DMA.
  168.  
  169.     If the file cannot be opened for any reason, the value returned
  170.     will be NULL, and a secondary error code will be available by
  171.     calling the routine dos.library/IoErr().
  172.  
  173.     INPUTS
  174.     name - name of the file to open, cannot be a window specification
  175.     accessMode - one of MODE_READ, MODE_WRITE, or MODE_APPEND
  176.     bufferSize - size of IO buffer to use. 8192 is recommended as it
  177.              provides very good performance for relatively little
  178.              memory.
  179.  
  180.     RESULTS
  181.     file - an async file handle or NULL for failure. You should not access
  182.            the fields in the AsyncFile structure, these are private to the
  183.            async IO routines. In case of failure, dos.library/IoErr() can
  184.            give more information.
  185.  
  186.     SEE ALSO
  187.     CloseAsync(), dos.library/Open()
  188.  
  189. asyncio/ReadAsync                                           asyncio/ReadAsync
  190.  
  191.    NAME
  192.     ReadAsync -- read bytes from an async file.
  193.  
  194.    SYNOPSIS
  195.     actualLength = ReadAsync(file, buffer, numBytes);
  196.  
  197.     LONG ReadAsync(struct AsyncFile *, APTR, LONG);
  198.  
  199.    FUNCTION
  200.     This function reads bytes of information from an opened async file
  201.         into the buffer given. 'numBytes' is the number of bytes to read from
  202.         the file.
  203.  
  204.     The value returned is the length of the information actually read.
  205.     So, when 'actualLength' is greater than zero, the value of
  206.     'actualLength' is the the number of characters read. Usually
  207.     ReadAsync() will try to fill up your buffer before returning. A value
  208.     of zero means that end-of-file has been reached. Errors are indicated
  209.     by a value of -1.
  210.  
  211.     INPUTS
  212.     file - opened file to read, as obtained from OpenAsync()
  213.     buffer - buffer where to put bytes read
  214.     numBytes - number of bytes to read into buffer
  215.  
  216.     RESULT
  217.     actualLength - actual number of bytes read, or -1 if an error. In
  218.                case of error, dos.library/IoErr() can give more
  219.                information.
  220.  
  221.     SEE ALSO
  222.     OpenAsync(), CloseAsync(), ReadCharAsync(), WriteAsync(),
  223.     dos.library/Read()
  224.  
  225. asyncio/ReadCharAsync                                   asyncio/ReadCharAsync
  226.  
  227.    NAME
  228.     ReadCharAsync -- read a single byte from an async file.
  229.  
  230.    SYNOPSIS
  231.     byte = ReadCharAsync(file);
  232.  
  233.     LONG ReadCharAsync(struct AsyncFile *);
  234.  
  235.    FUNCTION
  236.     This function reads a single byte from an async file. The byte is
  237.     returned, or -1 if there was an error reading, or if the end-of-file
  238.     was reached.
  239.  
  240.    INPUTS
  241.     file - opened file to read from, as obtained from OpenAsync()
  242.  
  243.    RESULT
  244.     byte - the byte read, or -1 if no byte was read. In case of error,
  245.            dos.library/IoErr() can give more information. If IoErr()
  246.            returns 0, it means end-of-file was reached. Any other value
  247.            indicates an error.
  248.  
  249.    SEE ALSO
  250.     OpenAsync(), CloseAsync(), ReadAsync(), WriteCharAsync()
  251.     dos.library/Read()
  252.  
  253. asyncio/SeekAsync                                           asyncio/SeekAsync
  254.  
  255.    NAME
  256.     SeekAsync -- set the current position for reading or writing within
  257.              an async file.
  258.  
  259.    SYNOPSIS
  260.     oldPosition = SeekAsync(file, position, mode);
  261.  
  262.     LONG SeekAsync(struct AsyncFile *, LONG, BYTE);
  263.  
  264.    FUNCTION
  265.     SeekAsync() sets the read/write cursor for the file 'file' to the
  266.     position 'position'. This position is used by the various read/write
  267.     functions as the place to start reading or writing. The result is the
  268.     current absolute position in the file, or -1 if an error occurs, in
  269.     which case dos.library/IoErr() can be used to find more information.
  270.     'mode' can be MODE_START, MODE_CURRENT or MODE_END. It is used to
  271.     specify the relative start position. For example, 20 from current
  272.     is a position 20 bytes forward from current, -20 is 20 bytes back
  273.     from current.
  274.  
  275.     To find out what the current position within a file is, simply seek
  276.     zero from current.
  277.  
  278.     INPUTS
  279.     file - an opened async file, as obtained from OpenAsync()
  280.     position - the place where to move the read/write cursor
  281.     mode - the mode for the position, one of MODE_START, MODE_CURRENT,
  282.            or MODE_END.
  283.  
  284.     RESULT
  285.     oldPosition - the previous position of the read/write cursor, or -1
  286.               if an error occurs. In case of error, dos.library/IoErr()
  287.               can give more information.
  288.  
  289.     SEE ALSO
  290.     OpenAsync(), CloseAsync(), ReadAsync(), WriteAsync(),
  291.     dos.library/Seek()
  292.  
  293. asyncio/WriteAsync                                         asyncio/WriteAsync
  294.  
  295.    NAME
  296.     WriteAsync -- write data to an async file.
  297.  
  298.    SYNOPSIS
  299.     actualLength = WriteAsync(file, buffer, numBytes);
  300.  
  301.     LONG WriteAsync(struct AsyncFile *, APTR, LONG);
  302.  
  303.    FUNCTION
  304.     WriteAsync() writes bytes of data to an opened async file. 'numBytes'
  305.     indicates the number of bytes of data to be transferred. 'buffer'
  306.     points to the data to write. The value returned is the length of
  307.     information actually written. So, when 'numBytes' is greater than
  308.     zero, the value of 'numBytes' is the number of characters written.
  309.     Errors are indicated by a return value of -1.
  310.  
  311.     INPUTS
  312.     file - an opened file, as obtained from OpenAsync()
  313.     buffer - address of data to write
  314.     numBytes - number of bytes to write to the file
  315.  
  316.     RESULT
  317.     actualLength - number of bytes written, or -1 if error. In case
  318.                of error, dos.library/IoErr() can give more
  319.                information.
  320.  
  321.     SEE ALSO
  322.     OpenAsync(), CloseAsync(), ReadAsync(), WriteCharAsync(),
  323.     dos.library/Write()
  324.  
  325. asyncio/WriteCharAsync                                 asyncio/WriteCharAsync
  326.  
  327.    NAME
  328.     WriteCharAsync -- write a single byte to an async file.
  329.  
  330.    SYNOPSIS
  331.     result = WriteCharAsync(file, byte);
  332.  
  333.     LONG WriteCharAsync(struct AsyncFile *, UBYTE);
  334.  
  335.    FUNCTION
  336.     This function writes a single byte to an async file.
  337.  
  338.    INPUTS
  339.     file - an opened async file, as obtained from OpenAsync()
  340.     byte - byte of data to add to the file
  341.  
  342.    RESULT
  343.     result - 1 if the byte was written, -1 if there was an error. In
  344.          case of error, dos.library/IoErr() can give more information.
  345.  
  346.    SEE ALSO
  347.     OpenAsync(), CloseAsync(), ReadAsync(), WriteAsync(),
  348.     dos.library/Write()
  349.