aos/include/mdb/mdb_tree.h
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

175 lines
6.1 KiB
C

/*
* Copyright (c) 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
*/
#ifndef LIBMDB_MDB_TREE_H
#define LIBMDB_MDB_TREE_H
#include <sys/cdefs.h>
#include <errors/errno.h>
#include <aos/types.h>
#include <mdb/types.h>
__BEGIN_DECLS
struct capability;
struct cte;
#define mdb_invariants(f) \
/* All checked invariants hold*/\
f(MDB_INVARIANT_OK) \
/* A node with level > 0 must have both children*/\
f(MDB_INVARIANT_BOTHCHILDREN) \
/* The level of a node's left child must be lt the node's level*/\
f(MDB_INVARIANT_LEFT_LEVEL_LESS) \
/* The level of a node's right child must be leq the node's level*/\
f(MDB_INVARIANT_RIGHT_LEVEL_LEQ) \
/* The level of a node's right grandchildren must bt lt the node's level*/\
f(MDB_INVARIANT_RIGHTRIGHT_LEVEL_LESS) \
f(MDB_INVARIANT_RIGHTLEFT_LEVEL_LESS) \
/* The node's "end" value must be the maximum of the subtree's ends*/\
f(MDB_INVARIANT_END_IS_MAX) \
/* The left child of a node must be earlier in the ordering*/\
f(MDB_INVARIANT_LEFT_SMALLER) \
/* The right child of a node must be later in the ordering*/\
f(MDB_INVARIANT_RIGHT_GREATER)
#define f_enum(x) x,
enum mdb_invariant {
mdb_invariants(f_enum)
};
#undef f_enum
#define f_str(x) #x,
static const char *mdb_invariant_str[] = { mdb_invariants(f_str) };
#undef f_str
#undef mdb_invariants
static inline const char *mdb_invariant_to_str(enum mdb_invariant i)
{
return mdb_invariant_str[i];
}
enum {
// No cap was found covering the specified region
MDB_RANGE_NOT_FOUND = 0,
// A cap was found covering at least the entire specified region
MDB_RANGE_FOUND_SURROUNDING = 1,
// A cap was found that is inside the specified region
MDB_RANGE_FOUND_INNER = 2,
// A cap was found that overlaps with one of the specified region's ends
MDB_RANGE_FOUND_PARTIAL = 3,
};
#if IN_KERNEL
// kcb defined else-where
struct kcb;
#else
// create mini kcb that can be used to set root node in user space mdb
struct kcb {
lvaddr_t mdb_root;
};
#endif
// Restore mdb state by passing in the address of the root node
// requires: mdb not initialized
// ensures: mdb_check_invariants() && mdb_is_sane()
errval_t mdb_init(struct kcb *k);
// Print the specified subtree
void mdb_dump(struct cte *cte, int indent);
// Print the complete tree
void mdb_dump_all_the_things(void);
// Check that the invariants hold. The return value indicates the first issue
// that was encountered.
int mdb_check_invariants(void);
// Insert a cap into the tree. An error (MDB_DUPLICATE_ENTRY) is returned iff
// the cap is already present in the tree.
errval_t mdb_insert(struct cte *new_node);
// Remove a cap from the tree. An error (MDB_ENTRY_NOTFOUND) is returned iff
// the cap is not present in the tree.
errval_t mdb_remove(struct cte *node);
struct cte *mdb_predecessor(struct cte *current);
struct cte *mdb_successor(struct cte *current);
// Find a cap in the tree that compares equal to the given cap. Returns NULL if
// no such cap is found.
struct cte *mdb_find_equal(struct capability *cap);
// Find the greatest cap in the tree that is earlier in the ordering. Returns
// NULL if no matching cap is found.
// @param equal_ok If true, will return a copy of the passed cap if it is
// present.
struct cte *mdb_find_less(struct capability *cap, bool equal_ok);
// Find the smallest cap in the tree that is later in the ordering. Returns
// NULL if no matching cap is found.
// @param equal_ok If true, will return a copy of the passed cap if it is
// present.
struct cte *mdb_find_greater(struct capability *cap, bool equal_ok);
// Find a cap in the given range.
// @param root indicates which type tree root to search through (usually
// `get_type_root(ObjType_PhysAddr)`).
// @param max_result Indicates the maximum outcome (not found, surrounding...)
// for which a cap should be returned. If an result is found that is
// greater than max_result, this function returns immediately with the
// given result and NULL cte. The semantics/uses for individual
// max_result values are thus:
// - MDB_RANGE_NOT_FOUND: A simple test whether the given region is
// covered by a cap.
// - MDB_RANGE_FOUND_SURROUNDING: Can be used to check if a region can
// be retyped.
// - MDB_RANGE_FOUND_INNER: Useful for iterating through *immediate*
// descendants.
errval_t mdb_find_range(mdb_root_t root, genpaddr_t address, gensize_t size,
int max_result, struct cte **ret_node, int *result);
errval_t mdb_find_cap_for_address(genpaddr_t address, struct cte **ret_node);
bool mdb_reachable(struct cte *cte);
/**
* Call-back function for tree traversals.
* @param cte The current tree entry.
* @param data User provided data pointer.
*/
typedef errval_t (*mdb_tree_traversal_fn)(struct cte *cte, void *data);
enum mdb_tree_traversal_order {
MDB_TRAVERSAL_ORDER_ASCENDING, ///< Traverse the tree in ascending order
MDB_TRAVERSAL_ORDER_DESCENDING ///< Traverse the tree in descending order
};
/**
* Traverse the mdb tree using some order with a call-back function and
* user-provided data. This function starts at the root of the tree.
* @param order The order to traverse the tree in.
* @param cb The call-back to execute for every node in the tree.
* @parm data User-provided data pointer.
*/
errval_t mdb_traverse(enum mdb_tree_traversal_order order, mdb_tree_traversal_fn cb, void *data);
/**
* Traverse an mdb sub tree using some order with a call-back function and
* user-provided data.
* @param cte The subtree to traverse. The call-back will be executed on this node.
* @param order The order to traverse the tree in.
* @param cb The call-back to execute for every node in the tree.
* @parm data User-provided data pointer.
*/
errval_t mdb_traverse_subtree(struct cte *cte, enum mdb_tree_traversal_order order, mdb_tree_traversal_fn cb, void *data);
errval_t mdb_size(size_t *count);
__END_DECLS
#endif // LIBMDB_MDB_TREE_H