home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / c / asyncio.lha / AsyncIO / asyncio.doc next >
Encoding:
Text File  |  1995-09-15  |  19.2 KB  |  500 lines

  1. TABLE OF CONTENTS
  2.  
  3. asyncio/--changes---
  4. asyncio/--background--
  5. asyncio/CloseAsync
  6. asyncio/OpenAsync
  7. asyncio/ReadAsync
  8. asyncio/ReadCharAsync
  9. asyncio/SeekAsync
  10. asyncio/WriteAsync
  11. asyncio/WriteCharAsync
  12. asyncio/--changes--                                       asyncio/--changes--
  13.  
  14.   All changes described in this section were made by Magnus Holmgren. If
  15. you want to contact me about something, feel free to send a message to
  16. cmh@augs.se (or cmh@lls.se) or "Magnus Holmgren", 2:204/204.6@fidonet
  17.  
  18.   Release 4 - Date 13-Sep-95
  19.  
  20.   ╖ Oops. Forgot to include the include/asyncio.h file. Maybe as well,
  21. since I anyway had forgot to mention a few things in it.. ;)
  22.  
  23.   ╖ Asyncio is now also available as a shared library (to be placed in
  24. libs:). This means that a couple of new include files were added, and a
  25. one include file was split up.
  26.  
  27.   The main reason for doing this was to simplify the use of it in other
  28. languages (only need to "port" a few includes). I have no other include
  29. files than those for (DICE) C at the moment, but feel free to send me
  30. headers for other languages as well.
  31.  
  32.   Note: I have not yet verified that the SeekAsync function works, but
  33. since read and write works just fine, I see no reason why SeekAsync
  34. wouldn't work. ;)
  35.  
  36.   Also, I haven't really used it in program much either (only some
  37. testing), so the different defines and similar to use different versions
  38. may be a bit clumsy to use (see below for more information). Feel free to
  39. send me comments on how to improve this.
  40.  
  41.   ╖ Changed so that a non-regargs version of the link library can be
  42. created. To use the regargs version now, simply make sure that the variable
  43. ASIO_REGARGS is defined, and link with the proper link library.
  44.  
  45.   ╖ Changed the name of the NOEXTERNALS define to ASIO_NOEXTERNALS. Define
  46. this before you include <clib/asyncio_protos.h> if you want to use that
  47. feature. Note that you need to create a proper link library yourself! (With
  48. DICE, all you need to do is "LbMake asyncio s r e" in the Src drawer.)
  49.  
  50.   ╖ Modified OpenAsync() a little, to work around a problem when having
  51. SnoopDos (with SendARexx active), MungWall and Enforcer running. Not an
  52. asyncio bug as such, but.. ;)
  53.  
  54.  
  55.   Details about the different link libraries:
  56.  
  57.   As before, the asyncio.lib libraries should be used when creating
  58. standalone versions of the program.
  59.  
  60.   New link libraries withe the "base name" asynciolib.lib are needed if you
  61. want to use asyncio.library, and don't use the -mi option (or perhaps you
  62. need the autoinit code). I've tried to generate a regargs version of this
  63. library (using FDTOLIB), but it seems like it isn't possible. I don't know
  64. why yet. :/
  65.  
  66.   The include file "include/diceclib/asyncio_protos.h" are for DICE 3.0
  67. users. This include file should go to "dinclude:clib" (you only need this
  68. to use the -mi option to use inline Amiga function calls), whereas the
  69. other ones should be copied to the respective drawers in "dinclude:amiga??".
  70.  
  71.  
  72.   Notes about using the different link libraries:
  73.  
  74.   If you want to be able to easily select between using the shared library
  75. and the link library, then install all files, and make sure that
  76. ASIO_NO_SHARED_LIB is defined when you want to compile with the link
  77. library (this only affects DICE users, using the -mi option).
  78.   
  79.   If you only want to use the link library, don't copy the file
  80. include/diceclib/asyncio_protos.h to dinclude:clib. You then don't need to
  81. worry about the ASIO_NO_SHARED_LIB define.
  82.  
  83.   If you only want to use the shared library, simply remember to not have
  84. ASIO_NO_SHARED_LIB defined. ;)
  85.  
  86.  
  87.   In the future I plan to add two new functions (which perhaps explains the
  88. "function order" in the shared library ;): ReadLineAsync and
  89. WriteLineAsync. I have fairly well working prototypes of them, but
  90. ReadLineAsync is a bit messy, so I ought to rewrite it first.. ;) I also
  91. need to test it a bit more first..
  92.  
  93.  
  94.   Release 3 - Date 12-Aug-95
  95.  
  96. All changes herein were made by Magnus Holmgren (with some inspiration from
  97. the asyncio code found in the AIFF datatype, by Olaf `Olsen' Barthel). I've
  98. been in contact with Martin Taillefer, and he is aware of this release.
  99. However, he is not informed about the actual details of the changes in the
  100. code. Thus, any comments about the code (especially the changes) should not
  101. be sent to him.
  102.  
  103. This version includes a couple of enhancements (most from the AIFF sources)
  104. and a couple of bugfixes to SeekAsync():
  105.  
  106.   - SeekAsync() is now not unecessarely slow when doing some "kinds" of
  107.     read-mode seeks (typically when seeking after some small amount of
  108.     initial read). The problem was that it usually only considered the
  109.     newly arrived buffer, not both buffers. This could make it discard both
  110.     buffers, and restart reading, although one of the buffers already had
  111.     the needed data. Note that the kind of seeks that caused the above
  112.     problem may still seem to be somewhat slow, since the code must wait
  113.     for both buffers to be loaded. This cannot (easily) be avoided.
  114.  
  115.   - SeekAsync() doesn't cause the read buffer to contain garbage after
  116.     certain seeks any more. The problem was that ReadAsync() would read
  117.     from the wrong buffer (the one currently being loaded). This made the
  118.     files seem to contain garbage. This happened when the seek location
  119.     was within the newly arrived buffer.
  120.  
  121.   - The code package is now supplied as a link library, rather than a
  122.     single source module. The internal functions labeled "AS_#?" are
  123.     private and should not be called directly by the application.
  124.  
  125.   - A few minor "cosmetic" changes were done, to either make the code more
  126.     readable, or to make it slightly smaller.
  127.  
  128.   - Include file restructured a little (a public and a private part).
  129.     
  130.   - OpenAsync() now offers some new "options" (all from the AIFF code by
  131.     Olaf Barthel):
  132.     1) Opening a file from an already open filehandle is now possible.
  133.     2) A "no externals" version may be compiled, that doesn't require any
  134.        external variables to be available.
  135.     3) Each of the buffers will now be roughly bufferSize / 2 bytes large,
  136.        rather than bufferSize bytes.
  137.     4) If there isn't enough memory for the requested buffer size, the code
  138.        will try with smaller buffers (still properly "aligned") before
  139.        giving up.
  140.  
  141. The code was compiled using DICE 3.0. SAS/C or GCC should be able to
  142. compile it as well, without any changes (although I haven't tested this).
  143.  
  144. I didn't include any makefile, since I don't use one anyway! ;) Instead I
  145. use the LbMake utility in the DICE package. The Lib.Def file contains the
  146. definitions for the link library.
  147.  
  148. asyncio/--background--                                 asyncio/--background--
  149.  
  150. This documentation and source code was written by Martin Taillefer. This
  151. version of the package is dated 16-Feb-94. This version contains several
  152. bug fixes over previous versions. The most important changes are:
  153.  
  154.   - SeekAsync() now consistently works. It was getting confused when called
  155.     multiple times in a row with no intervening IO.
  156.  
  157.   - WriteAsync() would produce garbage in the destination file if it had
  158.     to bring up a "Disk is full" requester, and the user freed some room on
  159.     the disk and selected "Retry".
  160.  
  161. Reading and writing data is crucial to most applications and is in many cases a
  162. major bottleneck. Using the AmigaDOS' sophisticated file system architecture
  163. can help reduce, and sometimes eliminate, the time spent waiting for IO to
  164. complete. This package offers a few small routines that can greatly improve an
  165. application's IO performance.
  166.  
  167. Normally, an application processes a file in a manner similar to the following:
  168.  
  169.   1 - Open the file
  170.  
  171.   2 - Read some data
  172.  
  173.   3 - Process data just read
  174.  
  175.   4 - Repeat steps 2 and 3 until all data is processed
  176.  
  177.   5 - Close file
  178.  
  179. Although the above sequence works fine, it doesn't make full use of the Amiga's
  180. multitasking abilities. Step 2 in the above can become a serious bottleneck.
  181. Whenever the application needs some data by using the DOS Read() function,
  182. AmigaDOS has to put that task to sleep, and initiate a request to the file
  183. system to have it fetch the data. The file system then starts up the disk
  184. hardware and reads the data. Once the data is read, the application is woken up
  185. and can start processing the data just read.
  186.  
  187. The point to note in the above paragraph is that when the file system is
  188. reading data from disk, the application is asleep. Wouldn't it be nice if the
  189. application could keep running while data is being fetched for it?
  190.  
  191. Most Amiga hard drives make use of DMA (Direct Memory Access). DMA enables a
  192. hard drive to transfer data to memory _at the same time_ as the CPU does some
  193. work. This parallelism is what makes the set of accompanying routines so
  194. efficient. They exploit the fact that data can be transfered to memory while
  195. the application is busy processing other data.
  196.  
  197. Using the asynchronous IO routines, an application's IO happens like this:
  198.  
  199.   1 - Open the file, ask the file system to start reading ahead
  200.  
  201.   2 - Read some data, ask the file system to read more data
  202.  
  203.   3 - Process data
  204.  
  205.   4 - Repeat steps 2 and 3 until all data is processed
  206.  
  207.   5 - Close file
  208.  
  209. Immediately after opening the file, a request is sent to the file system to get
  210. it reading data in the background. By the time the application gets around to
  211. reading the first byte of data, it is likely already in memory. That means the
  212. application doesn't need to wait and can start processing the data. As soon as
  213. the application starts processing data from the file, a second request is sent
  214. out to the file system to fill up a second buffer. Once the application is done
  215. processing the first buffer, it starts processing the second one. When this
  216. happens, the file system starts filling up the first buffer again with new
  217. data. This process continues until all data has been read.
  218.  
  219. The whole technique is known as "double-buffered asynchronous IO" since it uses
  220. two buffers, and happens in the background (asynchronously).
  221.  
  222. The set of functions presented below offers high-performance IO using the
  223. technique described above. The interface is very similar to standard AmigaDOS
  224. files. These routines enable full asynchronous read/write of any file.
  225.  
  226. asyncio/CloseAsync                                         asyncio/CloseAsync
  227.  
  228.    NAME
  229.     CloseAsync -- close an async file.
  230.  
  231.    SYNOPSIS
  232.     success = CloseAsync(file);
  233.       d0                  a0
  234.  
  235.     LONG CloseAsync(struct AsyncFile *);
  236.  
  237.    FUNCTION
  238.     Closes a file, flushing any pending writes. Once this call has been
  239.     made, the file can no longer be accessed.
  240.  
  241.    INPUTS
  242.     file - the file to close. May be NULL, in which case this function
  243.            returns -1 and sets the IoErr() code to ERROR_INVALID_LOCK.
  244.            If the "no externals" version is used, then a NULL will not
  245.            set IoErr() (not possible).
  246.  
  247.    RESULT
  248.     result - < 0 for an error, >= 0 for success. Indicates whether closing
  249.          the file worked or not. If the file was opened in read-mode,
  250.              then this call will always work. In case of error,
  251.              dos.library/IoErr() can give more information.
  252.  
  253.    SEE ALSO
  254.     OpenAsync(), dos.library/Close()
  255.  
  256. asyncio/OpenAsync                                           asyncio/OpenAsync
  257.  
  258.    NAME
  259.     OpenAsync -- open a file for asynchronous IO.
  260.  
  261.    SYNOPSIS
  262.     file = OpenAsync(fileName, accessMode, bufferSize
  263.      d0                 a0         d0          d1
  264.                                            [, sysbase, dosbase ] );
  265.                                                 a1       a2
  266.  
  267.     struct AsyncFile OpenAsync(const STRPTR, UBYTE, LONG
  268.                        [, struct ExecBase *, struct DosLibrary * ] );
  269.  
  270.     file = OpenAsyncFromFH(handle, accessMode, bufferSize
  271.                              a0        d0          d1
  272.                                            [, sysbase, dosbase ] );
  273.                                                 a1       a2
  274.  
  275.     struct AsyncFile OpenAsyncFromFH(BPTR, UBYTE, LONG
  276.                        [, struct ExecBase *, struct DosLibrary * ] );
  277.  
  278.    FUNCTION
  279.     The named file is opened and an async file handle returned. If the
  280.     accessMode is MODE_READ, an existing file is opened for reading.
  281.     If accessMode is MODE_WRITE, a new file is created for writing. If
  282.     a file of the same name already exists, it is first deleted. If
  283.     accessMode is MODE_APPEND, an existing file is prepared for writing.
  284.     Data written is added to the end of the file. If the file does not
  285.     exists, it is created.
  286.  
  287.     'fileName' is a filename and CANNOT be a window specification such as
  288.     CON: or RAW:, or "*"
  289.  
  290.     'bufferSize' specifies the size of the IO buffer to use. There are
  291.     in fact two buffers allocated, each of roughly (bufferSize/2) bytes
  292.     in size. The actual buffer size use can vary slightly as the size
  293.     is rounded to speed up DMA.
  294.  
  295.     If the file cannot be opened for any reason, the value returned
  296.     will be NULL, and a secondary error code will be available by
  297.     calling the routine dos.library/IoErr().
  298.  
  299.     INPUTS
  300.     name - name of the file to open, cannot be a window specification.
  301.     handle - file handle to use async io on. The file pointer must be
  302.          located at the start of the file, and you may not access
  303.          it during the life of the AsyncFile handle. After CloseAsync,
  304.          you are responsible of closing the file.
  305.     accessMode - one of MODE_READ, MODE_WRITE, or MODE_APPEND
  306.     bufferSize - size of IO buffer to use. 8192 is recommended as it
  307.              provides very good performance for relatively little
  308.              memory.
  309.     sysbase - Library base needed for the "no externals" version of the
  310.         library.
  311.     dosbase - Library base, as sysbase.
  312.  
  313.     RESULTS
  314.     file - an async file handle or NULL for failure. You should not access
  315.            the fields in the AsyncFile structure, these are private to the
  316.            async IO routines. In case of failure, dos.library/IoErr() can
  317.            give more information.
  318.  
  319.     NOTES (by MH)
  320.     Although stated that CON:, RAW:, or "*" cannot be used as the file
  321.     name, tests indicates that the "Console:" volume is safe to use for
  322.     writing at least. No guarantees though.
  323.  
  324.     SEE ALSO
  325.     CloseAsync(), dos.library/Open()
  326.  
  327. asyncio/ReadAsync                                           asyncio/ReadAsync
  328.  
  329.    NAME
  330.     ReadAsync -- read bytes from an async file.
  331.  
  332.    SYNOPSIS
  333.     actualLength = ReadAsync(file, buffer, numBytes);
  334.         d0                    a0     a1       d0
  335.  
  336.     LONG ReadAsync(struct AsyncFile *, APTR, LONG);
  337.  
  338.    FUNCTION
  339.     This function reads bytes of information from an opened async file
  340.         into the buffer given. 'numBytes' is the number of bytes to read from
  341.         the file.
  342.  
  343.     The value returned is the length of the information actually read.
  344.     So, when 'actualLength' is greater than zero, the value of
  345.     'actualLength' is the the number of characters read. Usually
  346.     ReadAsync() will try to fill up your buffer before returning. A value
  347.     of zero means that end-of-file has been reached. Errors are indicated
  348.     by a value of -1.
  349.  
  350.     INPUTS
  351.     file - opened file to read, as obtained from OpenAsync()
  352.     buffer - buffer where to put bytes read
  353.     numBytes - number of bytes to read into buffer
  354.  
  355.     RESULT
  356.     actualLength - actual number of bytes read, or -1 if an error. In
  357.                case of error, dos.library/IoErr() can give more
  358.                information.
  359.  
  360.     SEE ALSO
  361.     OpenAsync(), CloseAsync(), ReadCharAsync(), WriteAsync(),
  362.     dos.library/Read()
  363.  
  364. asyncio/ReadCharAsync                                   asyncio/ReadCharAsync
  365.  
  366.    NAME
  367.     ReadCharAsync -- read a single byte from an async file.
  368.  
  369.    SYNOPSIS
  370.     byte = ReadCharAsync(file);
  371.      d0                   a0
  372.  
  373.     LONG ReadCharAsync(struct AsyncFile *);
  374.      d0                        a0
  375.  
  376.    FUNCTION
  377.     This function reads a single byte from an async file. The byte is
  378.     returned, or -1 if there was an error reading, or if the end-of-file
  379.     was reached.
  380.  
  381.    INPUTS
  382.     file - opened file to read from, as obtained from OpenAsync()
  383.  
  384.    RESULT
  385.     byte - the byte read, or -1 if no byte was read. In case of error,
  386.            dos.library/IoErr() can give more information. If IoErr()
  387.            returns 0, it means end-of-file was reached. Any other value
  388.            indicates an error.
  389.  
  390.    SEE ALSO
  391.     OpenAsync(), CloseAsync(), ReadAsync(), WriteCharAsync()
  392.     dos.library/Read()
  393.  
  394. asyncio/SeekAsync                                           asyncio/SeekAsync
  395.  
  396.    NAME
  397.     SeekAsync -- set the current position for reading or writing within
  398.              an async file.
  399.  
  400.    SYNOPSIS
  401.     oldPosition = SeekAsync(file, position, mode);
  402.         d0                   a0      d0      d1
  403.  
  404.     LONG SeekAsync(struct AsyncFile *, LONG, BYTE);
  405.  
  406.    FUNCTION
  407.     SeekAsync() sets the read/write cursor for the file 'file' to the
  408.     position 'position'. This position is used by the various read/write
  409.     functions as the place to start reading or writing. The result is the
  410.     current absolute position in the file, or -1 if an error occurs, in
  411.     which case dos.library/IoErr() can be used to find more information.
  412.     'mode' can be MODE_START, MODE_CURRENT or MODE_END. It is used to
  413.     specify the relative start position. For example, 20 from current
  414.     is a position 20 bytes forward from current, -20 is 20 bytes back
  415.     from current.
  416.  
  417.     To find out what the current position within a file is, simply seek
  418.     zero from current.
  419.  
  420.     INPUTS
  421.     file - an opened async file, as obtained from OpenAsync()
  422.     position - the place where to move the read/write cursor
  423.     mode - the mode for the position, one of MODE_START, MODE_CURRENT,
  424.            or MODE_END.
  425.  
  426.     RESULT
  427.     oldPosition - the previous position of the read/write cursor, or -1
  428.               if an error occurs. In case of error, dos.library/IoErr()
  429.               can give more information.
  430.  
  431.     NOTES (by MH)
  432.     If you seek after having read only a few bytes, the function must
  433.     wait for both buffers to be loaded, before the seek can be done.
  434.     This can cause small delays. Note that the above case isn't the
  435.     only one, but the typical one.
  436.  
  437.     SEE ALSO
  438.     OpenAsync(), CloseAsync(), ReadAsync(), WriteAsync(),
  439.     dos.library/Seek()
  440.  
  441. asyncio/WriteAsync                                         asyncio/WriteAsync
  442.  
  443.    NAME
  444.     WriteAsync -- write data to an async file.
  445.  
  446.    SYNOPSIS
  447.     actualLength = WriteAsync(file, buffer, numBytes);
  448.          d0                    a0     a1       d0
  449.  
  450.     LONG WriteAsync(struct AsyncFile *, APTR, LONG);
  451.  
  452.    FUNCTION
  453.     WriteAsync() writes bytes of data to an opened async file. 'numBytes'
  454.     indicates the number of bytes of data to be transferred. 'buffer'
  455.     points to the data to write. The value returned is the length of
  456.     information actually written. So, when 'numBytes' is greater than
  457.     zero, the value of 'numBytes' is the number of characters written.
  458.     Errors are indicated by a return value of -1.
  459.  
  460.     INPUTS
  461.     file - an opened file, as obtained from OpenAsync()
  462.     buffer - address of data to write
  463.     numBytes - number of bytes to write to the file
  464.  
  465.     RESULT
  466.     actualLength - number of bytes written, or -1 if error. In case
  467.                of error, dos.library/IoErr() can give more
  468.                information.
  469.  
  470.     SEE ALSO
  471.     OpenAsync(), CloseAsync(), ReadAsync(), WriteCharAsync(),
  472.     dos.library/Write()
  473.  
  474. asyncio/WriteCharAsync                                 asyncio/WriteCharAsync
  475.  
  476.    NAME
  477.     WriteCharAsync -- write a single byte to an async file.
  478.  
  479.    SYNOPSIS
  480.     result = WriteCharAsync(file, byte);
  481.       d0                     a0    d0
  482.  
  483.     LONG WriteCharAsync(struct AsyncFile *, UBYTE);
  484.  
  485.    FUNCTION
  486.     This function writes a single byte to an async file.
  487.  
  488.    INPUTS
  489.     file - an opened async file, as obtained from OpenAsync()
  490.     byte - byte of data to add to the file
  491.  
  492.    RESULT
  493.     result - 1 if the byte was written, -1 if there was an error. In
  494.          case of error, dos.library/IoErr() can give more information.
  495.  
  496.    SEE ALSO
  497.     OpenAsync(), CloseAsync(), ReadAsync(), WriteAsync(),
  498.     dos.library/Write()
  499.  
  500.