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:
parent
5de1932a25
commit
0b8a2c94ce
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user