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 */
|
#define GRANT_FAULTED 1 /* CPF_TRY: a soft fault occurred */
|
||||||
|
|
||||||
/* Prototypes for functions in libsys. */
|
/* Prototypes for functions in libsys. */
|
||||||
cp_grant_id_t cpf_grant_direct(endpoint_t, vir_bytes, size_t, int);
|
void cpf_prealloc(unsigned int count);
|
||||||
cp_grant_id_t cpf_grant_indirect(endpoint_t, endpoint_t, cp_grant_id_t);
|
cp_grant_id_t cpf_grant_direct(endpoint_t who_to, vir_bytes addr, size_t bytes,
|
||||||
cp_grant_id_t cpf_grant_magic(endpoint_t, endpoint_t, vir_bytes, size_t, int);
|
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);
|
int cpf_revoke(cp_grant_id_t grant_id);
|
||||||
|
|
||||||
/* START OF DEPRECATED API */
|
/* START OF DEPRECATED API */
|
||||||
|
@ -44,23 +44,35 @@ static cp_grant_t *grants = NULL;
|
|||||||
static int ngrants = 0;
|
static int ngrants = 0;
|
||||||
static int freelist = -1;
|
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;
|
cp_grant_t *new_grants;
|
||||||
int g, new_size;
|
int g, new_size;
|
||||||
|
|
||||||
if(!ngrants) {
|
if (!ngrants && count <= NR_STATIC_GRANTS) {
|
||||||
/* Use statically allocated grants the first time. */
|
/* Use statically allocated grants the first time. */
|
||||||
new_size = NR_STATIC_GRANTS;
|
new_size = NR_STATIC_GRANTS;
|
||||||
new_grants = static_grants;
|
new_grants = static_grants;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Double(ish) the size, up to the maximum number of slots. */
|
|
||||||
if (ngrants >= GRANT_MAX_IDX)
|
if (ngrants >= GRANT_MAX_IDX)
|
||||||
return;
|
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)
|
if (new_size >= GRANT_MAX_IDX)
|
||||||
new_size = GRANT_MAX_IDX;
|
new_size = GRANT_MAX_IDX;
|
||||||
assert(new_size > ngrants);
|
assert(new_size > ngrants);
|
||||||
@ -116,7 +128,7 @@ cpf_new_grantslot(void)
|
|||||||
/* Obtain a free slot. */
|
/* Obtain a free slot. */
|
||||||
if ((g = freelist) == -1) {
|
if ((g = freelist) == -1) {
|
||||||
/* Table full - try to make the table larger. */
|
/* Table full - try to make the table larger. */
|
||||||
cpf_grow();
|
cpf_prealloc(0);
|
||||||
if ((g = freelist) == -1) {
|
if ((g = freelist) == -1) {
|
||||||
/* ngrants hasn't increased. */
|
/* ngrants hasn't increased. */
|
||||||
errno = ENOSPC;
|
errno = ENOSPC;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user