You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

219 lines
7.5 KiB

/*
* Copyright 2011-2016 Formal Methods and Tools, University of Twente
* Copyright 2016-2017 Tom van Dijk, Johannes Kepler University Linz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Do not include this file directly. Instead, include sylvan.h */
#ifndef SYLVAN_COMMON_H
#define SYLVAN_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Initialize the Sylvan parallel decision diagrams package.
*
* First, Sylvan must know how big the nodes table and cache may be.
* Either use sylvan_set_sizes to explicitly set the table sizes, or use sylvan_set_limits
* to let Sylvan compute the sizes for you.
*
* Then, call sylvan_init_package. This allocates the tables and other support structures.
* Sylvan allocates virtual memory to accomodate the maximum sizes of both tables.
* Initially, Sylvan only uses the minimum sizes.
* During garbage collection, table sizes may be doubled until the maximum size is reached.
*
* Then, call initialization functions for the MTBDD/LDD modules like sylvan_init_mtbdd
* and sylvan_init_ldd.
*
* Memory usage:
* Every node requires 24 bytes memory. (16 bytes data + 8 bytes table overhead)
* Every operation cache entry requires 36 bytes memory. (32 bytes data + 4 bytes table overhead)
*/
void sylvan_init_package(void);
/**
* Explicitly set the sizes of the nodes table and the operation cache.
* The sizes are in bytes, but they must be powers of two.
* The minimum size is the size initially used.
* The maximum size is the size allocated in virtual memory.
*/
void sylvan_set_sizes(size_t min_tablesize, size_t max_tablesize, size_t min_cachesize, size_t max_cachesize);
/**
* Implicitly compute and set the sizes of the nodes table and the operation cache.
*
* This function computes max_tablesize and max_cachesize to fit the memory cap.
* The memory cap is in bytes.
*
* The parameter table_ratio controls the ratio between the nodes table and the cache.
* For the value 0, both tables are of the same size.
* For values 1, 2, 3 ... the nodes table will be 2x, 4x, 8x ... as big as the cache
* For values -1, -2, -3 ... the cache will be 2x, 4x, 8x ... as big as the nodes table
*
* The parameter initial_ratio controls how much smaller the initial table sizes are.
* For values of 1, 2, 3, 4 the tables will initially be 2, 4, 8, 16 times smaller.
*/
void sylvan_set_limits(size_t memory_cap, int table_ratio, int initial_ratio);
/**
* Frees all Sylvan data (also calls the quit() functions of BDD/LDD parts)
*/
void sylvan_quit(void);
/**
* Registers a hook callback called during sylvan_quit()
*/
typedef void (*quit_cb)(void);
void sylvan_register_quit(quit_cb cb);
/**
* Return number of occupied buckets in nodes table and total number of buckets.
*/
VOID_TASK_DECL_2(sylvan_table_usage, size_t*, size_t*);
#define sylvan_table_usage(filled, total) (CALL(sylvan_table_usage, filled, total))
/**
* GARBAGE COLLECTION
*
* Garbage collection is performed in a new Lace frame, interrupting all ongoing work
* until garbage collection is completed.
*
* By default, garbage collection is triggered when no new nodes can be added to the nodes table.
* This is detected when there are no more available buckets in the bounded probe sequence.
* Garbage collection can also be triggered manually with sylvan_gc()
*
* Garbage collection procedure:
* 1) All installed pre_gc hooks are called.
* See sylvan_gc_hook_pre to add hooks.
* 2) The operation cache is cleared.
* 3) The nodes table (data part) is cleared.
* 4) All nodes are marked (to be rehashed) using the various marking callbacks.
* See sylvan_gc_add_mark to add marking callbacks.
* Afterwards, the ondead hook is called for all now-dead nodes with the custom flag set.
* 5) The main gc hook is called. The function of this hook is to perform resizing.
* The default implementation doubles the nodes table and operation cache sizes.
* See sylvan_gc_hook_main to set the hook.
* 5) The nodes table (hash part) is cleared.
* 6) All marked nodes are rehashed.
* 7) All installed post_gc hooks are called.
* See sylvan_gc_hook_post to add hooks.
*
* For parts of the garbage collection process, specific methods exist.
* - sylvan_clear_cache() clears the operation cache (step 2)
* - sylvan_clear_and_mark() performs steps 3 and 4.
* - sylvan_rehash_all() performs steps 5 and 6.
*/
/**
* Trigger garbage collection manually.
*/
/**
* Trigger garbage collection manually.
*/
VOID_TASK_DECL_0(sylvan_gc);
#define sylvan_gc() (CALL(sylvan_gc))
/**
* Enable or disable garbage collection.
*
* This affects both automatic and manual garbage collection, i.e.,
* calling sylvan_gc() while garbage collection is disabled does not have any effect.
* If no new nodes can be added, Sylvan will write an error and abort.
*/
void sylvan_gc_enable(void);
void sylvan_gc_disable(void);
/**
* Test if garbage collection must happen now.
* This is just a call to the Lace framework to see if NEWFRAME has been used.
* Before calling this, make sure all used BDDs are referenced.
*/
#define sylvan_gc_test() YIELD_NEWFRAME()
/**
* Clear the operation cache.
*/
VOID_TASK_DECL_0(sylvan_clear_cache);
#define sylvan_clear_cache() CALL(sylvan_clear_cache)
/**
* Clear the nodes table (data part) and mark all nodes with the marking mechanisms.
*/
VOID_TASK_DECL_0(sylvan_clear_and_mark);
#define sylvan_clear_and_mark() CALL(sylvan_clear_and_mark)
/**
* Clear the nodes table (hash part) and rehash all marked nodes.
*/
VOID_TASK_DECL_0(sylvan_rehash_all);
#define sylvan_rehash_all() CALL(sylvan_rehash_all)
/**
* Callback type
*/
LACE_TYPEDEF_CB(void, gc_hook_cb);
/**
* Add a hook that is called before garbage collection begins.
*/
void sylvan_gc_hook_pregc(gc_hook_cb callback);
/**
* Add a hook that is called after garbage collection is finished.
*/
void sylvan_gc_hook_postgc(gc_hook_cb callback);
/**
* Replace the hook called between node marking and rehashing.
* Typically, the hook resizes the hash table and operation cache according to some heuristic.
*/
void sylvan_gc_hook_main(gc_hook_cb callback);
/**
* Add a marking mechanism.
*
* The mark_cb callback is called during garbage collection and should call the
* appropriate recursive marking functions for the decision diagram nodes, for example
* mtbdd_gc_mark_rec() for MTBDDs or lddmc_gc_mark_rec() for LDDs.
*
* The sylvan_count_refs() function uses the count_cb callbacks to compute the number
* of references.
*/
void sylvan_gc_add_mark(gc_hook_cb mark_cb);
/**
* One of the hooks for resizing behavior.
* Default if SYLVAN_AGGRESSIVE_RESIZE is set.
* Always double size on gc() until maximum reached.
* Use sylvan_gc_hook_main() to set this heuristic.
*/
VOID_TASK_DECL_0(sylvan_gc_aggressive_resize);
/**
* One of the hooks for resizing behavior.
* Default if SYLVAN_AGGRESSIVE_RESIZE is not set.
* Double size on gc() whenever >50% is used.
* Use sylvan_gc_hook_main() to set this heuristic.
*/
VOID_TASK_DECL_0(sylvan_gc_normal_resize);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif