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
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
|