Commit f49008eb authored by Charlie Jacobsen's avatar Charlie Jacobsen

reorganize: Cleans up doc in libcap.h. Moves cptr init/fini into internals.

It's probably better to combine cap and cptr init/fini for now,
so there aren't tons of init/fini functions to keep track of on the
user's part. (Maybe we'll find a use case where we want them separate.)
parent 6d4d95b6
......@@ -30,20 +30,40 @@ static unsigned long long cspace_id = 0;
int cap_init(void)
{
int ret;
/*
* Initialize cptr cache subsystem
*/
ret = __cptr_init();
if (ret) {
CAP_ERR("failed to initialize cptr cache subsystem");
goto fail1;
}
/*
* Initialize cdt cache
*/
cdt_cache.cdt_root_cache = cap_cache_create(cdt_root_node);
if (!cdt_cache.cdt_root_cache) {
CAP_ERR("failed to initialize cdt_root_node allocator");
return -ENOMEM;
return -1;
ret = -ENOMEM;
goto fail2;
}
/*
* Initialize locks
*/
cap_mutex_init(&cdt_cache.lock);
cap_mutex_init(&global_lock);
/*
* Zero out types
*/
memset(cap_types, 0, sizeof(cap_types));
return 0;
fail2:
__cptr_fini();
fail1:
return ret;
}
void cap_fini(void)
......@@ -59,6 +79,10 @@ void cap_fini(void)
for (i = CAP_TYPE_FIRST_NONBUILTIN; i < CAP_TYPE_MAX; ++i)
if (cap_types[i].name)
free(cap_types[i].name);
/*
* Tear down cptr cache subsystem
*/
__cptr_fini();
}
cap_type_t cap_register_type(cap_type_t type, const struct cap_type_ops *ops)
......
......@@ -149,14 +149,6 @@ static inline int cptr_is_null(cptr_t c)
/* CPTR CACHEs -------------------------------------------------- */
/**
* cptr_init -- Initalize the cptr cache subsystem
*/
int cptr_init(void);
/**
* cptr_fini -- Tear down the cptr cache subsystem.
*/
void cptr_fini(void);
/**
* cptr_cache_alloc -- Allocate a cptr cache data structure (not initialized)
* @out: out param, pointer to newly alloc'd cache
......@@ -208,16 +200,18 @@ void cptr_free(struct cptr_cache *cptr_cache, cptr_t c);
/* CSPACES -------------------------------------------------- */
/**
* Initializes caches, etc. in capability subsystem. Called when microkernel
* intializes.
* cap_init -- Initializes caches, etc. in capability subsystem.
*
* IMPORTANT: You should call this before any other functions in libcap.
*/
int cap_init(void);
/**
* Tears down caches, etc. in capability subsystem. Called when microkernel
* is exiting.
* cap_fini -- Tears down caches, etc. in capability subsystem.
*
* IMPORTANT (at least for kernel users): You should call this before
* libcap is unloaded.
*/
void cap_fini(void);
/**
* cap_cspace_slots_in_level -- Return total number of slots in cspace at lvl
* @lvl: the level to query
......@@ -234,40 +228,80 @@ static inline int cap_cspace_slots_in_level(int lvl)
out *= CAP_CSPACE_CNODE_TABLE_SIZE/2;
return out;
}
/**
* Register a new capability object type. If you pass type == 0, the
* system will select the next available identifier and return it. You
* should use the returned value as your object identifier. If you
* attempt to use a type that is already in use, this returns
* -EADDRINUSE. If there are no types remaining or you exceed
* CAP_TYPE_MAX, this returns -ENOMEM .
* cap_alloc_cspace -- Allocates a new cspace.
*
* (The struct def is internal for now, so you have to call this function
* to alloc.)
*
* If no memory could be allocated, returns NULL.
*
* Here is the run down on the cspace lifetime and functions:
*
* cap_alloc_cspace -- cspace allocated, not initialized
* cap_init_cspace -- initialize cspace internals
* cap_destroy_cspace -- clears out all of the slots in the cspace,
* destroys some internal caches
* cap_free_cspace -- frees the cspace itself
*/
cap_type_t cap_register_type(cap_type_t type, const struct cap_type_ops *ops);
struct cspace * cap_alloc_cspace(void);
/**
* Allocates a new cspace. If no memory could be allocated, returns NULL.
* cap_init_cspace -- Sets up cspace - initializes lock, root cnode table, etc.
* @cspace: the cspace to initialize
*/
struct cspace * cap_alloc_cspace(void);
int cap_init_cspace(struct cspace *cspace);
/**
* Frees a cspace allocated with `cap_alloc_cspace`.
* cap_destroy_cspace --
* Equivalent to calling lcd_cap_delete on all cnodes in cspace. Frees up
* all cnode tables, etc.
*/
void cap_free_cspace(struct cspace *cspace);
void cap_destroy_cspace(struct cspace *cspace);
/**
* Sets up cspace - initializes lock, root cnode table, etc.
* cap_free_cspace -- Frees a cspace allocated with `cap_alloc_cspace`.
* @cspace: the cspace to free, pointer invalid after this call
*/
int cap_init_cspace(struct cspace *cspace);
void cap_free_cspace(struct cspace *cspace);
/**
* Set the "owner" field of the given cspace
* cap_cspace_setowner -- Set the "owner" field of the given cspace
*
* This can be any object you wish. You will be able to access it
* via cap_cspace_getowner (perhaps it would be convenient for you
* to do so in one of the cap type ops, provide some kind of
* context for the cspace).
*/
void cap_cspace_setowner(struct cspace *cspace, void * owner);
/**
* Get the "owner" field of the given cspace
* cap_cspace_getowner -- Get the "owner" field of the given cspace
*/
void* cap_cspace_getowner(struct cspace *cspace);
/**
* Inserts object data into cspace at cnode pointed at by c.
* cap_register_type -- Register a new capability object type
* @type: integer type index / identifier
* @ops: the cap_type_ops to associate with this type
*
* If you pass type == 0, the system will select the next available
* identifier and return it. You should use the returned value as your
* object identifier. If you attempt to use a type that is already in use,
* this returns -EADDRINUSE. If there are no types remaining or you exceed
* CAP_TYPE_MAX, this returns -ENOMEM.
*
* The built-in types are in libcap_platform.h in the definition of
* cap_type_t.
*/
cap_type_t cap_register_type(cap_type_t type, const struct cap_type_ops *ops);
/**
* cap_insert -- Inserts object data into cspace at cnode pointed at by c
* @cspace: the cspace to insert the object into
* @c: the cptr that identifies which slot to insert the object into
* @object: the object to insert
* @type: the type to associate with @object
*
* You must register @type via cap_register_type before using it.
*
* The lifetime of @object must be at least as long as @object is
* in the cspace (it's up to you, the libcap user, to ensure that).
*
* If the slot is already occupied, or @c is invalid, returns non-zero.
*/
int cap_insert(struct cspace *cspace, cptr_t c, void *object, cap_type_t type);
/**
......@@ -320,41 +354,34 @@ int cap_grant(struct cspace *cspacesrc, cptr_t c_src,
*/
int cap_revoke(struct cspace *cspace, cptr_t c);
/**
* Equivalent to calling lcd_cap_delete on all cnodes in cspace. Frees up
* all cnode tables, etc.
*/
void cap_destroy_cspace(struct cspace *cspace);
/**
* Looks up cnode at cap in cspace.
* cap_cnode_get -- Return the cnode that this cptr points to in cspace
* @cspace: the cspace to look in
* @cptr: the index into the cspace radix tree
* @cnode: out param, the cnode/slot that contains the capability
*
* ** Frees the cnode lock itself without relying on user.
* Acquires a lock to the cnode. Returns zero on success.
*
* ** Interrupts and preemption *are not* disabled. **
* (so we can easily get out of deadlocks while debugging)
*/
int cap_cnode_verify(struct cspace *cspace, cptr_t cap);
/**
* Return the cptr that points to this cnode.
*/
cptr_t cap_cnode_cptr(struct cnode *cnode);
/**
* Return the cnode that this cptr points to in the given cspace. Acquires
* a lock to the cnode. Returns zero on success. Make sure to call
* cap_cnode_put after every cap_cnode_get.
* NOTE: Make sure to call cap_cnode_put after every cap_cnode_get.
*
* Since the struct cnode def is private, use the accessor functions
* below to get the object stored (cap_cnode_object), to get the
* cptr that indexes to this cnode (cap_cnode_cptr), and so on.
*/
int cap_cnode_get(struct cspace *cspace, cptr_t cptr, struct cnode **cnode);
/**
* Unlock the cnode. Call this on every cnode you've called
* cap_cnode_get on.
* cap_cnode_put -- Unlock the cnode
*
* Call this on every cnode you've called cap_cnode_get on.
*/
void cap_cnode_put(struct cnode *cnode);
/**
* Get the object stored at this cnode.
* cap_cnode_object -- Get the object stored at this cnode.
*/
void* cap_cnode_object(struct cnode *cnode);
/**
* cap_cnode_cptr -- Return the cptr that points to this cnode
*/
cptr_t cap_cnode_cptr(struct cnode *cnode);
/**
* cap_cnode_metadata -- Get the metadata stored in the cnode
* @cnode: the cnode to get metadata from
......@@ -386,14 +413,21 @@ void* cap_cnode_metadata(struct cnode *cnode);
*/
void cap_cnode_set_metadata(struct cnode *cnode, void *metadata);
/**
* Get the type of this cnode
* cap_cnode_type -- Get the type of this cnode
*/
cap_type_t cap_cnode_type(struct cnode *cnode);
/**
* Get the cspace this cnode is in.
* cap_cnode_cspace -- Get the cspace this cnode is in
*/
struct cspace * cap_cnode_cspace(struct cnode *cnode);
/**
* cap_cnode_verify -- Looks up cnode at cap in cspace.
*
* ** Frees the cnode lock itself without relying on user.
*
* ** Interrupts and preemption *are not* disabled. **
* (so we can easily get out of deadlocks while debugging)
*/
int cap_cnode_verify(struct cspace *cspace, cptr_t cap);
#endif /* __LIBCAP_H__ */
......@@ -434,7 +434,6 @@ int main()
CAP_ERR("libcap init failed");
return ret;
}
cptr_init();
stringobj_type = cap_register_type(stringobj_type, &stringobj_ops);
......@@ -442,7 +441,6 @@ int main()
ret = testcase_grant();
ret = testcase_revoke();
cptr_fini();
cap_fini();
return ret;
......
......@@ -252,11 +252,6 @@ int main()
CAP_ERR("libcap init failed");
goto out;
}
ret = cptr_init();
if (ret < 0) {
CAP_ERR("cptr init failed");
goto cap_exit;
}
stringobj_type = cap_register_type(stringobj_type, &stringobj_ops);
......@@ -265,7 +260,7 @@ int main()
scsp = cap_alloc_cspace();
if (!scsp) {
printf("Source Cspace allocation failed!\n");
goto cptr_exit;
goto cap_exit;
}
ret = cap_init_cspace(scsp);
......@@ -360,8 +355,6 @@ destroy_scspace:
cap_destroy_cspace(scsp);
free_scspace:
cap_free_cspace(scsp);
cptr_exit:
cptr_fini();
cap_exit:
cap_fini();
out:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment