|
POLIS Programmers' Guide
The information in this text is derived from many messages exchanged between the members of the hardware-software codesign team. The author of this document is Ellen M. Sentovich currently at Ecole des Mines de Paris, Centre de Mathématiques Appliquées, B.P. 207, F, 06904 Sophia-Antipolis Cedex, FRANCE; ellen@cma.cma.fr.
Contents
1 IntroductionThis document is for the benefit of POLIS programmers. It summarizes information that has been disseminated within the group since its inception. Members of the group are encouraged to contribute updates and corrections as necessary.
2 Creating POLIS in a new location2.1 Initial set upEdit your .cshrc file at UCB and the new location:
For new POLIS programmers: have your login added to the hwsw group at UCB. 2.2 Creating a new distribution at UCBLet the name of the new location be nl. Execute the following: cd /projects/hwsw/hwsw/common/src mkdir for_nl chmod g+w for_nl cd polis co -l Makefile.src vi Makefile.srcAdd the for_nl and for_nl_force rules (see examples in the Makefile). ci -u Makefile.src make Makefile cd .. tar cf - polis | gzip > for_nl/polis.tar.gz touch for_nl/bundle chmod g+w for_nl/bundle 2.3 Directory structure setupLet root_hwsw be the root directory at the new location (e.g. /projects/hwsw/hwsw). cd root_hwsw mkdir sun4Create directories for each architecture. mkdir sun4/bin mkdir sun4/lib mkdir common mkdir common/src 2.4 FTPing the filescd root_hwsw/common/src ftp 128.32.168.7 binary cd /projects/hwsw/hwsw/common/src/for_nl get polis.tar.Z quitAt UCB, execute rm polis.tar.Z. Note that you will need the mm libraries at the new location too. Instructions for getting and compiling those are not contained here. If you don't have them and can't get them, either compile POLIS without the -g options (make libpolis.a, make polis), or remove the references to libmm*.a from util/Makefile*.beg and/or from the root Makefile. gunzip polis.tar.Z tar xmf polis.tarThe m is important so that the modification times are consistent. rm polis.tar cd polis % make strip_depend 2.5 Initial script installationOn any machine, set up the scripts by compiling them in the common area. These scripts are later used to create the shadow source trees, at which point the scripts for each architecture are built. Execute the following commands: cd root_hwsw/common/src/polis/util co -l makemakefile.sh vi makemakefile.shChange the POLIS variable. ci -u makemakefile.sh source makemakefile.sh make rehash 2.6 Creating the Makefiles and Linking Header Filescd root_hwsw/common/src/polis/util co -l Make.sh Makefile.leaf.beg Makefile.non_leaf.beg Makefile.strl.beg Shell.sh vi Make.sh Makefile.leaf.beg Makefile.non_leaf.beg Makefile.strl.beg Shell.shSet the POLIS variable appropriately: POLIS = root_hwsw/$(ARCH). To make the Makefiles: cd root_hwsw/common/src/polis makemakefile_all To link the header files: cd root_hwsw/common/src/polis mkdir include (in fact, all the include directories need to be created) make link_header Remake the makefiles since now they will find the header files: cd root_hwsw/common/src/polis makemakefile_all
2.7 Creating the architecture-specific source linksCreate the shadow source trees for each architecture, linking the include and lib directories. For each architecture: cd root_hwsw/$ARCH ln -s ../common/src/polis/include ln -s ../common/src/polis/polis_lib mkdir src cd src rslink ../../common/src/polis polisIn the common directory: cd root_hwsw/common ln -s src/polis/polis_lib 2.8 Script installation for each architectureExecute the following commands for each architecture (you should be logged onto a machine of that architecture, so that everything is installed correctly): cd root_hwsw/$(ARCH)/src/polis/util make 2.9 Compilingcd root_hwsw/$ARCH/src/polis Make installIt may be necessary to do a ``make clean'' before each compile, since the source file linking may have linked some yacc and lex generated files to files in the common subdirectory. 2.10 Testingcd root_hwsw/$ARCH/src/polis/examples/test make clean make make clean 2.11 Results
2.12 UpdatesUpdates to an installation procede similarly. At UCB: cd /projects/hwsw/hwsw/common/src/polis make for_nlFTP for_nl/polis.tar.Z to the root_hwsw/common/src/polis directory and execute gunzip polis.tar.Z; tar xf polis.tar; rm polis.tar. If the extraction works properly, remove polis.tar.Z from the common area at UCB. After this, follow the instructions in Section 3.2 to completely update directory and recompile.
3 General procedure for installing POLIS code3.1 Code OverviewThere are 3 places where code development and changes take place:
Makefiles for all directories and subdirectories are standardized and set up to be automatically created and updated. In general, it is best to look at a stable existing package to see how to set up the packages correctly. In brief, code development involves
General guidelines follow. 3.2 General instructions for code installationThe following is a quick summary of commands to be executed after installing new code in the common area, or to update links in your own directories, or to update a remote distribution. Sections 2 and 3.5 contain more detailed information about some of these tasks. Code installation:Install the new code in the common area:
Architecture updates:Update the code links, the Makefiles, and the header-file links: rsh $(ARCH)_machine; cd /projects/hwsw/hwsw/$(ARCH)/src/polis; make rslink; cd util; make; cd ..; make makefile; make link_header; make makefile. This second invokation is needed now that the header files are correctly linked. Again, for large or unknown changes, it is best to execute makemakefile_all or make makefile_force (only in the common directory). (For directories in your home directory that you are using for code development, note that you will also have to issue make depend if you want robust dependency-based compilation.)
Compilation:cd /projects/hwsw/hwsw/$(ARCH)/src/polis; Make. Do not interrupt compilation, or if you must, remove all object and library files afterward. Make locks the compilation. If it is already locked by someone else and you are sure they are finished, remove or move the file .make_lock and inform the owner.
Testing:cd /projects/hwsw/hwsw/$(ARCH)/src/polis/examples/test; makeDissemination:Inform the polis group by e-mail of the changes.3.3 Creating new leaf packages and subdirectoriesThis section contains information about the POLIS code structure, i.e., the subdirectories and leaf packages (leaf subdirectories) contained in /projects/hwsw/hwsw/common/src/polis.
3.4 Creating new programsTo create a new POLIS auxiliary program (e.g. golden_gate, strl2shift), follow the existing models. Note also
3.5 Using RCSEach directory should have an RCS subdirectory. Directories and files are created and maintained according to the following rules.
3.6 File PermissionsIt is absolutely imperative that the file permissions are maintained correctly. Using RCS (see Section 3.5) permits organization of file revision and proper file permissions. For other files (examples, auxiliary files, etc.) and for directories, permissions must be explicitly maintained correctly. If the instructions in Section 3.5 are followed carefully, the permissions will be set up correctly. Nonetheless, it is often useful to execute the following in a new directory of files: find . -type f -exec chmod g+w {} ';' find . -type f -exec chgrp hwsw {} ';'or execute find . -type d -exec chmod g+w {} ';' find . -type d -exec chgrp hwsw {} ';'in an updated directory tree (both common and machine-dependent) on ic. 3.7 Automatic DocumentationProgrammers documentation in HTML format is automatically generated with the addition of some simple text in the source files. Makefiles are being set up so that documentation is automatically extracted from the files com_pkg.c, pkg_*.c, pkg.h, and pkg_int.h. To set up this documentation in your package:
3.8 Notes on using the shell scripts and make targets
3.9 On interacting with the POLIS groupInformation of interest to POLIS developers goes to polis@eecs.berkeley.edu. General information on hwsw codesign issues goes to hwsw@eecs.berkeley.edu. Questions and comments on individual packages go to the OWNERS of the package. Keep the bandwidth on e-mail down! Don't respond simply with "I agree". Only include the relevant parts of a previous message.
4 Notes on C-programmingThis section contains a number of helpful hints for C-programming in POLIS. It is no substitute for reading a good programming manual, but does contain information that has been needed in particular in POLIS in the past. See also John Ousterhout's programming style document in /vol/hyper/hyper14/vis/vis/common/doc/TclEngineering/engManual.ps.
Robust switch statements:For robustness, an if-then-else test on a two-valued enumerated type should be done with a switch with a default failure. In this way, one can later add a third value to the enum and get a nice core dump rather than a nasty wrong result. For example: switch (net_trel_out_type (out)) { case CONST: val = net_trel_out_value (out); assert (val < nval); break; case VAR: val = net_var_nval (var) + net_var_index (net_trel_out_var (out)); break; default: fail ("invalid net_trel_out_type"); }This example also shows (1) judicious use of assertions and (2) how to use access functions rather than directly accessing data structures.
Naming data structures and routines:Names of generally accessible data structures and procedures (that is, everything that is not static) should be prefaced with a short package indicator (e.g. net_). All such procedures should be externally declared in the header file (e.g. net.h). All static procedures and internal data structures should be declared in the appropriate internal header file (e.g. net_int.h).
On data structure duplication:Avoid duplicating objects whenever possible. Example: the s-graph package has pointers to CFSM variables (ivar and ovar). Should we do a net_var_copy (i.e. duplicate the whole variable) or just assign the pointer? Don't duplicate if possible. Pointer copying is usually safe, this saves memory, and this way comparison for equality can be done just by pointer comparison, symbol tables can use just st_ptrhash and st_ptrcmp, and so on. Note that for strings this is slightly different - it is easy and often safer to copy them. There is more on this issue in the archives. Of course, remember that whoever allocates data should free it.
On allocating strings:Use the util_strsav() function whenever possible. You will avoid mistakes such as under-allocating space.
On setting variables to NIL after freeing:Don't set a call-by-value variable to NIL in ``free'' functions. This is useless and misleading for two reasons: the value is not passed back to the calling environment, and you are not setting to NIL all other references to that variable. It is also useless to set the FREED fields to an illegal value, because this is done automatically by libmm_p.a.
On testing for NIL values:Avoid simply testing if a parameter is NIL and aborting. You get exactly the same result as you do when using the NIL pointer, but waste time and space. Note that testing for NIL and taking corrective action, on the other hand, is useful and should be done whenever appropriate.
On using data structure fields:Don't use data structure fields directly in packages other than that where the data structure is defined. Use access functions instead.
On memory leaks:A memory leak is any area of memory that is allocated but not freed. POLIS should have none, with a few exceptions due to system I/O buffer allocations. At Berkeley, we have been using mprof on DEC MIPS machines. Purify should be used at locations with SUN workstations and the proper software. To use mprof, compile POLIS, linking with luciano/util/mprof/libc_mp.a instead of whatever_dir/libmm.a. Run luciano/util/mprof/mprof executable_name (probably polis-g) with a few commands of your choice (if possible exercising all the options of your package), and quit. Then issue mprof -terse polis-g and have a look at the leak table. It gives a short stack backtrace of every leak.
On printing information programmatically:Don't just arbitrarily choose stdout or stderr to send to printing routines. Every non-top-level (i.e., non-exported) routine that prints some output should get a FILE* parameter. Top-level calls, from comamnd line interface or from other routines, should use the polisout and poliserr file pointers ONLY. Polisout is for debugging and generic information, while poliserr is for error messages.
On using the basic data structures (hash tables, arrays, etc.):The basic data structures that come with polis (arrays, lists, symbol tables AVL trees, sparse matrices, directed graphs, BDDs, MDDs) serve different purposes and should be used appropriately. For example, if you need to generate a list of unique elements (i.e., check if an object is already in the structure, and insert it otherwise), then you should use a symbol table (or an AVL tree, if you need to retrieve them sorted by insertion key). Brief cross-reference - definitions and optimal use:
Macros:Remember that macro arguments must be put in parentheses in the macro body. For example: #define foreach_net_node_attribute(node,name,value) \ { st_generator *gen;\ st_foreach_item(node->attributes,gen,&name,&value) }must become #define foreach_net_node_attribute(node,name,value) \ { st_generator *gen;\ st_foreach_item((node)->attributes,gen,&(name),&(value)) }
On gcc:gcc should be used for development. The advantage of using an ANSI compiler is that we can check parameter type compatibility during each compilation. gcc will tell you if you call a function with a parameter that is inconsistent with its declaration (or whose declaration is missing from the scope where you use it). It will also tell you if the definition of a function in a .c file matches its extern declaration in a .h file. Ideally, each package should compile without warnings.
On lint:The use of lint should get rid of programming errors such as uninitialized variables. Luciano wrote a (heuristic) lint filter that will remove spurious errors deriving from any use of the FREE macro and of the array package. Anything else should be considered a problem (except in files produced by yacc/lex, which are notoriously full of lint problems). Do a make lint from time to time in your directory to make sure that your code is ``lint free''.
On using cc, gcc, and lint together:cc is used to produce object files (so that dbx and ups can work). gcc and lint are used to check for programming errors, by doing make lint. They produce an output (filtered, to remove junk errors) both to the terminal and to a file called lint.out. There is also a utility that is automatically called when you are making lint in the source tree. It e-mails lint warnings to the OWNER of each package and subpackage.
Bug finding and fixing:When a bug is found:
Whenever a bug is fixed, put the list of fixed bugs in an e-mail that announces the update to the source tree. Now the bug-finder can test the updated code, and if it works, move the bug information to, e.g., polis/OLDBUGS/luciano.
5 ExamplesCompiling the resulting C-files: compile os.c and z_*.c generated by polis with -I<lib site>. In practice, <lib site> is usually polis_lib/os.
6 References
About this document ...POLIS Programmers' Guide This document was generated using the LaTeX2HTML translator Version 0.6.4 (Tues Aug 30 1994) Copyright © 1993, 1994, Nikos Drakos, Computer Based Learning Unit, University of Leeds. The command line arguments were: The translation was initiated by Luciano Lavagno on Fri Aug 2 15:15:30 PDT 1996 Luciano Lavagno Fri Aug 2 15:15:30 PDT 1996 |
Contact |
©2002-2018 U.C. Regents |