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:
+25
-12
@@ -56,6 +56,7 @@ static void _dump_port_info(struct port_entry *port);
|
|||||||
|
|
||||||
// sMaxPorts must be power of 2
|
// sMaxPorts must be power of 2
|
||||||
static int32 sMaxPorts = 4096;
|
static int32 sMaxPorts = 4096;
|
||||||
|
static int32 sUsedPorts = 0;
|
||||||
|
|
||||||
#define MAX_QUEUE_LENGTH 4096
|
#define MAX_QUEUE_LENGTH 4096
|
||||||
#define PORT_MAX_MESSAGE_SIZE 65536
|
#define PORT_MAX_MESSAGE_SIZE 65536
|
||||||
@@ -106,6 +107,8 @@ port_init(kernel_args *ka)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// ToDo: the test code does not belong here!
|
// 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
|
* testcode
|
||||||
*/
|
*/
|
||||||
@@ -361,16 +364,7 @@ port_max_ports(void)
|
|||||||
int32
|
int32
|
||||||
port_used_ports(void)
|
port_used_ports(void)
|
||||||
{
|
{
|
||||||
int32 count = 0;
|
return sUsedPorts;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -396,6 +390,12 @@ create_port(int32 queueLength, const char *name)
|
|||||||
|| queueLength > MAX_QUEUE_LENGTH)
|
|| queueLength > MAX_QUEUE_LENGTH)
|
||||||
return B_BAD_VALUE;
|
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
|
// check & dup name
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
name = "unnamed port";
|
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
|
// ToDo: we could save the memory and use the semaphore name only instead
|
||||||
strlcpy(nameBuffer, name, B_OS_NAME_LENGTH);
|
strlcpy(nameBuffer, name, B_OS_NAME_LENGTH);
|
||||||
name = strdup(nameBuffer);
|
name = strdup(nameBuffer);
|
||||||
if (name == NULL)
|
if (name == NULL) {
|
||||||
|
atomic_add(&sUsedPorts, -1);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
// create read sem with owner set to -1
|
// create read sem with owner set to -1
|
||||||
// ToDo: should be B_SYSTEM_TEAM
|
// ToDo: should be B_SYSTEM_TEAM
|
||||||
@@ -412,6 +414,7 @@ create_port(int32 queueLength, const char *name)
|
|||||||
if (readSem < B_OK) {
|
if (readSem < B_OK) {
|
||||||
// cleanup
|
// cleanup
|
||||||
free((char *)name);
|
free((char *)name);
|
||||||
|
atomic_add(&sUsedPorts, -1);
|
||||||
return readSem;
|
return readSem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,6 +424,7 @@ create_port(int32 queueLength, const char *name)
|
|||||||
// cleanup
|
// cleanup
|
||||||
delete_sem(readSem);
|
delete_sem(readSem);
|
||||||
free((char *)name);
|
free((char *)name);
|
||||||
|
atomic_add(&sUsedPorts, -1);
|
||||||
return writeSem;
|
return writeSem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,6 +444,7 @@ create_port(int32 queueLength, const char *name)
|
|||||||
|
|
||||||
GRAB_PORT_LOCK(sPorts[i]);
|
GRAB_PORT_LOCK(sPorts[i]);
|
||||||
sPorts[i].id = sNextPort++;
|
sPorts[i].id = sNextPort++;
|
||||||
|
atomic_add(&sUsedPorts, 1);
|
||||||
RELEASE_PORT_LIST_LOCK();
|
RELEASE_PORT_LIST_LOCK();
|
||||||
|
|
||||||
sPorts[i].capacity = queueLength;
|
sPorts[i].capacity = queueLength;
|
||||||
@@ -452,12 +457,17 @@ create_port(int32 queueLength, const char *name)
|
|||||||
list_init(&sPorts[i].msg_queue);
|
list_init(&sPorts[i].msg_queue);
|
||||||
sPorts[i].total_count = 0;
|
sPorts[i].total_count = 0;
|
||||||
returnValue = sPorts[i].id;
|
returnValue = sPorts[i].id;
|
||||||
|
|
||||||
RELEASE_PORT_LOCK(sPorts[i]);
|
RELEASE_PORT_LOCK(sPorts[i]);
|
||||||
goto out;
|
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...
|
// not enough ports...
|
||||||
RELEASE_PORT_LIST_LOCK();
|
RELEASE_PORT_LIST_LOCK();
|
||||||
returnValue = B_NO_MORE_PORTS;
|
returnValue = B_NO_MORE_PORTS;
|
||||||
@@ -467,6 +477,7 @@ create_port(int32 queueLength, const char *name)
|
|||||||
delete_sem(writeSem);
|
delete_sem(writeSem);
|
||||||
delete_sem(readSem);
|
delete_sem(readSem);
|
||||||
free((char *)name);
|
free((char *)name);
|
||||||
|
atomic_add(&sUsedPorts, -1);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
@@ -543,6 +554,8 @@ delete_port(port_id id)
|
|||||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
|
atomic_add(&sUsedPorts, -1);
|
||||||
|
|
||||||
// free the queue
|
// free the queue
|
||||||
while ((msg = (port_msg *)list_remove_head_item(&list)) != NULL) {
|
while ((msg = (port_msg *)list_remove_head_item(&list)) != NULL) {
|
||||||
put_port_msg(msg);
|
put_port_msg(msg);
|
||||||
|
|||||||
+7
-12
@@ -53,6 +53,7 @@ struct sem_entry {
|
|||||||
|
|
||||||
// Todo: Compute based on the amount of available memory.
|
// Todo: Compute based on the amount of available memory.
|
||||||
static int32 sMaxSems = 4096;
|
static int32 sMaxSems = 4096;
|
||||||
|
static int32 sUsedSems = 0;
|
||||||
|
|
||||||
static struct sem_entry *gSems = NULL;
|
static struct sem_entry *gSems = NULL;
|
||||||
static region_id gSemRegion = 0;
|
static region_id gSemRegion = 0;
|
||||||
@@ -224,7 +225,7 @@ create_sem_etc(int32 count, const char *name, team_id owner)
|
|||||||
char *temp_name;
|
char *temp_name;
|
||||||
int name_len;
|
int name_len;
|
||||||
|
|
||||||
if (gSemsActive == false)
|
if (gSemsActive == false || sUsedSems == sMaxSems)
|
||||||
return B_NO_MORE_SEMS;
|
return B_NO_MORE_SEMS;
|
||||||
|
|
||||||
if (name == NULL)
|
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.q.head = NULL;
|
||||||
sem->u.used.name = temp_name;
|
sem->u.used.name = temp_name;
|
||||||
sem->u.used.owner = owner;
|
sem->u.used.owner = owner;
|
||||||
RELEASE_SEM_LOCK(*sem);
|
|
||||||
retval = sem->id;
|
retval = sem->id;
|
||||||
|
RELEASE_SEM_LOCK(*sem);
|
||||||
|
|
||||||
|
atomic_add(&sUsedSems, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
RELEASE_SEM_LIST_LOCK();
|
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
|
// append slot to the free list
|
||||||
GRAB_SEM_LIST_LOCK();
|
GRAB_SEM_LIST_LOCK();
|
||||||
free_sem_slot(slot, id + sMaxSems);
|
free_sem_slot(slot, id + sMaxSems);
|
||||||
|
atomic_add(&sUsedSems, -1);
|
||||||
RELEASE_SEM_LIST_LOCK();
|
RELEASE_SEM_LIST_LOCK();
|
||||||
|
|
||||||
if (released_threads > 0) {
|
if (released_threads > 0) {
|
||||||
@@ -930,16 +934,7 @@ sem_max_sems(void)
|
|||||||
int32
|
int32
|
||||||
sem_used_sems(void)
|
sem_used_sems(void)
|
||||||
{
|
{
|
||||||
int32 count = 0;
|
return sUsedSems;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user