AMIPROC Copyright (c) 1989-1994 Steve Krueger and Doug Walker, Raleigh, NC, USA. All Rights Reserved. Send any correspondance to: Doug Walker and Steve Krueger 4701 Oak Park Road Raleigh, NC 27612 USA walker@unx.sas.com sassek@unx.sas.com This distribution is freely redistributable provided that you do not modify the contents of the files, and that all files are kept together. You may use this code freely in your commercial and noncommercial projects. AMIPROC: Spawn a new process with its own near data section. Requires the SAS/CŪ Development System Version 6.50 or higher (Some features might work with Version 6.0). SAS/C is a registered trademark of SAS Institute, Inc, Cary, NC, USA. AMIPROC consists of a couple of small functions that will start a new process, initialize a near data section for it, and run the SAS/C autoinit and autoterm functions. The autoinit/autoterm functions give you the ability to use virtually the entire SAS/C link library in your new process, as well as running C++ constructors and destructors and user-written autoinit/autoterm functions. ***HOW TO USE AMIPROC 1. Include the file "amiproc.h" in your C source file. 2. When you want to start your new process, call the function AmiProc_Start(): res = AmiProc_Start(func, userdata); struct AmiProcMsg *res; The return value is a pointer to a private data structure. You need to keep track of it and pass it to AmiProc_Wait() when you're ready to exit. Do not attempt to read the contents of this data structure. If res is NULL, the attempt to create a new process failed. int (*func)(void *userdata); This parameter is a pointer to a function in your code. The function should return "int" and take a "void *" as its parameter. The parameter will be the data pointer passed as AmiProc_Start's second parameter. void *userdata; This parameter is a pointer to data that you supply. It will be passed to your function as its argument when the subprocess has been created. This data must not be reused or freed until after the subprocess exits! 3. Sometime before your program exits, call AmiProc_Wait(), passing it the pointer returned by AmiProc_Start(). AmiProc_Wait() will wait until the subprocess exits, free some resources, then return the subprocess's return code to you. Do not attempt to use the AmiProcMsg pointer after this. 4. Make sure your subprocess does not call exit(), __exit(), abort(), _XCEXIT(), or any other function that would cause your program to exit (EVEN INDIRECTLY!). If it does, the program will attempt to free some resources belonging to the parent, and will bypass your DS_FREE() call, which will cause other resources not to be freed. Always exit by a simple return() from your entry point function. 5. Make sure your program is linked with the SAS/C-supplied cres.o startup, that it is compiled with the NOSTACKCHECK and NOSTACKEXT options, and that CTRL-C checking has been disabled. See below for more explanation. ***WARNINGS/POSSIBLE PROBLEMS Remember that although you have your own NEAR data section in the subprocess, FAR and CHIP data will still be shared with the parent process. Either reserve FAR and CHIP for read-only data or use semaphores to protect any read/write FAR or CHIP data. String literals ("the ones in double quotes") count as external data, too. If you do not specify the STRSECT or STRMERGE options, they will go whereever your external data goes. Since you probably don't modify string literals, STRSECT=CODE or STRSECT=FAR will save your program some space in the near section. Use this if you have a lot of near data and need to make room, or if you want to minimize the amount of data that gets duplicated each time you create a new subprocess Make sure your program is compiled with NOSTACKCHECK and NOSTACKEXT. (NOSTACKEXT is the default). These options rely on the values of certain external variables, which are not set up for the new subprocess. (This could probably be made to work, but we haven't done it. If you want to try, you'd need to duplicate the code in c.a that deals with setting the stack up.) Make sure that CTRL-C checking is disabled in your subprocess. The easiest way to do this is to disable the __chkabort function. See your SAS/C V6.50 User's Guide, page 220, for a description of how to disable CTRL-C checking. If you link with the SC command, you can also use the NOCHKABORT option described in the User's Guide. Make sure your program is linked with the cres.o startup. Programs linked with cres.o have a read-only copy of their initialized near data that these macros access. Programs linked with c.o or cback.o do not have this extra copy. Even if these programs link correctly, which may or may not be true, they won't work as expected since external variables used by library functions will be initialized incorrectly. (For example, the malloc() memory pools in both processes will be pointing to the same memory blocks...) Remember that the __saveds keyword and the geta4() function do not work in code linked with cres.o. This is described in your SAS/C manual.