home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / SASC6571.LZX / examples / cres / READ.ME < prev    next >
Encoding:
Text File  |  1996-12-24  |  7.5 KB  |  189 lines

  1. Resident Program Example
  2. Copyright (c) 1993 SAS Institute, Inc, Cary, NC, USA
  3. All Rights Reserved
  4.  
  5.  
  6. Resident - What does it mean?
  7. -----------------------------
  8.  
  9. On the Amiga, when you type the name of a program, it is loaded from
  10. whatever disk device it exists on into your computer's memory, and
  11. then executed.  There are two inefficiencies in executing commands in
  12. this way:
  13.  
  14.    1. If the disk device is slow, your program may take some
  15.       time to load and begin running.  If you run the program more than
  16.       once, the system reloads it from the disk again and again.
  17.       
  18.    2. If you run the same program twice (for example, running an
  19.       editor twice to edit two different files) the system allocates
  20.       memory for the program twice, but puts the same code in both
  21.       copies.  This wastes memory.
  22.  
  23. Both of these problems are addressed by making the program "resident".
  24. Resident programs are pre-loaded into memory.  Any future invocations
  25. of the program use the already-loaded copy instead of loading it from
  26. the disk.
  27.  
  28. The main requirement for making a program resident is that it be a "pure"
  29. program.  "pure" in this context means that the code and data in memory
  30. must not change after the program is loaded.  If the code or data changed
  31. with each invocation, one run of a resident program might cause the next
  32. run of the same program to behave differently.
  33.  
  34. Unfortunately, writing a truly pure program can be quite difficult, 
  35. especially if you are used to writing C programs using traditional
  36. coding styles.  For example, if you assign a value to a global or
  37. static variable, your program is no longer pure!  Assigning to the
  38. global modifies your program's data section, and the next invocation
  39. of your program will see your modified value.  Also, if two invocations
  40. of the program are running at the same time, they might end up "fighting"
  41. over the variable - each program would set the variable to the value it
  42. wanted, but only one could win!
  43.  
  44. The Commodore Resident command will not allow you to make a program
  45. resident unless it has the 'p', or "pure" bit set (See your AmigaDOS manual for a
  46. description of the "Protect" command for a description of protection bits
  47. which can exist for a file), unless you force it to do so with the PURE
  48. keyword.  Once a program is made resident, however, the Commodore Shell
  49. will not complain if it actually is NOT a pure program.  Some other Shells
  50. WILL complain (for instance, WShell will report "***Impure resident
  51. module!" after you execute your resident program if it is not pure).
  52.  
  53. What the "cres.o" Startup Module Does for You
  54. ---------------------------------------------
  55.  
  56. "cres.o" is a version of the standard "c.o" startup module that makes it
  57. easier for you to create programs which can be made resident.  "cres.o"
  58. ensures that your program will stay pure by making a COPY of your near
  59. data section each time the program is run.  This copy is deleted as soon
  60. as your program is finished, leaving the original for use the next time 
  61. you run your program.  This means that you can write external and static
  62. data as if your program was not resident.
  63.  
  64. NOTE:  This only works for NEAR data.  It is up to you to make sure that no
  65. FAR (or __chip) data is written to, as there is no way for cres.o to make
  66. this work.  For details on near and far data, see the User's Guide, 
  67. Volume I, Chapter 12, "How Does the Compiler Work?".
  68.  
  69. When you link with cres.o, the linker automatically sets the PURE bit
  70. to let the Resident command know that it's OK to make your program
  71. resident.
  72.  
  73. Using cres.o
  74. ------------
  75.  
  76. Using this version of the startup code is simplicity itself.  You don't have
  77. to make any changes to your code.  All that needs to be done is to tell the
  78. compiler to use cres.o in place of c.o.
  79.  
  80. FROM WORKBENCH
  81.  
  82. Double-click the SCoptions icon to run the compiler options setting program.
  83. In the main window, click the 'NoLink' gadget until it reads 'Link' (should
  84. be one click).  Then click the 'LINKER OPTIONS' gadget to go to the Linker
  85. Options window.  Click on the 'Startup=' gadget until it reads
  86. 'Startup=cres' (should be one click).  Then click on 'OK' and then 'Save'.
  87.  
  88. FROM CLI
  89.  
  90. The 'scopts' program may be used from the CLI as well as from Workbench.
  91. Simply type
  92.  
  93.         scopts link startup=cres
  94.  
  95. at the CLI prompt to set the proper options.
  96.  
  97.  
  98. Example
  99. -------
  100.  
  101. In this directory is a file named "cres.c", which is an example of a program
  102. which won't work if made resident using the standard startup module.  It has
  103. global data which is modified every time it is run.  If you compile this
  104. program as-is (the 'Link' option is already specified), and then make it
  105. resident, you will see the problem.  Here are the step-by-step operations to
  106. see this work:
  107.  
  108.         1) Open a Shell.  You can do this from the Workbench, or from within
  109.            the SE Editor, using the "Create New CLI" menu option, or by
  110.            pressing Ctrl-F within SE.
  111.  
  112.            (We need to do this from a Shell as there is no easy way to use the
  113.            Resident command from the Workbench.)
  114.  
  115.         2) Enter the command: sc cres.c
  116.         
  117.            (Since you have set the LINK option in the SCOPTIONS file, this
  118.            command will compile and link the program.)
  119.  
  120.         3) Enter the command: Resident cr cres pure
  121.         
  122.            (This makes the program "cres" resident.  You can invoke it 
  123.            by typing "cr".)
  124.  
  125.         4) Enter the command: cr
  126.  
  127.            (It should print two lines of output, the second saying
  128.            "Everything's O.K.!"  If you are running WShell or some other
  129.            shell that detects impure resident modules, you should get
  130.            a warning now.)
  131.  
  132.         5) Enter the command again: cr
  133.  
  134.            (This time, it should print two lines of output again, but the
  135.            second line will say "Something's wrong!  check = nn", where 'nn'
  136.            equals some number other than 5.)
  137.  
  138.         6) Enter the command: Resident cr remove
  139.  
  140.            (Since it doesn't work correctly, we need to get rid of it!)
  141.  
  142. If this program relied on the value of 'check' being 5 whenever is started
  143. running, you can see that it will fail on the second or subsequent runs.
  144.  
  145. Now, to make this work, all we must do is enter the following command
  146.  
  147.         scopts startup=cres
  148.  
  149. this will add 'startup=cres' to our current options (leaving the 'Link'
  150. option set).
  151.  
  152. Now, the following steps will demonstrate that the program has just been
  153. turned into a pure, residentable program, without having to change a line of
  154. code!
  155.  
  156.         1) Open a CLI.
  157.  
  158.         2) Enter the command: sc cres.c
  159.  
  160.         3) Enter the command: Resident cr cres
  161.  
  162.         4) Enter the command: cr
  163.  
  164.            (It should print two lines of output, the second saying
  165.            "Everything's O.K.!")
  166.  
  167.         -) Each time you repeat step 4, you should get the exact same
  168.            output.
  169.  
  170.  
  171. Synopsis
  172. --------
  173.  
  174. Making programs resident has several advantages over non-resident status, if
  175. you have enough RAM to keep them around!
  176.  
  177. There is no load time involved, since the code is already in place, and if
  178. you try to run multiple copies of the code at the same time, only one copy
  179. is actually needed, thereby using less RAM.
  180.  
  181. To create a program which can be made resident, simply link with cres.o in
  182. place of c.o.  Then use the Resident command (or equivalent) to install the
  183. program in memory.
  184.  
  185. Remember though, that cres.o will only work with near data.  If you must
  186. create a resident program which needs more than 64K of writable global data,
  187. you must use other techniques (such as runtime allocation, passing global
  188. structure pointers, etc.) which are beyond the scope of this article.
  189.