Multi-cored process changes
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 30 Oct 2009 20:10:44 +0000 (13:10 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 31 Oct 2009 01:02:31 +0000 (18:02 -0700)
Changes how yielding works and made transitions to and from _M states
more explicit.  Vcore0 can yield and come back up at the hart entry (you
need to prepare_for_multi_mode()).  In general, all cores are equal when
in an _M state, and vcore0 continues running the calling context only on
transition from _S to _M, and not whenever proc_run()ing a RUNNABLE_M.

Added documentation about how processes work, mostly with respect to
the kernel interface.  Part 2 has specific info about the transitions to
and from _M.

Finally moved current to per_cpu_info, and also added current_tf.
Current is still a pointer to the process that is on the core.
Current_tf is a pointer to the trapframe that is on the core's kernel
stack.  This is also stored in per_cpu_info.  It could be discovered
through arcane hackery, but probably isn't worth it.

30 files changed:
.gitignore
Documentation/doxygen/doc/img/nanwan.png [new file with mode: 0644]
Documentation/doxygen/doc/include/annots.h [new file with mode: 0644]
Documentation/doxygen/doc/rosdoc.cfg [new file with mode: 0644]
Documentation/doxygen/doc/rosdoc.main [new file with mode: 0644]
Documentation/processes.txt [new file with mode: 0644]
doc/img/nanwan.png [deleted file]
doc/include/annots.h [deleted file]
doc/rosdoc.cfg [deleted file]
doc/rosdoc.main [deleted file]
kern/arch/i386/ioapic.c
kern/arch/i386/smp_boot.c
kern/arch/i386/trap.c
kern/arch/sparc/cpuinfo.c
kern/arch/sparc/trap.c
kern/include/env.h
kern/include/process.h
kern/include/smp.h
kern/include/syscall.h
kern/src/env.c
kern/src/manager.c
kern/src/process.c
kern/src/resource.c
kern/src/schedule.c
kern/src/syscall.c
user/apps/roslib/mhello.c
user/apps/roslib/mproctests.c
user/roslib/inc/lib.h
user/roslib/src/i386/entry.S
user/roslib/src/libmain.c

index 455d8a5..9aa5c24 100644 (file)
@@ -20,7 +20,7 @@ ros-project.tmproj
 kern/boot
 kern/include/arch
 kern/src/arch
-doc/rosdoc
+Documentation/doxygen/rosdoc
 sim/
 tools/.*
 tools/syscall_server/syscall_server_*
diff --git a/Documentation/doxygen/doc/img/nanwan.png b/Documentation/doxygen/doc/img/nanwan.png
new file mode 100644 (file)
index 0000000..ad47bce
Binary files /dev/null and b/Documentation/doxygen/doc/img/nanwan.png differ
diff --git a/Documentation/doxygen/doc/include/annots.h b/Documentation/doxygen/doc/include/annots.h
new file mode 100644 (file)
index 0000000..7c49bae
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef ANNOT_H
+#define ANNOT_H
+
+#define BOUND(lo, hi)   
+#define COUNT(n)        
+#define SIZE(n)         
+#define SAFE            
+#define SNT             
+#define DANGEROUS       
+
+/* Begin Experimental attributes */
+#define META(p)            
+#define HANDLER_ATOMIC              
+#define LOCK_HANDLER_ATOMIC(...)   
+#define IN_HANDLER_ATOMIC  
+#define IN_HANDLER         
+#define ASYNC              
+#define NORACE             
+#define SYNCHRONOUS        
+#define REGION(r)          
+#define NOREGION           
+#define SOMEREGION         
+#define SAMEREGION         
+#define DELETES_REGION(r)  
+#define GROUP(g)           
+#define NOGROUP            
+#define SOMEGROUP          
+#define SAMEGROUP          
+#define UNIQUE             
+#define NOALIAS            
+#define PAIRED_WITH(c)     
+#define PAIRED(c1,c2)      
+#define ARGPAIRED(c1,c2,arg) 
+#define FNPTRCALLER(fn)    
+#define INITSTRUCT(s)      
+#define NOINIT             
+#define WRITES(...)        
+#define RPROTECT           
+#define WPROTECT           
+#define RWPROTECT          
+#define R_PERMITTED(...) 
+#define W_PERMITTED(...) 
+#define RW_PERMITTED(...) 
+/* End Experimental attributes */
+
+#define BND(lo, hi)     
+#define CT(n)           
+#define SZ(n)           
+
+#define EFAT            
+#define FAT             
+
+#define NULLTERM        
+#define NT              
+#define NTS             
+#define NTC(n)          
+
+#define NTDROPATTR      
+#define NTEXPANDATTR    
+
+#define NULLABLE
+#define OPT             
+#define NONNULL         
+
+#define TRUSTED         
+#define TRUSTEDBLOCK    
+
+#define POLY           
+
+#define COPYTYPE        
+
+//specifies that Deputy's typechecker (but not optimizer) should assume
+//that this lvalue is constant. (unsound)
+#define ASSUMECONST     
+
+#define WHEN(e)         
+
+#define DMEMCPY(x, y, z) 
+#define DMEMSET(x, y, z) 
+#define DMEMCMP(x, y, z)
+
+#define DALLOC(x)       
+#define DREALLOC(x, y)  
+#define DFREE(x)        
+
+#define DVARARG(x)      
+#define DPRINTF(x)      
+
+#define NTDROP(x)       (x)
+#define NTEXPAND(x)     (x)
+#define TC(x)           (x)
+
+#define TVATTR(x)       
+#define TPATTR(x)       
+
+#define TV(x)           void * (x)
+#define TP(x)           
+
+#endif // ANNOT_H
diff --git a/Documentation/doxygen/doc/rosdoc.cfg b/Documentation/doxygen/doc/rosdoc.cfg
new file mode 100644 (file)
index 0000000..ef297b2
--- /dev/null
@@ -0,0 +1,1462 @@
+# Doxyfile 1.5.7
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = ROS
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc/rosdoc/
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = . doc/rosdoc.main
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.h *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = */obj/* */newlib/* */gccinclude/* */.git/*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file .
+
+QHG_LOCATION           = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = doc/include/
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = BOUND COUNT SIZE SAFE SNT DANGEROUS META HANDLER_ATOMIC LOCK_HANDLER_ATOMIC IN_HANDLER_ATOMIC IN_HANDLER ASYNC NORACE SYNCHRONOUS REGION NOREGION SOMEREGION SAMEREGION DELETES_REGION GROUP NOGROUP SOMEGROUP SAMEGROUP UNIQUE NOALIAS PAIRED_WITH PAIRED ARGPAIRED FNPTRCALLER INITSTRUCT NOINIT WRITES RPROTECT WPROTECT RWPROTECT R_PERMITTED W_PERMITTED RW_PERMITTED BND CT SZ EFAT FAT NULLTERM NT NTS NTC NTDROPATTR NTEXPANDATTR NULLABLE OPT NONNULL TRUSTED TRUSTEDBLOCK POLY COPYTYPE ASSUMECONST WHEN DMEMCPY DMEMSET DMEMCMP DALLOC DREALLOC DFREE DVARARG DPRINTF NTDROP NTEXPAND TC TVATTR TPATTR TV TP
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = NO
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = NO
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = NO
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/Documentation/doxygen/doc/rosdoc.main b/Documentation/doxygen/doc/rosdoc.main
new file mode 100644 (file)
index 0000000..7205a85
--- /dev/null
@@ -0,0 +1,17 @@
+/*! \mainpage The ROS Source Documentation
+    \htmlonly
+
+<p>
+Looks like I can now put whatever I want in here in HTML format, 
+so have at it.....
+</p>
+<img src="img/nanwan.png" align=left width=200></img>
+<img src="img/nanwan.png" align=right width=200></img>
+<center><font size=200>
+INCOMPLETE DOCUMENTATION:<br><br>
+ONLY ONE FILE MARKED UP SO FAR: KERN/SRC/PMAP.C<br><br>
+CLICK ON THE 'FILES' TAB IN THE UPPER LEFT AND SCROLL DOWN TO SEE IT
+</font></center>
+
+    \endhtmlonly
+ */
\ No newline at end of file
diff --git a/Documentation/processes.txt b/Documentation/processes.txt
new file mode 100644 (file)
index 0000000..e8fba72
--- /dev/null
@@ -0,0 +1,531 @@
+All things processes!  This explains processes from a high level, especially
+focusing on the user-kernel boundary and transitions to the multi-cored state,
+which is the way in which parallel processes run.  This doesn't discuss deep
+details of the ROS kernel's process code.
+
+This is motivated by two things: kernel scalability and direct support for
+parallel applications.
+
+Part 1: Overview
+Part 2: How They Work
+Part 3: Resource Requests
+Part 4: Notification
+Part 5: Old Arguments (mostly for archival purposes))
+Part 6: Parlab app use cases
+
+Part 1: World View of Processes
+==================================
+A process is the lowest level of control, protection, and organization in the
+kernel.
+
+1.1: What's a process?
+-------------------------------
+Features:
+- They are an executing instance of a program.  A program can load multiple
+  other chunks of code and run them (libraries), but they are written to work
+  with each other, within the same address space, and are in essence one
+  entity.
+- They have one address space/ protection domain.  
+- They run in Ring 3 / Usermode.
+- They can interact with each other, subject to permissions enforced by the
+  kernel.
+- They can make requests from the kernel, for things like resource guarantees.
+  They have a list of resources that are given/leased to them.
+
+None of these are new.  Here's what's new:
+- They can run in a multi-core mode, where its cores run at the same time, and
+  it is aware of changes to these conditions (page faults, preemptions).  It
+  can still request more resources (cores, memory, whatever).
+- Every core in a multi-cored process is *not* backed by a kernel
+  thread/kernel stack, unlike with Linux tasks.
+       - There are *no* per-core run-queues in the kernel that decide for
+         themselves which kernel thread to run.
+- They are not fork()/execed().  They are created(), and then later made
+  runnable.  This allows the controlling process (parent) to do whatever it
+  wants: pass file descriptors, give resources, whatever.
+
+These changes are directly motivated by what is wrong with current SMP
+operating systems as we move towards many-core: direct (first class) support
+for truly parallel processes, kernel scalability, and an ability of a process
+to see through classic abstractions (the virtual processor) to understand (and
+make requests about) the underlying state of the machine.
+
+1.2: What's a partition?
+-------------------------------
+So a process can make resource requests, but some part of the system needs to
+decide what to grant, when to grant it, etc.  This goes by several names:
+scheduler / resource allocator / resource manager.  The scheduler simply says
+when you get some resources, then calls functions from lower parts of the
+kernel to make it happen.
+
+This is where the partitioning of resources comes in.  In the simple case (one
+process per partitioned block of resources), the scheduler just finds a slot
+and runs the process, giving it its resources.  
+
+A big distinction is that the *partitioning* of resources only makes sense
+from the scheduler on up in the stack (towards userspace).  The lower levels
+of the kernel know about resources that are granted to a process.  The
+partitioning is about the accounting of resources and an interface for
+adjusting their allocation.  It is a method for telling the 'scheduler' how
+you want resources to be granted to processes.
+
+A possible interface for this is procfs, which has a nice hierarchy.
+Processes can be grouped together, and resources can be granted to them.  Who
+does this?  A process can create it's own directory entry (a partition), and
+move anyone it controls (parent of, though that's not necessary) into its
+partition or a sub-partition.  Likewise, a sysadmin/user can simply move PIDs
+around in the tree, creating partitions consisting of processes completely
+unaware of each other.
+
+Now you can say things like "give 25% of the system's resources to apache and
+mysql".  They don't need to know about each other.  If you want finer-grained
+control, you can create subdirectories (subpartitions), and give resources on
+a per-process basis.  This is back to the simple case of one process for one
+(sub)partition.
+
+This is all influenced by Linux's cgroups (process control groups).
+http://www.mjmwired.net/kernel/Documentation/cgroups.txt. They group processes
+together, and allow subsystems to attach meaning to those groups.
+
+Ultimately, I view partitioning as something that tells the kernel how to
+grant resources.  It's an abstraction presented to userspace and higher levels
+of the kernel.  The specifics still need to be worked out, but by separating
+them from the process abstraction, we can work it out and try a variety of
+approaches.
+
+The actual granting of resources and enforcement is done by the lower levels
+of the kernel (or by hardware, depending on future architectural changes).
+
+Part 2: How They Work
+===============================
+2.1: States
+-------------------------------
+PROC_CREATED
+PROC_RUNNABLE_S
+PROC_RUNNING_S
+PROC_WAITING
+PROC_DYING
+PROC_RUNNABLE_M
+PROC_RUNNING_M
+
+Difference between the _M and the _S states:
+- _S : legacy process mode
+- RUNNING_M implies *guaranteed* core(s).  You can be a single core in the
+  RUNNING_M state.  The guarantee is subject to time slicing, but when you
+  run, you get all of your cores.
+- The time slicing is at a coarser granularity for _M states.  This means that
+  when you run an _S on a core, it should be interrupted/time sliced more
+  often, which also means the core should be classified differently for a
+  while.  Possibly even using it's local APIC timer.
+- A process in an _M state will be informed about changes to its state, e.g.,
+  will have a handler run in the event of a page fault
+
+For more details, check out kern/inc/process.h  For valid transitions between
+these, check out kern/src/process.c's proc_set_state().
+
+2.2: Creation and Running
+-------------------------------
+Unlike the fork-exec model, processes are created, and then explicitly made
+runnable.  In the time between creation and running, the parent (or another
+controlling process) can do whatever it wants with the child, such as pass
+specific file descriptors, map shared memory regions (which can be used to
+pass arguments).
+
+New processes are not a copy-on-write version of the parent's address space.
+Due to our changes in the threading model, we no longer need (or want) this
+behavior left over from the fork-exec model.
+
+By splitting the creation from the running and by explicitly sharing state
+between processes (like inherited file descriptors), we avoid a lot of
+concurrency and security issues.
+
+2.3: Vcoreid vs Pcoreid
+-------------------------------
+The vcoreid is a virtual cpu number.  Its purpose is to provide an easy way
+for the kernel and userspace to talk about the same core.  pcoreid (physical)
+would also work.  The vcoreid makes things a little easier, such as when a
+process wants to refer to one of its other cores (not the calling core).  It
+also makes the event notification mechanisms easier to specify and maintain.
+
+The vcoreid only makes sense when in an _M mode.  In _S mode, your vcoreid is
+0.  Vcoreid's only persist when in _M mode.  If you leave _M mode on a non-0
+vcore, that context becomes vcore0.  This can get tricky for userspace's
+stacks (more below).
+
+Processes that care about locality should check what their pcoreid is.  This
+is currently done via sys_getcpuid().  The name will probably change.
+
+2.4: Transitioning to and from states
+-------------------------------
+2.4.1: To go from _S to _M, a process requests cores.
+--------------
+A resource request from 0 to 1 or more causes a transition from _S to _M.  The
+calling context moves to vcore0 (proc_run() handles that) and continues from
+where it left off (the return point of the syscall).  
+
+For all other cores, and all subsequently allocated cores, they start at the
+elf entry point, with vcoreid in eax or a suitable arch-specific manner.  This
+could be replaced with a syscall that returns the vcoreid, but probably won't
+to help out sparc.
+
+Future proc_runs(), like from RUNNABLE_M to RUNNING_M start all cores at the
+entry point, including vcore0.  The magic of moving contexts only happens on
+the transition from _S to _M (which the process needs to be aware of for a
+variety of reasons).  This also means that userspace needs to handle vcore0
+coming up at the entry point again (and not starting the program over).  I
+recommend setting a global variable that can be checked from assembly before
+going to _M the first time.
+
+When coming in to the entry point, new cores should grab a stack.  There are a
+few ways to do this.  They ought to be the same stack every time for a
+specific vcore.  They will be the transition stacks (in Lithe terms) that are
+used as jumping-off points for future function calls.  These stacks need to be
+used in a continuation-passing style.  Start from the top every time.  The
+reason for that is actual contexts may move around, and vcores will come and
+go - and each vcore will always reuse the same stack.  Lithe works this way,
+so it's not an issue.
+
+It's recommended that while in _S mode the process allocates stacks and puts
+them in an array, indexed by vcoreid for the entry point to easily find them.
+Then each core grabs its transition stack, then goes into hart_entry.
+
+Userspace needs to make sure the calling context (which will become vcore0) is
+on a good stack, like USTACKTOP.  This could happen if you leave _M from a core
+other than vcore0, then return to _M mode.  While in _S mode, you were still
+on whatever stack you came from (like vcore3's transition stack).
+
+2.4.2: To go from _M to _S, a process requests 0 cores
+--------------
+The caller becomes the new _S context.  Everyone else gets trashed
+(abandon_core()).  Their stacks are still allocated and it is up to userspace
+to deal with this.  In general, they will regrab their transition stacks when
+they come back up.  Their other stacks and whatnot (like TBB threads) need to
+be dealt with.
+
+As mentioned above, when the caller next switches to _M, that context
+(including its stack) becomes the new vcore0.
+
+2.4.3: Requesting more cores while in _M
+--------------
+Any core can request more cores and adjust the resource allocation in any way.
+These new cores come up just like the original new cores in the transition
+from _S to _M: at the entry point.
+
+2.4.4: Yielding
+--------------
+Yielding gives up a core.  In _S mode, it will transition from RUNNING_S to
+RUNNABLE_S.  The context is saved in env_tf.  A yield will *not* transition
+from _M to _S.
+
+In _M mode, this yields the calling core.  The kernel will rip it out of your
+vcore list.  A process can yield its cores in any order.  The kernel will
+"fill in the holes of the vcoremap" when for any future newcores (e.g., proc A
+has 4 vcores, yields vcore2, and then asks for another vcore.  The new one
+will be vcore2).
+
+When you are in _M and yield your last core, it is an m_yield.  This
+completely suspends all cores, like a voluntary preemption.  When the process
+is run again, all cores will come up at the entry point (including vcore0 and
+the calling core).  This isn't implemented yet, and will wait on some work
+with preemption.
+
+2.4.5: Others
+--------------
+There are other transitions, mostly self-explanatory.  We don't currently use
+any WAITING states, since we have nothing to block on yet.  DYING is a state
+when the kernel is trying to kill your process, which can take a little while
+to clean up.
+       
+2.5: Preemption
+-------------------------------
+None of this is implemented yet, or fully flushed out.
+
+2.5.1: Ideas
+--------------
+The rough plan is to notify beforehand, then take action if userspace doesn't
+yield.
+
+When a core is preempted or interrupted for any reason (like a pagefault or
+other trap), the context is saved in a structure in procinfo that contains the
+vcoreid, a code for what happened, and the actual context (probably always
+including FP/SSE registers).
+
+If userspace is keeping the core, like with a page fault or other trap, that
+core will start up at the entry point, and regrab its transition stack.  There
+could be issues with this, if the trap came while operating on that stack.
+There'll probably be some way other way to help userspace know something
+happened.  Recursive (page) faults are also tricky.
+
+If it lost the core, like in a preemption, the context is saved (fully), and
+the process is notified (in the manner it wishes).  See Part 4.
+
+When a process loses all of its cores, it just loses them all.  There is no
+notification interrupt (though there will be a message posted).  When a
+process comes up at the entry point once it is run again, it should check its
+event queue (if it cares).
+
+2.5.2: Issues with preemption, trap redirection, and event notification
+--------------
+There are other issues with cascading interrupts (when contexts are still
+running handlers).  Imagine a pagefault, followed by preempting the handler.
+It doesn't make sense to run the preempt context after the page fault.  The
+difficulty is in determining when the context is no longer handling an event.
+We could consider using a register, controllable by userspace, to give the
+kernel this hint.  Maybe have a window of time we won't preempt again (though
+that is really painful.  How long is this window?).
+
+Even worse, consider vcore0 is set up to receive all events.  If events come
+in faster than it can process them, it will both nest too deep and process out
+of order.
+
+Also, we don't have a good way to handle interrupts/events when on the
+transition stack at all (let alone cascading or overflow).  The kernel will
+just start you from the top of the stack, which will eventually clobber
+whatever the core was doing previously.
+
+We can consider using another register to signal some sort of exceptional
+event, and before touching the transition stack, the core can jump to a
+per-core exception stack.  Perhaps to avoid nesting exceptions, when an
+interrupt comes in, the kernel can see userspace is on it's exception stack
+and not post the event, and it's up to userspace to check for any missed
+events before leaving its core.  Ugly.  And can't handle traps.
+
+Pre-Notification issues: how much time does userspace need to clean up and
+yield?  How quickly does the kernel need the core back (for scheduling
+reasons)?
+
+Part 3: Resource Requests
+===============================
+A process can ask for resources from the kernel.  The kernel either grants
+these requests or not, subject to QoS guarantees, or other scheduler-related
+criteria.
+
+A process requests resources, currently via sys_resource_req.  The form of a
+request is to tell the kernel how much of a resource it wants.  Currently,
+this is the amt_wanted.  We'll also have a minimum amount wanted, which tells
+the scheduler not to run the process until the minimum amount of resources are
+available.
+
+How the kernel actually grants resources is resource-specific.  In general,
+there are functions like proc_give_cores() (which gives certain cores to a
+process) that actually does the allocation, as well as adjusting the
+amt_granted for that resource.
+
+For expressing QoS guarantees, we'll probably use something like procfs (as
+mentioned above) to explicitly tell the scheduler/resource manager what the
+user/sysadmin wants.  An interface like this ought to be usable both by
+programs as well as simple filesystem tools (cat, etc).
+
+Guarantees exist regardless of whether or not the allocation has happened.  An
+example of this is when a process may be guaranteed to use 8 cores, but
+currently only needs 2.  Whenever it asks for up to 8 cores, it will get them.
+The exact nature of the guarantee is TBD, but there will be some sort of
+latency involved in the guarantee for systems that want to take advantage of
+idle resources (compared to simply reserving and not allowing anyone else to
+use them).  A latency of 0 would mean a process wants it instantly, which
+probably means they ought to be already allocated (and billed to) that
+process.  
+
+Part 4: Event Notification
+===============================
+One of the philosophical goals of ROS is to expose information up to userspace
+(and allow requests based on that information).  There will be a variety of
+events in the system that processes will want to know about.  To handle this,
+we'll eventually build something like the following.
+
+All events will have a number, like an interrupt vector.  Each process will
+have an event queue.  On most architectures, it will be a simple
+producer-consumer ring buffer sitting in the "shared memory" procdata region
+(shared between the kernel and userspace).  The kernel writes a message into
+the buffer with the event number and some other helpful information.  For
+instance, a preemption event will say which vcore was preempted and provide a
+pointer to the context that was preempted.
+
+Additionally, the process may request to be actively notified of specific
+events.  This is done by having the process write into an event vector table
+(like an IDT) in procdata.  For each event, the process can write a function
+pointer and a vcoreid.  The kernel will execute that function on the given
+core (and pass appropriate arguments, such as a pointer to the message in the
+event queue and a pointer to the context that was just interrupted).
+
+Part 5: Old Arguments about Processes vs Partitions
+===============================
+This is based on my interpretation of the cell (formerly what I thought was
+called a partition).
+
+5.1: Program vs OS
+-------------------------------
+A big difference is what runs inside the object.  I think trying to support
+OS-like functionality is a quick path to unnecessary layers and complexity,
+esp for the common case.  This leads to discussions of physical memory
+management, spawning new programs, virtualizing HW, shadow page tables,
+exporting protection rings, etc.
+
+This unnecessarily brings in the baggage and complexity of supporting VMs,
+which are a special case.  Yes, we want processes to be able to use their
+resources, but I'd rather approach this from the perspective of "what do they
+need?" than "how can we make it look like a real machine."  Virtual machines
+are cool, and paravirtualization influenced a lot of my ideas, but they have
+their place and I don't think this is it.
+
+For example, exporting direct control of physical pages is a bad idea.  I
+wasn't clear if anyone was advocating this or not.  By exposing actual machine
+physical frames, we lose our ability to do all sorts of things (like swapping,
+for all practical uses, and other VM tricks).  If the cell/process thinks it
+is manipulating physical pages, but really isn't, we're in the VM situation of
+managing nested or shadow page tables, which we don't want.
+
+For memory, we'd be better off giving an allocation of a quantity frames, not
+specific frames.  A process can pin up to X pages, for instance.  It can also
+pick pages to be evicted when there's memory pressure.  There are already
+similar ideas out there, both in POSIX and in ACPM.
+
+Instead of mucking with faking multiple programs / entities within an cell,
+just make more processes.  Otherwise, you'd have to export weird controls that
+the kernel is doing anyway (and can do better!), and have complicated middle
+layers.
+
+5.2: Multiple "Things" in a "partition"
+-------------------------------
+In the process-world, the kernel can make a distinction between different
+entities that are using a block of resources.  Yes, "you" can still do
+whatever you want with your resources.  But the kernel directly supports
+useful controls that you want. 
+- Multiple protection domains are no problem.  They are just multiple
+  processes.  Resource allocation is a separate topic.
+- Processes can control one another, based on a rational set of rules.  Even
+  if you have just cells, we still need them to be able to control one another
+  (it's a sysadmin thing).
+
+"What happens in a cell, stays in a cell."  What does this really mean?  If
+it's about resource allocation and passing of resources around, we can do that
+with process groups.  If it's about the kernel not caring about what code runs
+inside a protection domain, a process provides that.  If it's about a "parent"
+program trying to control/kill/whatever a "child" (even if it's within a cell,
+in the cell model), you *want* the kernel to be involved.  The kernel is the
+one that can do protection between entities.
+
+5.3: Other Things
+-------------------------------
+Let the kernel do what it's made to do, and in the best position to do: manage
+protection and low-level resources.
+
+Both processes and partitions "have" resources.  They are at different levels
+in the system.  A process actually gets to use the resources.  A partition is
+a collection of resources allocated to one or more processes.
+
+In response to this:
+
+On 2009-09-15 at 22:33 John Kubiatowicz wrote:
+> John Shalf wrote:  
+> >
+> > Anyhow, Barret is asking that resource requirements attributes be 
+> > assigned on a process basis rather than partition basis.  We need
+> > to justify why gang scheduling of a partition and resource
+> > management should be linked.  
+
+I want a process to be aware of it's specific resources, as well as the other
+members of it's partition.  An individual process (which is gang-scheduled in
+multi-core mode) has a specific list of resources.  Its just that the overall
+'partition of system resources' is separate from the list of specific
+resources of a process, simply because there can be many processes under the
+same partition (collection of resources allocated).
+
+> >  
+> Simplicity!
+> 
+> Yes, we can allow lots of options, but at the end of the day, the 
+> simplest model that does what we need is likely the best. I don't
+> want us to hack together a frankenscheduler.  
+
+My view is also simple in the case of one address space/process per
+'partition.'  Extending it to multiple address spaces is simply asking that
+resources be shared between processes, but without design details that I
+imagine will be brutally complicated in the Cell model.
+
+
+Part 6: Use Cases
+===============================
+6.1: Matrix Multiply / Trusting Many-core app
+-------------------------------
+The process is created by something (bash, for instance).  It's parent makes
+it runnable.  The process requests a bunch of cores and RAM.  The scheduler
+decides to give it a certain amount of resources, which creates it's partition
+(aka, chunk of resources granted to it's process group, of which it is the
+only member).  The sysadmin can tweak this allocation via procfs.
+
+The process runs on its cores in it's multicore mode.  It is gang scheduled,
+and knows how many cores there are.  When the kernel starts the process on
+it's extra cores, it passes control to a known spot in code (the ELF entry
+point), with the virtual core id passed as a parameter.
+
+The code runs from a single binary image, eventually with shared
+object/library support.  It's view of memory is a virtual address space, but
+it also can see it's own page tables to see which pages are really resident
+(similar to POSIX's mincore()).
+
+When it comes time to lose a core, or be completely preempted, the process is
+notified by the OS running a handler of the process's choosing (in userspace).
+The process can choose what to do (pick a core to yield, prepare to be
+preempted, etc).
+
+To deal with memory, the process is notified when it page faults, and keeps
+its core.  The process can pin pages in memory.  If there is memory pressure,
+the process can tell the kernel which pages to unmap.
+
+This is the simple case.
+
+6.2: Browser
+-------------------------------
+In this case, a process wants to create multiple protection domains that share
+the same pool of resources.  Or rather, with it's own allocated resources.
+
+The browser process is created, as above.  It creates, but does not run, it's
+untrusted children.  The kernel will have a variety of ways a process can
+"mess with" a process it controls.  So for this untrusted child, the parent
+can pass (for example), a file descriptor of what to render, "sandbox" that
+process (only allow a whitelist of syscalls, e.g. can only read and write
+descriptors it has).  You can't do this easily in the cell model.
+
+The parent can also set up a shared memory mapping / channel with the child.
+
+For resources, the parent can put the child in a subdirectory/ subpartition
+and give a portion of its resources to that subpartition.  The scheduler will
+ensure that both the parent and the child are run at the same time, and will
+give the child process the resources specified.  (cores, RAM, etc).
+
+After this setup, the parent will then make the child "runnable".  This is why
+we want to separate the creation from the runnability of a process, which we
+can't do with the fork/exec model.
+
+The parent can later kill the child if it wants, reallocate the resources in
+the partition (perhaps to another process rendering a more important page),
+preempt that process, whatever.
+
+6.3: SMP Virtual Machines
+-------------------------------
+The main issue (regardless of paravirt or full virt), is that what's running
+on the cores may or may not trust one another.  One solution is to run each
+VM-core in it's own process (like with Linux's KVM, it uses N tasks (part of
+one process) for an N-way SMP VM).  The processes set up the appropriate
+shared memory mapping between themselves early on.  Another approach would be
+to allow a multi-cored process to install specific address spaces on each
+core, and interpose on syscalls, privileged instructions, and page faults.
+This sounds very much like the Cell approach, which may be fine for a VM, but
+not for the general case of a process.
+
+Or with a paravirtualized SMP guest, you could (similar to the L4Linux way,)
+make any Guest OS processes actual processes in our OS.  The resource
+allocation to the Guest OS partition would be managed by the parent process of
+the group (which would be running the Guest OS kernel).  We still need to play
+tricks with syscall redirection.
+
+For full virtualization, we'd need to make use of hardware virtualization
+instructions. Dealing with the VMEXITs, emulation, and other things is a real
+pain, but already done.  The long range plan was to wait til the
+http://v3vee.org/ project supported Intel's instructions and eventually
+incorporate that.
+
+All of these ways involve subtle and not-so-subtle difficulties.  The
+Cell-as-OS mode will have to deal with them for the common case, which seems
+brutal.  And rather unnecessary.
diff --git a/doc/img/nanwan.png b/doc/img/nanwan.png
deleted file mode 100644 (file)
index ad47bce..0000000
Binary files a/doc/img/nanwan.png and /dev/null differ
diff --git a/doc/include/annots.h b/doc/include/annots.h
deleted file mode 100644 (file)
index 7c49bae..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef ANNOT_H
-#define ANNOT_H
-
-#define BOUND(lo, hi)   
-#define COUNT(n)        
-#define SIZE(n)         
-#define SAFE            
-#define SNT             
-#define DANGEROUS       
-
-/* Begin Experimental attributes */
-#define META(p)            
-#define HANDLER_ATOMIC              
-#define LOCK_HANDLER_ATOMIC(...)   
-#define IN_HANDLER_ATOMIC  
-#define IN_HANDLER         
-#define ASYNC              
-#define NORACE             
-#define SYNCHRONOUS        
-#define REGION(r)          
-#define NOREGION           
-#define SOMEREGION         
-#define SAMEREGION         
-#define DELETES_REGION(r)  
-#define GROUP(g)           
-#define NOGROUP            
-#define SOMEGROUP          
-#define SAMEGROUP          
-#define UNIQUE             
-#define NOALIAS            
-#define PAIRED_WITH(c)     
-#define PAIRED(c1,c2)      
-#define ARGPAIRED(c1,c2,arg) 
-#define FNPTRCALLER(fn)    
-#define INITSTRUCT(s)      
-#define NOINIT             
-#define WRITES(...)        
-#define RPROTECT           
-#define WPROTECT           
-#define RWPROTECT          
-#define R_PERMITTED(...) 
-#define W_PERMITTED(...) 
-#define RW_PERMITTED(...) 
-/* End Experimental attributes */
-
-#define BND(lo, hi)     
-#define CT(n)           
-#define SZ(n)           
-
-#define EFAT            
-#define FAT             
-
-#define NULLTERM        
-#define NT              
-#define NTS             
-#define NTC(n)          
-
-#define NTDROPATTR      
-#define NTEXPANDATTR    
-
-#define NULLABLE
-#define OPT             
-#define NONNULL         
-
-#define TRUSTED         
-#define TRUSTEDBLOCK    
-
-#define POLY           
-
-#define COPYTYPE        
-
-//specifies that Deputy's typechecker (but not optimizer) should assume
-//that this lvalue is constant. (unsound)
-#define ASSUMECONST     
-
-#define WHEN(e)         
-
-#define DMEMCPY(x, y, z) 
-#define DMEMSET(x, y, z) 
-#define DMEMCMP(x, y, z)
-
-#define DALLOC(x)       
-#define DREALLOC(x, y)  
-#define DFREE(x)        
-
-#define DVARARG(x)      
-#define DPRINTF(x)      
-
-#define NTDROP(x)       (x)
-#define NTEXPAND(x)     (x)
-#define TC(x)           (x)
-
-#define TVATTR(x)       
-#define TPATTR(x)       
-
-#define TV(x)           void * (x)
-#define TP(x)           
-
-#endif // ANNOT_H
diff --git a/doc/rosdoc.cfg b/doc/rosdoc.cfg
deleted file mode 100644 (file)
index ef297b2..0000000
+++ /dev/null
@@ -1,1462 +0,0 @@
-# Doxyfile 1.5.7
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file 
-# that follow. The default is UTF-8 which is also the encoding used for all 
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
-# iconv built into libc) for the transcoding. See 
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = ROS
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 0.1
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = doc/rosdoc/
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
-# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
-# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
-# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
-# Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like regular Qt-style comments 
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF      = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
-# interpret the first line (until the first dot) of a Qt-style 
-# comment as the brief description. If set to NO, the comments 
-# will behave just like regular Qt-style comments (thus requiring 
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Java. For instance, namespaces will be presented as packages, qualified 
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
-# sources. Doxygen will then generate output that is tailored for 
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
-# to include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also make the inheritance and collaboration 
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
-# Doxygen will parse them like normal C++ but will assume all classes use public 
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter 
-# and setter methods for a property. Setting this option to YES (the default) 
-# will make doxygen to replace the get and set methods by a property in the 
-# documentation. This will only work if the methods are indeed getting or 
-# setting a simple type. If this is not the case, or you want to show the 
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
-# is documented as struct, union, or enum with the name of the typedef. So 
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
-# with name TypeT. When disabled the typedef will appear as a member of a file, 
-# namespace, or class. And the struct will be named TypeS. This can typically 
-# be useful for C code in case the coding convention dictates that all compound 
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is 
-# probably good enough. For larger projects a too small cache size can cause 
-# doxygen to be busy swapping symbols to and from disk most of the time 
-# causing a significant performance penality. 
-# If the system has enough physical memory increasing the cache will improve the 
-# performance by keeping more symbols in memory. Note that the value works on 
-# a logarithmic scale so increasing the size by one will rougly double the 
-# memory usage. The cache size is given by this formula: 
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be 
-# extracted and appear in the documentation as a namespace called 
-# 'anonymous_namespace{file}', where file will be replaced with the base 
-# name of the file that contains the anonymous namespace. By default 
-# anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = YES
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
-# hierarchy of group names into alphabetical order. If set to NO (the default) 
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the 
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
-# Namespaces page.  This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from 
-# the version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    = 
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
-# doxygen. The layout file controls the global structure of the generated output files 
-# in an output format independent way. The create the layout file that represents 
-# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
-# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
-# of the layout file.
-
-LAYOUT_FILE            = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = . doc/rosdoc.main
-
-# This tag can be used to specify the character encoding of the source files 
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
-# also the default input encoding. Doxygen uses libiconv (or the iconv built 
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
-# the list of possible encodings.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS          = *.h *.c
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = */obj/* */newlib/* */gccinclude/* */.git/*
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the 
-# output. The symbol name can be a fully qualified name, a word, or if the 
-# wildcard * is used, a substring. Examples: ANamespace, AClass, 
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS        = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
-# documentation will contain sections that can be hidden and shown after the 
-# page has loaded. For this to work a browser that supports 
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files 
-# will be generated that can be used as input for Apple's Xcode 3 
-# integrated development environment, introduced with OSX 10.5 (Leopard). 
-# To create a documentation set, doxygen will generate a Makefile in the 
-# HTML output directory. Running make will produce the docset in that 
-# directory and running "make install" will install the docset in 
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
-# it at startup. 
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
-
-GENERATE_DOCSET        = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
-# feed. A documentation feed provides an umbrella under which multiple 
-# documentation sets from a single provider (such as a company or product suite) 
-# can be grouped.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
-# should uniquely identify the documentation set bundle. This should be a 
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING     = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
-# are set, an additional index file will be generated that can be used as input for 
-# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
-# HTML documentation.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
-# be used to specify the file name of the resulting .qch file. 
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE               = 
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
-# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
-# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
-# be used to specify the location of Qt's qhelpgenerator. 
-# If non-empty doxygen will try to run qhelpgenerator on the generated 
-# .qhp file .
-
-QHG_LOCATION           = 
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to FRAME, a side panel will be generated
-# containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature. Other possible values 
-# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list;
-# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
-# disables this behavior completely. For backwards compatibility with previous
-# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
-# respectively.
-
-GENERATE_TREEVIEW      = NONE
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-# Use this tag to change the font size of Latex formulas included 
-# as images in the HTML documentation. The default is 10. Note that 
-# when you change the font size after a successful doxygen run you need 
-# to manually remove any form_*.png images from the HTML output directory 
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE       = 10
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF     = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = doc/include/
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = BOUND COUNT SIZE SAFE SNT DANGEROUS META HANDLER_ATOMIC LOCK_HANDLER_ATOMIC IN_HANDLER_ATOMIC IN_HANDLER ASYNC NORACE SYNCHRONOUS REGION NOREGION SOMEREGION SAMEREGION DELETES_REGION GROUP NOGROUP SOMEGROUP SAMEGROUP UNIQUE NOALIAS PAIRED_WITH PAIRED ARGPAIRED FNPTRCALLER INITSTRUCT NOINIT WRITES RPROTECT WPROTECT RWPROTECT R_PERMITTED W_PERMITTED RW_PERMITTED BND CT SZ EFAT FAT NULLTERM NT NTS NTC NTDROPATTR NTEXPANDATTR NULLABLE OPT NONNULL TRUSTED TRUSTEDBLOCK POLY COPYTYPE ASSUMECONST WHEN DMEMCPY DMEMSET DMEMCMP DALLOC DREALLOC DFREE DVARARG DPRINTF NTDROP NTEXPAND TC TVATTR TPATTR TV TP
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
-# powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see 
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
-# the mscgen tool resides. If left empty the tool is assumed to be found in the 
-# default search path.
-
-MSCGEN_PATH            = 
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = YES
-
-# By default doxygen will write a font called FreeSans.ttf to the output 
-# directory and reference it in all dot files that doxygen generates. This 
-# font does not include all possible unicode characters however, so when you need 
-# these (or just want a differently looking font) you can specify the font name 
-# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
-# which can be done by putting it in a standard location or by setting the 
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
-# containing the font.
-
-DOT_FONTNAME           = FreeSans
-
-# By default doxygen will tell dot to use the output directory to look for the 
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
-# different font using DOT_FONTNAME you can set the path where dot 
-# can find it using this tag.
-
-DOT_FONTPATH           = 
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = NO
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = NO
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = NO
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = NO
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
-# doxygen will generate a call dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable call graphs 
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH             = YES
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
-# doxygen will generate a caller dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable caller 
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH           = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = NO
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
-# nodes that will be shown in the graph. If the number of nodes in a graph 
-# becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the 
-# number of direct children of the root node in a graph is already larger than 
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that the size of a graph can be further restricted by 
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, because dot on Windows does not 
-# seem to support this out of the box. Warning: Depending on the platform used, 
-# enabling this option may lead to badly anti-aliased labels on the edges of 
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
diff --git a/doc/rosdoc.main b/doc/rosdoc.main
deleted file mode 100644 (file)
index 7205a85..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*! \mainpage The ROS Source Documentation
-    \htmlonly
-
-<p>
-Looks like I can now put whatever I want in here in HTML format, 
-so have at it.....
-</p>
-<img src="img/nanwan.png" align=left width=200></img>
-<img src="img/nanwan.png" align=right width=200></img>
-<center><font size=200>
-INCOMPLETE DOCUMENTATION:<br><br>
-ONLY ONE FILE MARKED UP SO FAR: KERN/SRC/PMAP.C<br><br>
-CLICK ON THE 'FILES' TAB IN THE UPPER LEFT AND SCROLL DOWN TO SEE IT
-</font></center>
-
-    \endhtmlonly
- */
\ No newline at end of file
index 483f32b..2e437e6 100644 (file)
@@ -46,7 +46,7 @@ void ioapic_init() {
        // We define a entry to be invalid by having an ioapic_address of NULL (0x0)
        memset(ioapic_redirects, 0x0, sizeof(ioapic_redirects));
        
-       extern uint8_t num_cpus;
+       extern volatile uint32_t num_cpus;
        uint32_t num_inconsistent_pci_mappings = 0;     // Increment if we find inconsistent mappings between
                                                                                                //  mptables and the pci bus.
        
@@ -164,7 +164,7 @@ void ioapic_route_irq(uint8_t irq, uint8_t dest) {
        }
 
        // THIS IS A TEMP CHECK. IF WE USE LOGICAL PARTITIONS THIS MUST BE REMOVED
-        extern uint8_t num_cpus;
+        extern volatile uint32_t num_cpus;
        if (dest >= num_cpus)
                panic("TRYING TO REROUTE TO AN INVALID DESTINATION!");
        
index c6e7ddb..cc4ef4d 100644 (file)
@@ -28,7 +28,7 @@
 #include <timing.h>
 
 extern handler_wrapper_t (RO handler_wrappers)[NUM_HANDLER_WRAPPERS];
-volatile uint8_t num_cpus = 0xee;
+volatile uint32_t num_cpus = 0xee;
 uintptr_t RO smp_stack_top;
 
 #define DECLARE_HANDLER_CHECKLISTS(vector)                          \
index 2b90f03..7a1f9c7 100644 (file)
@@ -17,7 +17,6 @@
 #include <process.h>
 #include <stdio.h>
 #include <slab.h>
-
 #include <syscall.h>
 
 taskstate_t RO ts;
@@ -185,9 +184,8 @@ trap_dispatch(trapframe_t *tf)
                case T_SYSCALL:
                        // check for userspace, for now
                        assert(tf->tf_cs != GD_KT);
-                       // Note we pass the tf ptr along, in case syscall needs to block
                        tf->tf_regs.reg_eax =
-                               syscall(current, tf, tf->tf_regs.reg_eax, tf->tf_regs.reg_edx,
+                               syscall(current, tf->tf_regs.reg_eax, tf->tf_regs.reg_edx,
                                        tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx,
                                        tf->tf_regs.reg_edi, tf->tf_regs.reg_esi);
                        proc_startcore(current, tf); // Note the comment in syscall.c
@@ -209,6 +207,7 @@ trap_dispatch(trapframe_t *tf)
 void
 env_push_ancillary_state(env_t* e)
 {
+       // TODO: (HSS) handle silly state (don't really want this per-process)
        // Here's where you'll save FP/MMX/XMM regs
 }
 
@@ -223,22 +222,18 @@ trap(trapframe_t *tf)
 {
        //printk("Incoming TRAP frame on core %d at %p\n", core_id(), tf);
 
-       // TODO: do this once we know we are are not returning to the current
-       // context.  doing it now is safe. (HSS)
-       // we also need to sort this wrt multiple contexts
-       env_push_ancillary_state(current);
+       /* Note we are not preemptively saving the TF in the env_tf.  We do maintain
+        * a reference to it in current_tf (a per-cpu pointer).
+        * In general, only save the tf and any silly state once you know it
+        * is necessary (blocking).  And only save it in env_tf when you know you
+        * are single core (PROC_RUNNING_S) */
+       set_current_tf(tf);
 
        if ((tf->tf_cs & ~3) != GD_UT && (tf->tf_cs & ~3) != GD_KT) {
                print_trapframe(tf);
                panic("Trapframe with invalid CS!");
        }
 
-       /* If we're vcore0, save the trapframe in the proc's env_tf.  make sure
-        * silly state is sorted (HSS). This applies to any RUNNING_* state. */
-       if (current->vcoremap[0] == core_id()) {
-               current->env_tf = *tf;
-               tf = &current->env_tf;
-       }
        // Dispatch based on what type of trap occurred
        trap_dispatch(tf);
 
@@ -254,14 +249,12 @@ trap(trapframe_t *tf)
 void
 irq_handler(trapframe_t *tf)
 {
+       // save a per-core reference to the tf
+       set_current_tf(tf);
        //if (core_id())
        //      cprintf("Incoming IRQ, ISR: %d on core %d\n", tf->tf_trapno, core_id());
        // merge this with alltraps?  other than the EOI... or do the same in all traps
 
-       // TODO: do this once we know we are are not returning to the current
-       // context.  doing it now is safe. (HSS)
-       env_push_ancillary_state(current);
-
        extern handler_wrapper_t (RO handler_wrappers)[NUM_HANDLER_WRAPPERS];
 
        // determine the interrupt handler table to use.  for now, pick the global
@@ -363,14 +356,10 @@ void sysenter_init(void)
 /* This is called from sysenter's asm, with the tf on the kernel stack. */
 void sysenter_callwrapper(struct Trapframe *tf)
 {
-       /* If we're vcore0, save the trapframe in the proc's env_tf.  make sure
-        * silly state is sorted (HSS). This applies to any RUNNING_* state. */
-       if (current->vcoremap[0] == core_id()) {
-               current->env_tf = *tf;
-               tf = &current->env_tf;
-       }
-       // Note we pass the tf ptr along, in case syscall needs to block
-       tf->tf_regs.reg_eax = (intreg_t) syscall(current, tf,
+       // save a per-core reference to the tf
+       set_current_tf(tf);
+
+       tf->tf_regs.reg_eax = (intreg_t) syscall(current,
                                                 tf->tf_regs.reg_eax,
                                                 tf->tf_regs.reg_edx,
                                                 tf->tf_regs.reg_ecx,
index 6599a24..10311ab 100644 (file)
@@ -86,7 +86,6 @@ void
 backtrace(void)
 {
        int i = 0, j;
-       env_t* curenv = curenvs[core_id()];
 
        flush_windows();
 
@@ -119,11 +118,11 @@ backtrace(void)
                        newsp = *((void**)sp+14);
                        pc = *((void**)sp+15);
                }
-               else if(curenv)
+               else if(current)
                {
                        error_t ret;
-                       ret  = memcpy_from_user(curenv,&newsp,(void**)sp+14,sizeof(void*));
-                       ret |= memcpy_from_user(curenv,&pc,(void**)sp+15,sizeof(void*));
+                       ret  = memcpy_from_user(current,&newsp,(void**)sp+14,sizeof(void*));
+                       ret |= memcpy_from_user(current,&pc,(void**)sp+15,sizeof(void*));
                        if(ret)
                        {
                                warn("Backtrace would have caused access exception; corrupt user stack?");
@@ -132,7 +131,7 @@ backtrace(void)
                }
                else
                {
-                       warn("Can't backtrace from user with curenv == NULL!");
+                       warn("Can't backtrace from user with current == NULL!");
                        break;
                }
        }
index 88d0a43..373fe5d 100644 (file)
@@ -225,9 +225,19 @@ handle_syscall(trapframe_t* state)
        state->pc = state->npc;
        state->npc += 4;
 
-       env_push_ancillary_state(current);
+       // this comment is from i386.  we don't save silly state early either
+       // hopefully you don't need to save it now.  let me know if otherwise
+       static_assert(0);
+       /* Note we are not preemptively saving the TF in the env_tf.  We do maintain
+        * a reference to it in current_tf (a per-cpu pointer).
+        * In general, only save the tf and any silly state once you know it
+        * is necessary (blocking).  And only save it in env_tf when you know you
+        * are single core (PROC_RUNNING_S) */
+       set_current_tf(tf);
 
-       state->gpr[8] = syscall(current,state,num,a1,a2,a3,a4,a5);
+       //env_push_ancillary_state(current); // remove this if you don't need it
+
+       state->gpr[8] = syscall(current,num,a1,a2,a3,a4,a5);
 
        trap_handled();
 }
@@ -266,7 +276,9 @@ handle_breakpoint(trapframe_t* state)
        state->pc = state->npc;
        state->npc += 4;
 
-       env_push_ancillary_state(current);
+       // see comment above about tf's
+       static_assert(0);
+       //env_push_ancillary_state(current);
 
        // run the monitor
        monitor(state);
index 996bf03..c00dbaa 100644 (file)
@@ -83,24 +83,10 @@ struct Env {
 };
 
 /* Process Flags */
-// None yet
+#define PROC_TRANSITION_TO_M                   0x0001
 
 extern env_t *CT(NENV) RO envs;                // All environments
 extern atomic_t num_envs;              // Number of envs
-// TODO: consider moving this to struct per_cpu_info
-extern env_t * (RO curenvs)[MAX_NUM_CPUS];
-
-static inline env_t *
-get_cpu_curenv() TRUSTED
-{
-       return curenvs[core_id()];
-}
-
-static inline void
-set_cpu_curenv(env_t *p) TRUSTED
-{
-       curenvs[core_id()] = p;
-}
 
 void   env_init(void);
 int            env_alloc(env_t *SAFE*SAFE e, envid_t parent_id);
@@ -110,13 +96,6 @@ void        env_free(env_t *SAFE e);
 void   env_user_mem_free(env_t* e);
 env_t* env_create(uint8_t *COUNT(size) binary, size_t size);
 
-/*
- * Allows the kernel to figure out what process is running on its core.
- * Can be used just like a pointer to a struct process.
- */
-#define current (get_cpu_curenv())
-//#define current (curenvs[core_id()])
-
 int    envid2env(envid_t envid, env_t **env_store, bool checkperm);
 // The following three functions do not return
 void   env_pop_tf(trapframe_t *tf) __attribute__((noreturn));
index 48bbdbf..06a434a 100644 (file)
@@ -90,16 +90,24 @@ error_t proc_take_cores(struct proc *SAFE p, uint32_t corelist[], size_t *num,
 error_t proc_take_allcores(struct proc *SAFE p, amr_t message, TV(a0t) arg0,
                            TV(a1t) arg1, TV(a2t) arg2);
 
-/* Arch Specific */
-void proc_init_trapframe(trapframe_t *SAFE tf);
-void proc_set_program_counter(trapframe_t *SAFE tf, uintptr_t pc);
-void proc_set_tfcoreid(trapframe_t *SAFE tf, uint32_t id);
-void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value);
-
 /* The reference counts are mostly to track how many cores loaded the cr3 */
 error_t proc_incref(struct proc *SAFE p);
 void proc_decref(struct proc *SAFE p);
 
+/* Allows the kernel to figure out what process is running on this core.  Can be
+ * used just like a pointer to a struct proc.  Need these to be macros due to
+ * some circular dependencies with smp.h. */
+#include <smp.h>
+#define current per_cpu_info[core_id()].cur_proc
+#define set_current_proc(p) per_cpu_info[core_id()].cur_proc = (p)
+
+/* Allows the kernel to figure out what tf is on this core's stack.  Can be used
+ * just like a pointer to a struct Trapframe.  Need these to be macros due to
+ * some circular dependencies with smp.h.  This is done here instead of
+ * elsewhere (like trap.h) for other elliptical reasons. */
+#define current_tf per_cpu_info[core_id()].cur_tf
+#define set_current_tf(tf) per_cpu_info[core_id()].cur_tf = (tf)
+
 void abandon_core(void);
 
 /* Active message handlers for process management */
@@ -115,6 +123,12 @@ void __death(trapframe_t *tf, uint32_t srcid, void * a0, void * a1,
              void * a2);
 #endif
 
+/* Arch Specific */
+void proc_set_program_counter(trapframe_t *SAFE tf, uintptr_t pc);
+void proc_init_trapframe(trapframe_t *SAFE tf);
+void proc_set_tfcoreid(trapframe_t *SAFE tf, uint32_t id);
+void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value);
+
 /* Degubbing */
 void print_idlecoremap(void);
 void print_proc_info(pid_t pid);
index 1114feb..7bceab9 100644 (file)
@@ -16,7 +16,6 @@
 #include <atomic.h>
 #include <process.h>
 #include <workqueue.h>
-#include <env.h>
 
 #ifdef __SHARC__
 typedef sharC_env_t;
@@ -24,6 +23,8 @@ typedef sharC_env_t;
 
 struct per_cpu_info {
        spinlock_t lock;
+       struct proc *cur_proc;
+       trapframe_t *cur_tf;
        bool preempt_pending;
        struct workqueue NTPTV(t) workqueue;
 
@@ -41,7 +42,7 @@ struct per_cpu_info {
 typedef struct per_cpu_info NTPTV(t) NTPTV(a0t) NTPTV(a1t) NTPTV(a2t) per_cpu_info_t;
 
 extern per_cpu_info_t (RO per_cpu_info)[MAX_NUM_CPUS];
-extern volatile uint8_t RO num_cpus;
+extern volatile uint32_t RO num_cpus;
 
 /* SMP bootup functions */
 void smp_boot(void);
index 0c2ac93..bb3151b 100644 (file)
@@ -7,8 +7,8 @@
 #include <ros/syscall.h>
 #include <process.h>
 
-intreg_t syscall(struct proc *p, trapframe_t *tf, uintreg_t num, uintreg_t a1,
-                 uintreg_t a2, uintreg_t a3, uintreg_t a4, uintreg_t a5);
+intreg_t syscall(struct proc *p, uintreg_t num, uintreg_t a1, uintreg_t a2,
+                 uintreg_t a3, uintreg_t a4, uintreg_t a5);
 intreg_t syscall_async(env_t* e, syscall_req_t *syscall);
 intreg_t process_generic_syscalls(env_t* e, size_t max);
 #endif /* !ROS_KERN_SYSCALL_H */
index 6ce9ed1..e679378 100644 (file)
 
 env_t *envs = NULL;            // All environments
 atomic_t num_envs;
-// TODO: make this a struct of info including the pointer and cacheline-align it
-// This lets the kernel know what process is running on the core it traps into.
-// A lot of the Env business, including this and its usage, will change when we
-// redesign the env as a multi-process.
-env_t* (RO curenvs)[MAX_NUM_CPUS] = {[0 ... (MAX_NUM_CPUS-1)] NULL};
 
 #define ENVGENSHIFT    12              // >= LOGNENV
 
index d99fc1c..e00d11e 100644 (file)
@@ -21,6 +21,7 @@
 #include <kfs.h>
 #include <stdio.h>
 #include <timing.h>
+#include <resource.h>
 
 /*
  * Currently, if you leave this function by way of proc_run (process_workqueue
@@ -34,6 +35,7 @@ void manager(void)
        struct proc *envs[256];
        static struct proc *p ;
 
+       // for testing taking cores, check in case 1 for usage
        uint32_t corelist[MAX_NUM_CPUS];
        uint32_t num = 3;
 
@@ -51,8 +53,9 @@ void manager(void)
 
        switch (progress++) {
                case 0:
-                       //p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
-                       p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
+                       //p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
+                       p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
+                       //p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
                        // being proper and all:
                        spin_lock_irqsave(&p->proc_lock);
                        proc_set_state(p, PROC_RUNNABLE_S);
@@ -72,19 +75,28 @@ void manager(void)
                        break;
                case 1:
                        #if 0
-                       panic("This is okay");
                        udelay(10000000);
-                       printk("taking 3 cores from p\n");
-                       for (int i = 0; i < num; i++)
-                               corelist[i] = 7-i; // 7, 6, and 5
-                       spin_lock_irqsave(&p->proc_lock);
-                       proc_take_cores(p, corelist, &num, __death);
-                       spin_unlock_irqsave(&p->proc_lock);
-                       udelay(5000000);
-                       printk("Killing p\n");
-                       proc_destroy(p);
-                       printk("Killed p\n");
-                       udelay(1000000);
+                       // this is a ghetto way to test restarting an _M
+                               printk("\nattempting to ghetto preempt...\n");
+                               spin_lock_irqsave(&p->proc_lock);
+                               proc_take_allcores(p, __death);
+                               proc_set_state(p, PROC_RUNNABLE_M);
+                               spin_unlock_irqsave(&p->proc_lock);
+                               udelay(5000000);
+                               printk("\nattempting to restart...\n");
+                               core_request(p); // proc still wants the cores
+                       panic("This is okay");
+                       // this tests taking some cores, and later killing an _M
+                               printk("taking 3 cores from p\n");
+                               for (int i = 0; i < num; i++)
+                                       corelist[i] = 7-i; // 7, 6, and 5
+                               spin_lock_irqsave(&p->proc_lock);
+                               proc_take_cores(p, corelist, &num, __death);
+                               spin_unlock_irqsave(&p->proc_lock);
+                               udelay(5000000);
+                               printk("Killing p\n");
+                               proc_destroy(p);
+                               printk("Killed p\n");
                        panic("This is okay");
 
                        envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
index e481fcc..b9e5b19 100644 (file)
@@ -33,6 +33,16 @@ spinlock_t idle_lock = SPINLOCK_INITIALIZER;
 uint32_t LCKD(&idle_lock) (RO idlecoremap)[MAX_NUM_CPUS];
 uint32_t LCKD(&idle_lock) num_idlecores = 0;
 
+/* Helper function to return a core to the idlemap.  It causes some more lock
+ * acquisitions (like in a for loop), but it's a little easier.  Plus, one day
+ * we might be able to do this without locks (for the putting). */
+static void put_idle_core(uint32_t coreid)
+{
+       spin_lock(&idle_lock);
+       idlecoremap[num_idlecores++] = coreid;
+       spin_unlock(&idle_lock);
+}
+
 /*
  * While this could be done with just an assignment, this gives us the
  * opportunity to check for bad transitions.  Might compile these out later, so
@@ -58,7 +68,7 @@ int proc_set_state(struct proc *p, uint32_t state)
         * RBS -> D
         * RBM -> D
         *
-        * This isn't allowed yet, may be later.
+        * This isn't allowed yet, should be later.  Is definitely causable.
         * C   -> D
         */
        #if 1 // some sort of correctness flag
@@ -154,18 +164,22 @@ void proc_run(struct proc *p)
                         * this process.  It is set outside proc_run.  For the active
                         * message, a0 = struct proc*, a1 = struct trapframe*.   */
                        if (p->num_vcores) {
+                               int i = 0;
                                // TODO: handle silly state (HSS)
-                               // set virtual core 0 to run the main context
-                               // TODO: this should only happen on transition (VC0)
+                               // set virtual core 0 to run the main context on transition
+                               if (p->env_flags & PROC_TRANSITION_TO_M) {
+                                       p->env_flags &= !PROC_TRANSITION_TO_M;
 #ifdef __IVY__
-                               send_active_message(p->vcoremap[0], __startcore, p,
-                                                   &p->env_tf, (void *SNT)0);
+                                       send_active_message(p->vcoremap[0], __startcore, p,
+                                                           &p->env_tf, (void *SNT)0);
 #else
-                               send_active_message(p->vcoremap[0], (void *)__startcore,
-                                                   (void *)p, (void *)&p->env_tf, 0);
+                                       send_active_message(p->vcoremap[0], (void *)__startcore,
+                                                           (void *)p, (void *)&p->env_tf, 0);
 #endif
+                                       i = 1; // start at vcore1 in the loop below
+                               }
                                /* handle the others. */
-                               for (int i = 1; i < p->num_vcores; i++)
+                               for (/* i set above */; i < p->num_vcores; i++)
 #ifdef __IVY__
                                        send_active_message(p->vcoremap[i], __startcore,
                                                            p, (trapframe_t *CT(1))NULL, (void *SNT)i);
@@ -231,7 +245,6 @@ void proc_startcore(struct proc *p, trapframe_t *tf) {
        // it's possible to be DYING, but it's a rare race.
        //if (p->state & (PROC_RUNNING_S | PROC_RUNNING_M))
        //      printk("dying before (re)startcore on core %d\n", core_id());
-
        // sucks to have ints disabled when doing env_decref and possibly freeing
        disable_irq();
        if (per_cpu_info[core_id()].preempt_pending) {
@@ -255,7 +268,7 @@ void proc_startcore(struct proc *p, trapframe_t *tf) {
                // process's context".  abandon_core() does this.
                if (current)
                        proc_decref(current);
-               set_cpu_curenv(p);
+               set_current_proc(p);
        }
        /* need to load our silly state, preferably somewhere other than here so we
         * can avoid the case where the context was just running here.  it's not
@@ -344,9 +357,7 @@ void proc_destroy(struct proc *p)
                        #if 0
                        /* right now, RUNNING_S only runs on a mgmt core (0), not cores
                         * managed by the idlecoremap.  so don't do this yet. */
-                       spin_lock(&idle_lock);
-                       idlecoremap[num_idlecores++] = p->vcoremap[0];
-                       spin_unlock(&idle_lock);
+                       put_idle_core(p->vcoremap[0]);
                        #endif
                        break;
                case PROC_RUNNING_M:
@@ -434,18 +445,19 @@ static uint32_t get_vcoreid(struct proc *SAFE p, int32_t pcoreid)
  * - If RUNNING_S, you just give up your time slice and will eventually return.
  * - If RUNNING_M, you give up the current vcore (which never returns), and
  *   adjust the amount of cores wanted/granted.
- * - If you have only one vcore, you switch to RUNNABLE_S.
- * - If you yield from vcore0 but are still RUNNING_M, your context will be
- *   saved, but may not be restarted, depending on how you get that core back.
- *   (currently)  see proc_give_cores for details.
+ * - If you have only one vcore, you switch to RUNNABLE_M.  When you run again,
+ *   you'll have one guaranteed core, starting from the entry point.
+ *
  * - RES_CORES amt_wanted will be the amount running after taking away the
- *   yielder.
+ *   yielder, unless there are none left, in which case it will be 1.
  */
 void proc_yield(struct proc *SAFE p)
 {
        spin_lock_irqsave(&p->proc_lock);
        switch (p->state) {
                case (PROC_RUNNING_S):
+                       p->env_tf= *current_tf;
+                       env_push_ancillary_state(p);
                        proc_set_state(p, PROC_RUNNABLE_S);
                        schedule_proc(p);
                        break;
@@ -455,19 +467,18 @@ void proc_yield(struct proc *SAFE p)
                        // give up core
                        p->vcoremap[get_vcoreid(p, core_id())] = -1;
                        // add to idle list
-                       spin_lock(&idle_lock);
-                       idlecoremap[num_idlecores++] = core_id();
-                       spin_unlock(&idle_lock);
-                       // out of vcores?  if so, we're now a regular process
+                       put_idle_core(core_id());
+                       // last vcore?  then we really want 1, and to yield the gang
                        if (p->num_vcores == 0) {
-                               // switch to runnable_s
-                               proc_set_state(p, PROC_RUNNABLE_S);
+                               // might replace this with m_yield, if we have it directly
+                               p->resources[RES_CORES].amt_wanted = 1;
+                               proc_set_state(p, PROC_RUNNABLE_M);
                                schedule_proc(p);
                        }
                        break;
                default:
                        // there are races that can lead to this (async death, preempt, etc)
-                       panic("Weird state(0x%08x) in sys_yield", p->state);
+                       panic("Weird state(0x%08x) in proc_yield", p->state);
        }
        spin_unlock_irqsave(&p->proc_lock);
        // clean up the core and idle.  for mgmt cores, they will ultimately call
@@ -542,14 +553,6 @@ error_t proc_give_cores(struct proc *SAFE p, uint32_t corelist[], size_t *num)
                                p->vcoremap[free_vcoreid] = corelist[i];
                                p->num_vcores++;
                                assert(corelist[i] != core_id()); // sanity
-                               /* if we want to allow yielding of vcore0 and restarting it at
-                                * its yield point *while still RUNNING_M*, uncomment this */
-                               // TODO: we don't (VC0)
-                               /*
-                               if (i == 0)
-                                       send_active_message(p->vcoremap[0], __startcore,
-                                                           (uint32_t)p, (uint32_t)&p->env_tf, 0);
-                               else */
                                send_active_message(corelist[i], __startcore, p,
                                                     (struct Trapframe *)0,
                                                     (void*SNT)free_vcoreid);
@@ -583,8 +586,6 @@ error_t proc_set_allcores(struct proc *SAFE p, uint32_t corelist[], size_t *num,
  * contain how many items are in corelist.  This isn't implemented yet, but
  * might be necessary later.  Or not, and we'll never do it.
  *
- * TODO: think about taking vcore0.  probably are issues... (or not (VC0))
- *
  * WARNING: You must hold the proc_lock before calling this!*/
 error_t proc_take_cores(struct proc *SAFE p, uint32_t corelist[], size_t *num,
                         amr_t message, TV(a0t) arg0, TV(a1t) arg1, TV(a2t) arg2)
@@ -602,17 +603,18 @@ error_t proc_take_cores(struct proc *SAFE p, uint32_t corelist[], size_t *num,
        }
        spin_lock(&idle_lock);
        assert((*num <= p->num_vcores) && (num_idlecores + *num <= num_cpus));
+       spin_unlock(&idle_lock);
        for (int i = 0; i < *num; i++) {
                vcoreid = get_vcoreid(p, corelist[i]);
                assert(p->vcoremap[vcoreid] == corelist[i]);
                if (message)
                        send_active_message(corelist[i], message, arg0, arg1, arg2);
                // give the pcore back to the idlecoremap
-               idlecoremap[num_idlecores++] = corelist[i];
+               put_idle_core(corelist[i]);
                p->vcoremap[vcoreid] = -1;
        }
-       spin_unlock(&idle_lock);
        p->num_vcores -= *num;
+       p->resources[RES_CORES].amt_granted -= *num;
        return 0;
 }
 
@@ -637,6 +639,7 @@ error_t proc_take_allcores(struct proc *SAFE p, amr_t message,
        }
        spin_lock(&idle_lock);
        assert(num_idlecores + p->num_vcores <= num_cpus); // sanity
+       spin_unlock(&idle_lock);
        for (int i = 0; i < p->num_vcores; i++) {
                // find next active vcore
                active_vcoreid = get_busy_vcoreid(p, active_vcoreid);
@@ -644,11 +647,11 @@ error_t proc_take_allcores(struct proc *SAFE p, amr_t message,
                        send_active_message(p->vcoremap[active_vcoreid], message,
                                             arg0, arg1, arg2);
                // give the pcore back to the idlecoremap
-               idlecoremap[num_idlecores++] = p->vcoremap[active_vcoreid];
+               put_idle_core(p->vcoremap[active_vcoreid]);
                p->vcoremap[active_vcoreid] = -1;
        }
-       spin_unlock(&idle_lock);
        p->num_vcores = 0;
+       p->resources[RES_CORES].amt_granted = 0;
        return 0;
 }
 
@@ -753,10 +756,11 @@ void abandon_core(void)
        if (current) {
                lcr3(boot_cr3);
                proc_decref(current);
-               set_cpu_curenv(NULL);
+               set_current_proc(NULL);
        }
        smp_idle();
 }
+
 /* Active message handler to clean up the core when a process is dying.
  * Note this leaves no trace of what was running.
  * It's okay if death comes to a core that's already idling and has no current.
index 29238cd..d090ecc 100644 (file)
@@ -14,6 +14,7 @@
 #include <process.h>
 #include <stdio.h>
 #include <assert.h>
+#include <schedule.h>
 
 /* This deals with a request for more cores.  The request is already stored in
  * the proc's amt_wanted (it is compared to amt_granted). 
@@ -23,7 +24,9 @@
  * such as if there was not a new request, but it's time to look at the
  * difference between amt_wanted and amt_granted (maybe on a timer interrupt).
  *
- * Will return either the number actually granted or an error code.
+ * Will return either the number actually granted or an error code.  This will
+ * not decrease the actual amount of cores (e.g. from 5 to 2), but it will
+ * transition a process from _M to _S (amt_wanted == 0).
  */
 ssize_t core_request(struct proc *p)
 {
@@ -33,6 +36,20 @@ ssize_t core_request(struct proc *p)
        bool need_to_idle = FALSE;
 
        spin_lock_irqsave(&p->proc_lock);
+       /* check to see if this is a full deallocation.  for cores, it's a
+        * transition from _M to _S */
+       if (!p->resources[RES_CORES].amt_wanted) {
+               assert(p->state == PROC_RUNNING_M);
+               // save the context, to be restarted in _S mode
+               p->env_tf = *current_tf;
+               env_push_ancillary_state(p);
+               proc_set_syscall_retval(&p->env_tf, ESUCCESS);
+               // in this case, it's not our job to save contexts or anything
+               proc_take_allcores(p, __death, 0, 0, 0);
+               proc_set_state(p, PROC_RUNNABLE_S);
+               schedule_proc(p);
+       }
+       /* otherwise, see how many new cores are wanted */
        amt_new = p->resources[RES_CORES].amt_wanted -
                  p->resources[RES_CORES].amt_granted;
        if (amt_new < 0) {
@@ -71,8 +88,16 @@ ssize_t core_request(struct proc *p)
                                // either of these should trip it.
                                if ((current != p) || (p->vcoremap[0] != core_id()))
                                        panic("We don't handle async RUNNING_S core requests yet.");
-                               /* in the async case, we'll need to bundle vcore0's TF.  this is
-                                * already done for the sync case (local syscall). */
+                               /* save the tf to be restarted on another core (in proc_run) */
+                               p->env_tf = *current_tf;
+                               env_push_ancillary_state(p);
+                               /* set the return code to 0. since we're transitioning, vcore0
+                                * will start up with the tf manually, and not get the return
+                                * value through the regular syscall return path */
+                               proc_set_syscall_retval(&p->env_tf, ESUCCESS);
+                               /* in the async case, we'll need to remotely stop and bundle
+                                * vcore0's TF.  this is already done for the sync case (local
+                                * syscall). */
                                /* this process no longer runs on its old location (which is
                                 * this core, for now, since we don't handle async calls) */
                                p->vcoremap[0] = -1;
@@ -80,6 +105,8 @@ ssize_t core_request(struct proc *p)
                                need_to_idle = TRUE;
                                // change to runnable_m (it's TF is already saved)
                                proc_set_state(p, PROC_RUNNABLE_M);
+                               // signals to proc_run that this is a _S to _M transition
+                               p->env_flags |= PROC_TRANSITION_TO_M;
                                break;
                        case (PROC_RUNNABLE_S):
                                /* Issues: being on the runnable_list, proc_set_state not liking
index 7ab2d9e..e80806d 100644 (file)
@@ -20,8 +20,8 @@
 
 // This could be useful for making scheduling decisions.  
 /* Physical coremap: each index is a physical core id, with a proc ptr for
- * whoever *should be or is* running.  Very similar to current / curenvs[],
- * which is what process is *really* running there. */
+ * whoever *should be or is* running.  Very similar to current, which is what
+ * process is *really* running there. */
 struct proc *pcoremap[MAX_NUM_CPUS];
 
 void schedule_init(void)
index 8f0b38e..10c3c0f 100644 (file)
@@ -94,7 +94,6 @@ static ssize_t sys_run_binary(env_t* e, void *DANGEROUS binary_buf,
        kfree(new_binary);
        proc_set_state(env, PROC_RUNNABLE_S);
        schedule_proc(env);
-       proc_yield(e); // changed from sys_yield.  did not test this at all.
        return 0;
 }
 
@@ -418,9 +417,8 @@ static error_t sys_proc_run(struct proc *p, unsigned pid)
  * TODO: Build a dispatch table instead of switching on the syscallno
  * Dispatches to the correct kernel function, passing the arguments.
  */
-intreg_t syscall(struct proc *p, trapframe_t *tf, uintreg_t syscallno,
-                 uintreg_t a1, uintreg_t a2, uintreg_t a3, uintreg_t a4,
-                                uintreg_t a5)
+intreg_t syscall(struct proc *p, uintreg_t syscallno, uintreg_t a1,
+                 uintreg_t a2, uintreg_t a3, uintreg_t a4, uintreg_t a5)
 {
        // Call the function corresponding to the 'syscallno' parameter.
        // Return any appropriate return value.
@@ -483,11 +481,6 @@ intreg_t syscall(struct proc *p, trapframe_t *tf, uintreg_t syscallno,
                        printk("brk not implemented yet\n");
                        return -EINVAL;
                case SYS_resource_req:
-                       /* preemptively set the return code to 0.  if it's not, it will get
-                        * overwriten on a proper return path.  if it ends up being a core
-                        * request from a RUNNING_S, it will never return out this way
-                        */
-                       proc_set_syscall_retval(tf, ESUCCESS);
                        return resource_req(p, a1, a2, a3);
 
        #ifdef __i386__
@@ -519,7 +512,7 @@ intreg_t syscall(struct proc *p, trapframe_t *tf, uintreg_t syscallno,
 
 intreg_t syscall_async(env_t* e, syscall_req_t *call)
 {
-       return syscall(e, NULL, call->num, call->args[0], call->args[1],
+       return syscall(e, call->num, call->args[0], call->args[1],
                       call->args[2], call->args[3], call->args[4]);
 }
 
index ac7581a..1afae72 100644 (file)
@@ -25,12 +25,12 @@ int main(int argc, char** argv)
        uint32_t vcoreid;
        error_t retval;
 
-       static int first_time = 1; // used by vcore2
+       prepare_for_multi_mode();
 
        if ((vcoreid = newcore())) {
-               cprintf("Hello from vcore %d\n", vcoreid);
+               cprintf("Should never see me! (from vcore %d)\n", vcoreid);
        } else { // core 0
-               cprintf("Hello from else vcore 0\n");
+               cprintf("Hello from vcore 0\n");
                cprintf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
                retval = sys_resource_req(RES_CORES, 7, 0);
        }
@@ -38,3 +38,10 @@ int main(int argc, char** argv)
        while (1);
        return 0;
 }
+
+void hart_entry(void)
+{
+       uint32_t vcoreid;
+       vcoreid = newcore();
+       cprintf("Hello from hart_entry in vcore %d\n", vcoreid);
+}
index b99d7e9..8a0936d 100644 (file)
@@ -20,27 +20,29 @@ void udelay(uint64_t usec, uint64_t tsc_freq)
        return;
 }
 
-#define TEST_MMAP                                      1
-#define TEST_ONE_CORE                          2
-#define TEST_ASK_FOR_TOO_MANY_CORES    3
-#define TEST_INCREMENTAL_CHANGES       4
-#define TEST_YIELD_OUT_OF_ORDER                5
-#define TEST_YIELD_0_OUT_OF_ORDER      6
-#define TEST_SWITCH_TO_RUNNABLE_S      7
-#define TEST_CRAZY_YIELDS                      8
-#define TEST_CONCURRENT_SYSCALLS       9
+#define TEST_MMAP                                       1
+#define TEST_ONE_CORE                           2
+#define TEST_ASK_FOR_TOO_MANY_CORES     3
+#define TEST_INCREMENTAL_CHANGES        4
+#define TEST_YIELD_OUT_OF_ORDER                 5
+#define TEST_YIELD_0_OUT_OF_ORDER       6
+#define TEST_YIELD_ALL               7
+#define TEST_SWITCH_TO_RUNNABLE_S       8
+#define TEST_CRAZY_YIELDS                       9
+#define TEST_CONCURRENT_SYSCALLS       10
+
+int test = TEST_SWITCH_TO_RUNNABLE_S;
+
+static void global_tests(uint32_t vcoreid);
 
 int main(int argc, char** argv)
 {
        uint32_t vcoreid;
        error_t retval;
-
-       int test = TEST_INCREMENTAL_CHANGES;
-
-       static int first_time = 1; // used by vcore2
+       prepare_for_multi_mode();
 
        if ((vcoreid = newcore())) {
-               cprintf("Hello from vcore %d\n", vcoreid);
+               cprintf("Should never see me! (from vcore %d)\n", vcoreid);
        } else { // core 0
                cprintf("Hello from else vcore 0\n");
                cprintf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
@@ -81,6 +83,36 @@ int main(int argc, char** argv)
                cprintf("Should see me if you want to relocate core0's context "
                        "when moving from RUNNING_S\n");
        }
+
+       // vcore0 only below here
+       switch (test) {
+               case TEST_YIELD_OUT_OF_ORDER:
+                       udelay(10000000, 1995014570);
+                       cprintf("Core 2 should have yielded, asking for another\n");
+                       retval = sys_resource_req(RES_CORES, 7, 0);
+                       break;
+               case TEST_YIELD_0_OUT_OF_ORDER:
+                       udelay(5000000, 1995014570);
+                       cprintf("Core %d yielding\n", vcoreid);
+                       yield();
+                       cprintf("Core 0 came back where it left off in RUNNING_M!!!\n");
+                       break;
+       }
+       global_tests(vcoreid);
+       cprintf("Vcore %d Done!\n", vcoreid);
+       while (1);
+       return 0;
+}
+
+void hart_entry(void)
+{
+       uint32_t vcoreid;
+       static int first_time = 1; // used by vcore2
+       error_t retval;
+
+       vcoreid = newcore();
+       cprintf("Hello from hart_entry in vcore %d\n", vcoreid);
+
        if ((vcoreid == 2) && first_time) {
                first_time = 0;
                switch (test) {
@@ -101,37 +133,33 @@ int main(int argc, char** argv)
                                yield();
                                break;
                        case TEST_YIELD_0_OUT_OF_ORDER:
-                               udelay(5000000, 1995014570);
+                               udelay(7500000, 1995014570);
                                cprintf("Core 0 should have yielded, asking for another\n");
                                retval = sys_resource_req(RES_CORES, 7, 0);
                }
        }
-       if (vcoreid == 0) {
-               switch (test) {
-                       case TEST_YIELD_OUT_OF_ORDER:
-                               udelay(10000000, 1995014570);
-                               cprintf("Core 2 should have yielded, asking for another\n");
-                               retval = sys_resource_req(RES_CORES, 7, 0);
-                               break;
-                       case TEST_YIELD_0_OUT_OF_ORDER:
-                               udelay(5000000, 1995014570);
-                               cprintf("Core %d yielding\n", vcoreid);
-                               yield();
-                               cprintf("Core 0 came back where it left off in RUNNING_M!!!\n");
-                               break;
-               }
-       }
-       /* This assumes the "core0 is the one who gets saved" style */
+       global_tests(vcoreid);
+       cprintf("Vcore %d Done!\n", vcoreid);
+}
+
+static void global_tests(uint32_t vcoreid)
+{
+       error_t retval;
        switch (test) {
+               case TEST_YIELD_ALL:
+                       cprintf("Core %d yielding\n", vcoreid);
+                       yield();
+                       // should be RUNNABLE_M now, amt_wanted == 1
+                       while(1);
                case TEST_SWITCH_TO_RUNNABLE_S:
-                       if (vcoreid) {
-                               yield();
-                       } else {
-                               udelay(5000000, 1995014570);
-                               cprintf("Core %d yielding\n", vcoreid);
-                               yield();
-                               cprintf("Should see me if you are ever scheduled again.\n");
-                       }
+                       if (vcoreid == 2) {
+                               cprintf("Core %d trying to request 0/ switch to _S\n", vcoreid);
+                               retval = sys_resource_req(RES_CORES, 0, 0);
+                               // will only see this if we are scheduled()
+                               cprintf("Core %d back up! (retval:%d)\n", vcoreid, retval);
+                               cprintf("And exiting\n");
+                               exit();
+                       } 
                        while(1);
                case TEST_CRAZY_YIELDS:
                        udelay(300000*vcoreid, 1995014570);
@@ -147,7 +175,4 @@ int main(int argc, char** argv)
                        }
                        break;
        }
-       cprintf("Vcore %d Done!\n", vcoreid);
-       while (1);
-       return 0;
 }
index 6bf33ca..3cc2d3f 100644 (file)
@@ -117,6 +117,7 @@ error_t get_all_desc(async_desc_t** a_desc, syscall_desc_t** s_desc);
 // kernel's arch folder
 uint32_t newcore(void);
 void setvcore0(void);
+void prepare_for_multi_mode(void);
 
 /* File open modes */
 #define        O_RDONLY        0x0000          /* open for reading only */
index 7adcac1..0ae8544 100644 (file)
@@ -32,6 +32,10 @@ _start:
        cmpl $0, %eax
        jne new_core
 
+       // See if we should start up normally, or act like a new core
+       cmpl $0, in_multi_mode
+       jne new_core
+
        // See if we were started with arguments on the stack
        cmpl $USTACKTOP, %esp
        jne args_exist
@@ -72,7 +76,7 @@ new_core:
        addl $PGSIZE, %edx
        movl %edx, %esp
        movl %esi, %eax // restore the vcoreid
-       call main // main will check to see if it came from here or not
+       call hart_entry
        // spin when we return.  ought to yield before this ever happens
 2:             jmp 2b
 
@@ -81,3 +85,6 @@ mmap_args:
        .long MAP_ANONYMOUS|MAP_FIXED|MAP_STACK|MAP_POPULATE|MAP_GROWSDOWN // arg4
        .long 0              // arg5
        .long 0              // arg6
+.globl in_multi_mode
+in_multi_mode:
+       .long 0              // flag for vcore0 to know to act like other cores
index 9df8b6a..62ca5ed 100644 (file)
@@ -45,3 +45,21 @@ void libmain(int argc, char * NTS * NT COUNT(argc) argv)
        // exit gracefully
        exit();
 }
+
+#pragma weak hart_entry
+void hart_entry()
+{
+       cprintf("Need to implement a hart entry!\n");
+}
+
+/* At the very least, we need to set this flag so that vcore0 can come up at the
+ * hart_entry, like everyone else.  When this is set, it will come up at the
+ * regular entry point (_start:) and jump to newcore:.  
+ *
+ * This function would be a decent place to mmap all the stacks in, which would
+ * simplify the logic of newcore. */
+void prepare_for_multi_mode(void)
+{
+       extern char (SAFE in_multi_mode)[];
+       *in_multi_mode = 1;
+}