libsys: allow for grant preallocation
Since the grant table is allocated dynamically, a system service always runs the risk of running out of memory at run time when trying to allocate a grant. In order to allow services to mitigate that risk, grants can now be preallocated, typically at system service startup, using the new cpf_prealloc(3) libsys function. The function takes a 'count' parameter that indicates the number of additional grants to preallocate. Thus, the function may be called from multiple submodules within a service, each preallocating their own maximum of grants that it may need at run time. Change-Id: I6904726a722a8c27dfe2efa470e683718f310272
This commit is contained in:
parent
5d5fbe79c1
commit
5edbea5063
@ -78,9 +78,13 @@ struct vscp_vec {
|
||||
#define GRANT_FAULTED 1 /* CPF_TRY: a soft fault occurred */
|
||||
|
||||
/* Prototypes for functions in libsys. */
|
||||
cp_grant_id_t cpf_grant_direct(endpoint_t, vir_bytes, size_t, int);
|
||||
cp_grant_id_t cpf_grant_indirect(endpoint_t, endpoint_t, cp_grant_id_t);
|
||||
cp_grant_id_t cpf_grant_magic(endpoint_t, endpoint_t, vir_bytes, size_t, int);
|
||||
void cpf_prealloc(unsigned int count);
|
||||
cp_grant_id_t cpf_grant_direct(endpoint_t who_to, vir_bytes addr, size_t bytes,
|
||||
int access);
|
||||
cp_grant_id_t cpf_grant_indirect(endpoint_t who_to, endpoint_t who_from,
|
||||
cp_grant_id_t gr);
|
||||
cp_grant_id_t cpf_grant_magic(endpoint_t who_to, endpoint_t who_from,
|
||||
vir_bytes addr, size_t bytes, int access);
|
||||
int cpf_revoke(cp_grant_id_t grant_id);
|
||||
|
||||
/* START OF DEPRECATED API */
|
||||
|
@ -44,23 +44,35 @@ static cp_grant_t *grants = NULL;
|
||||
static int ngrants = 0;
|
||||
static int freelist = -1;
|
||||
|
||||
static void
|
||||
cpf_grow(void)
|
||||
/*
|
||||
* Preallocate more grants that will be free for subsequent use. If a specific
|
||||
* number of grants is given (i.e., count > 0), the total number of grants will
|
||||
* be increased by that amount. If no number of grants is given (count == 0),
|
||||
* double(ish) the size of the table. The latter is used internally. This
|
||||
* function may fail, either because the maximum number of slots is reached or
|
||||
* because no new memory can be allocated. In that case, nothing will change;
|
||||
* the caller must check afterward whether there are newly available grants.
|
||||
*/
|
||||
void
|
||||
cpf_prealloc(unsigned int count)
|
||||
{
|
||||
/* Grow the grants table if possible. */
|
||||
cp_grant_t *new_grants;
|
||||
int g, new_size;
|
||||
|
||||
if(!ngrants) {
|
||||
if (!ngrants && count <= NR_STATIC_GRANTS) {
|
||||
/* Use statically allocated grants the first time. */
|
||||
new_size = NR_STATIC_GRANTS;
|
||||
new_grants = static_grants;
|
||||
}
|
||||
else {
|
||||
/* Double(ish) the size, up to the maximum number of slots. */
|
||||
if (ngrants >= GRANT_MAX_IDX)
|
||||
return;
|
||||
new_size = (1+ngrants)*2;
|
||||
if (count != 0) {
|
||||
if (count > (unsigned)(GRANT_MAX_IDX - ngrants))
|
||||
count = (unsigned)(GRANT_MAX_IDX - ngrants);
|
||||
new_size = ngrants + (int)count;
|
||||
} else
|
||||
new_size = (1+ngrants)*2;
|
||||
if (new_size >= GRANT_MAX_IDX)
|
||||
new_size = GRANT_MAX_IDX;
|
||||
assert(new_size > ngrants);
|
||||
@ -116,7 +128,7 @@ cpf_new_grantslot(void)
|
||||
/* Obtain a free slot. */
|
||||
if ((g = freelist) == -1) {
|
||||
/* Table full - try to make the table larger. */
|
||||
cpf_grow();
|
||||
cpf_prealloc(0);
|
||||
if ((g = freelist) == -1) {
|
||||
/* ngrants hasn't increased. */
|
||||
errno = ENOSPC;
|
||||
|
Loading…
x
Reference in New Issue
Block a user