Introduced sUsedPorts/sUsedSems variables that can make it more efficient

to deny further port/sem allocation (and also simplifies port/sem stats).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7570 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-05-13 19:35:49 +00:00
parent 5de1932a25
commit 0b8a2c94ce
2 changed files with 32 additions and 24 deletions

View File

@ -56,6 +56,7 @@ static void _dump_port_info(struct port_entry *port);
// sMaxPorts must be power of 2
static int32 sMaxPorts = 4096;
static int32 sUsedPorts = 0;
#define MAX_QUEUE_LENGTH 4096
#define PORT_MAX_MESSAGE_SIZE 65536
@ -106,6 +107,8 @@ port_init(kernel_args *ka)
#ifdef DEBUG
// ToDo: the test code does not belong here!
// the same code is present in the test_app in kernel/apps
// so I guess we can remove this
/*
* testcode
*/
@ -361,16 +364,7 @@ port_max_ports(void)
int32
port_used_ports(void)
{
int32 count = 0;
int32 i;
// ToDo: we should have a variable that counts the used ports for us
for (i = 0; i < sMaxPorts; i++) {
if (sPorts[i].id >= 0)
count++;
}
return count;
return sUsedPorts;
}
@ -396,6 +390,12 @@ create_port(int32 queueLength, const char *name)
|| queueLength > MAX_QUEUE_LENGTH)
return B_BAD_VALUE;
// check early on if there are any free port slots to use
if (atomic_add(&sUsedPorts, 1) >= sMaxPorts) {
atomic_add(&sUsedPorts, -1);
return B_NO_MORE_PORTS;
}
// check & dup name
if (name == NULL)
name = "unnamed port";
@ -403,8 +403,10 @@ create_port(int32 queueLength, const char *name)
// ToDo: we could save the memory and use the semaphore name only instead
strlcpy(nameBuffer, name, B_OS_NAME_LENGTH);
name = strdup(nameBuffer);
if (name == NULL)
if (name == NULL) {
atomic_add(&sUsedPorts, -1);
return B_NO_MEMORY;
}
// create read sem with owner set to -1
// ToDo: should be B_SYSTEM_TEAM
@ -412,6 +414,7 @@ create_port(int32 queueLength, const char *name)
if (readSem < B_OK) {
// cleanup
free((char *)name);
atomic_add(&sUsedPorts, -1);
return readSem;
}
@ -421,6 +424,7 @@ create_port(int32 queueLength, const char *name)
// cleanup
delete_sem(readSem);
free((char *)name);
atomic_add(&sUsedPorts, -1);
return writeSem;
}
@ -440,6 +444,7 @@ create_port(int32 queueLength, const char *name)
GRAB_PORT_LOCK(sPorts[i]);
sPorts[i].id = sNextPort++;
atomic_add(&sUsedPorts, 1);
RELEASE_PORT_LIST_LOCK();
sPorts[i].capacity = queueLength;
@ -452,12 +457,17 @@ create_port(int32 queueLength, const char *name)
list_init(&sPorts[i].msg_queue);
sPorts[i].total_count = 0;
returnValue = sPorts[i].id;
RELEASE_PORT_LOCK(sPorts[i]);
goto out;
}
}
// ToDo: due to sUsedPorts, this cannot happen anymore - as
// long as sMaxPorts stays constant over the kernel run
// time (which it should be). IOW we could simply panic()
// here.
// not enough ports...
RELEASE_PORT_LIST_LOCK();
returnValue = B_NO_MORE_PORTS;
@ -467,6 +477,7 @@ create_port(int32 queueLength, const char *name)
delete_sem(writeSem);
delete_sem(readSem);
free((char *)name);
atomic_add(&sUsedPorts, -1);
out:
restore_interrupts(state);
@ -543,6 +554,8 @@ delete_port(port_id id)
RELEASE_PORT_LOCK(sPorts[slot]);
restore_interrupts(state);
atomic_add(&sUsedPorts, -1);
// free the queue
while ((msg = (port_msg *)list_remove_head_item(&list)) != NULL) {
put_port_msg(msg);

View File

@ -53,6 +53,7 @@ struct sem_entry {
// Todo: Compute based on the amount of available memory.
static int32 sMaxSems = 4096;
static int32 sUsedSems = 0;
static struct sem_entry *gSems = NULL;
static region_id gSemRegion = 0;
@ -224,7 +225,7 @@ create_sem_etc(int32 count, const char *name, team_id owner)
char *temp_name;
int name_len;
if (gSemsActive == false)
if (gSemsActive == false || sUsedSems == sMaxSems)
return B_NO_MORE_SEMS;
if (name == NULL)
@ -255,8 +256,10 @@ create_sem_etc(int32 count, const char *name, team_id owner)
sem->u.used.q.head = NULL;
sem->u.used.name = temp_name;
sem->u.used.owner = owner;
RELEASE_SEM_LOCK(*sem);
retval = sem->id;
RELEASE_SEM_LOCK(*sem);
atomic_add(&sUsedSems, 1);
}
RELEASE_SEM_LIST_LOCK();
@ -332,6 +335,7 @@ delete_sem_etc(sem_id id, status_t return_code, bool interrupted)
// append slot to the free list
GRAB_SEM_LIST_LOCK();
free_sem_slot(slot, id + sMaxSems);
atomic_add(&sUsedSems, -1);
RELEASE_SEM_LIST_LOCK();
if (released_threads > 0) {
@ -930,16 +934,7 @@ sem_max_sems(void)
int32
sem_used_sems(void)
{
int32 count = 0;
int32 i;
// ToDo: we should have a variable that counts the used sems for us
for (i = 0; i < sMaxSems; i++) {
if (gSems[i].id >= 0)
count++;
}
return count;
return sUsedSems;
}