Partially implemented get_system_info(), courtesy of Jack Burton.
Added system_info.c to the build. Added stats support functions to sems & ports. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7290 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+30
-20
@@ -1,37 +1,47 @@
|
|||||||
SubDir OBOS_TOP src kernel core ;
|
SubDir OBOS_TOP src kernel core ;
|
||||||
|
|
||||||
|
{
|
||||||
|
local defines =
|
||||||
|
OBOS_ARCH=\\\"$(OBOS_ARCH)\\\"
|
||||||
|
;
|
||||||
|
|
||||||
|
defines = [ FDefines $(defines) ] ;
|
||||||
|
SubDirCcFlags $(defines) ;
|
||||||
|
SubDirC++Flags $(defines) ;
|
||||||
|
}
|
||||||
|
|
||||||
KernelMergeObject kernel_core.o :
|
KernelMergeObject kernel_core.o :
|
||||||
<$(SOURCE_GRIST)>cbuf.c
|
<$(SOURCE_GRIST)>cbuf.c
|
||||||
<$(SOURCE_GRIST)>console.c
|
<$(SOURCE_GRIST)>console.c
|
||||||
<$(SOURCE_GRIST)>cpu.c
|
<$(SOURCE_GRIST)>cpu.c
|
||||||
<$(SOURCE_GRIST)>debug.c
|
<$(SOURCE_GRIST)>debug.c
|
||||||
<$(SOURCE_GRIST)>elf.c
|
<$(SOURCE_GRIST)>elf.c
|
||||||
<$(SOURCE_GRIST)>faults.c
|
<$(SOURCE_GRIST)>faults.c
|
||||||
<$(SOURCE_GRIST)>gdb.c
|
<$(SOURCE_GRIST)>gdb.c
|
||||||
<$(SOURCE_GRIST)>heap.c
|
<$(SOURCE_GRIST)>heap.c
|
||||||
<$(SOURCE_GRIST)>image.c
|
<$(SOURCE_GRIST)>image.c
|
||||||
<$(SOURCE_GRIST)>int.c
|
<$(SOURCE_GRIST)>int.c
|
||||||
<$(SOURCE_GRIST)>kernel_daemon.c
|
<$(SOURCE_GRIST)>kernel_daemon.c
|
||||||
<$(SOURCE_GRIST)>khash.c
|
<$(SOURCE_GRIST)>khash.c
|
||||||
<$(SOURCE_GRIST)>linkhack.c
|
<$(SOURCE_GRIST)>linkhack.c
|
||||||
<$(SOURCE_GRIST)>lock.c
|
<$(SOURCE_GRIST)>lock.c
|
||||||
<$(SOURCE_GRIST)>main.c
|
<$(SOURCE_GRIST)>main.c
|
||||||
<$(SOURCE_GRIST)>misc.c
|
<$(SOURCE_GRIST)>misc.c
|
||||||
<$(SOURCE_GRIST)>module.c
|
<$(SOURCE_GRIST)>module.c
|
||||||
# <$(SOURCE_GRIST)>pools.c
|
<$(SOURCE_GRIST)>port.c
|
||||||
<$(SOURCE_GRIST)>port.c
|
|
||||||
<$(SOURCE_GRIST)>queue.c
|
<$(SOURCE_GRIST)>queue.c
|
||||||
<$(SOURCE_GRIST)>real_time_clock.c
|
<$(SOURCE_GRIST)>real_time_clock.c
|
||||||
<$(SOURCE_GRIST)>scheduler.c
|
<$(SOURCE_GRIST)>scheduler.c
|
||||||
<$(SOURCE_GRIST)>sem.c
|
<$(SOURCE_GRIST)>sem.c
|
||||||
<$(SOURCE_GRIST)>signal.c
|
<$(SOURCE_GRIST)>signal.c
|
||||||
|
<$(SOURCE_GRIST)>system_info.c
|
||||||
<$(SOURCE_GRIST)>smp.c
|
<$(SOURCE_GRIST)>smp.c
|
||||||
<$(SOURCE_GRIST)>syscalls.c
|
<$(SOURCE_GRIST)>syscalls.c
|
||||||
<$(SOURCE_GRIST)>sysctl.c
|
<$(SOURCE_GRIST)>sysctl.c
|
||||||
<$(SOURCE_GRIST)>team.c
|
<$(SOURCE_GRIST)>team.c
|
||||||
<$(SOURCE_GRIST)>thread.c
|
<$(SOURCE_GRIST)>thread.c
|
||||||
<$(SOURCE_GRIST)>timer.c
|
<$(SOURCE_GRIST)>timer.c
|
||||||
:
|
:
|
||||||
-fno-pic -D_KERNEL_MODE
|
-fno-pic -D_KERNEL_MODE
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
+47
-24
@@ -54,8 +54,8 @@ static int dump_port_info(int argc, char **argv);
|
|||||||
static void _dump_port_info(struct port_entry *port);
|
static void _dump_port_info(struct port_entry *port);
|
||||||
|
|
||||||
|
|
||||||
// gMaxPorts must be power of 2
|
// sMaxPorts must be power of 2
|
||||||
int32 gMaxPorts = 4096;
|
static int32 sMaxPorts = 4096;
|
||||||
|
|
||||||
#define MAX_QUEUE_LENGTH 4096
|
#define MAX_QUEUE_LENGTH 4096
|
||||||
#define PORT_MAX_MESSAGE_SIZE 65536
|
#define PORT_MAX_MESSAGE_SIZE 65536
|
||||||
@@ -77,7 +77,7 @@ status_t
|
|||||||
port_init(kernel_args *ka)
|
port_init(kernel_args *ka)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int size = sizeof(struct port_entry) * gMaxPorts;
|
int size = sizeof(struct port_entry) * sMaxPorts;
|
||||||
|
|
||||||
// create and initialize ports table
|
// create and initialize ports table
|
||||||
sPortArea = create_area("port_table", (void **)&sPorts, B_ANY_KERNEL_ADDRESS,
|
sPortArea = create_area("port_table", (void **)&sPorts, B_ANY_KERNEL_ADDRESS,
|
||||||
@@ -91,7 +91,7 @@ port_init(kernel_args *ka)
|
|||||||
// might do it as well, though :-)
|
// might do it as well, though :-)
|
||||||
|
|
||||||
memset(sPorts, 0, size);
|
memset(sPorts, 0, size);
|
||||||
for (i = 0; i < gMaxPorts; i++)
|
for (i = 0; i < sMaxPorts; i++)
|
||||||
sPorts[i].id = -1;
|
sPorts[i].id = -1;
|
||||||
|
|
||||||
// add debugger commands
|
// add debugger commands
|
||||||
@@ -212,7 +212,7 @@ dump_port_list(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < gMaxPorts; i++) {
|
for (i = 0; i < sMaxPorts; i++) {
|
||||||
if (sPorts[i].id >= 0)
|
if (sPorts[i].id >= 0)
|
||||||
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &sPorts[i], sPorts[i].id, sPorts[i].name);
|
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &sPorts[i], sPorts[i].id, sPorts[i].name);
|
||||||
}
|
}
|
||||||
@@ -251,11 +251,11 @@ dump_port_info(int argc, char **argv)
|
|||||||
|
|
||||||
if (num > KERNEL_BASE && num <= (KERNEL_BASE + (KERNEL_SIZE - 1))) {
|
if (num > KERNEL_BASE && num <= (KERNEL_BASE + (KERNEL_SIZE - 1))) {
|
||||||
// XXX semi-hack
|
// XXX semi-hack
|
||||||
// one can use either address or a port_id, since KERNEL_BASE > gMaxPorts assumed
|
// one can use either address or a port_id, since KERNEL_BASE > sMaxPorts assumed
|
||||||
_dump_port_info((struct port_entry *)num);
|
_dump_port_info((struct port_entry *)num);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
unsigned slot = num % gMaxPorts;
|
unsigned slot = num % sMaxPorts;
|
||||||
if(sPorts[slot].id != (int)num) {
|
if(sPorts[slot].id != (int)num) {
|
||||||
dprintf("port 0x%lx doesn't exist!\n", num);
|
dprintf("port 0x%lx doesn't exist!\n", num);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -266,7 +266,7 @@ dump_port_info(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// walk through the ports list, trying to match name
|
// walk through the ports list, trying to match name
|
||||||
for (i = 0; i < gMaxPorts; i++) {
|
for (i = 0; i < sMaxPorts; i++) {
|
||||||
if (sPorts[i].name != NULL
|
if (sPorts[i].name != NULL
|
||||||
&& strcmp(argv[1], sPorts[i].name) == 0) {
|
&& strcmp(argv[1], sPorts[i].name) == 0) {
|
||||||
_dump_port_info(&sPorts[i]);
|
_dump_port_info(&sPorts[i]);
|
||||||
@@ -296,7 +296,7 @@ delete_owned_ports(team_id owner)
|
|||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LIST_LOCK();
|
GRAB_PORT_LIST_LOCK();
|
||||||
|
|
||||||
for (i = 0; i < gMaxPorts; i++) {
|
for (i = 0; i < sMaxPorts; i++) {
|
||||||
if (sPorts[i].id != -1 && sPorts[i].owner == owner) {
|
if (sPorts[i].id != -1 && sPorts[i].owner == owner) {
|
||||||
port_id id = sPorts[i].id;
|
port_id id = sPorts[i].id;
|
||||||
|
|
||||||
@@ -351,6 +351,29 @@ get_port_msg(int32 code, size_t bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
port_max_ports(void)
|
||||||
|
{
|
||||||
|
return sMaxPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
// public kernel API
|
// public kernel API
|
||||||
|
|
||||||
@@ -407,13 +430,13 @@ create_port(int32 queueLength, const char *name)
|
|||||||
GRAB_PORT_LIST_LOCK();
|
GRAB_PORT_LIST_LOCK();
|
||||||
|
|
||||||
// find the first empty spot
|
// find the first empty spot
|
||||||
for (i = 0; i < gMaxPorts; i++) {
|
for (i = 0; i < sMaxPorts; i++) {
|
||||||
if (sPorts[i].id == -1) {
|
if (sPorts[i].id == -1) {
|
||||||
// make the port_id be a multiple of the slot it's in
|
// make the port_id be a multiple of the slot it's in
|
||||||
if (i >= sNextPort % gMaxPorts)
|
if (i >= sNextPort % sMaxPorts)
|
||||||
sNextPort += i - sNextPort % gMaxPorts;
|
sNextPort += i - sNextPort % sMaxPorts;
|
||||||
else
|
else
|
||||||
sNextPort += gMaxPorts - (sNextPort % gMaxPorts - i);
|
sNextPort += sMaxPorts - (sNextPort % sMaxPorts - i);
|
||||||
|
|
||||||
GRAB_PORT_LOCK(sPorts[i]);
|
GRAB_PORT_LOCK(sPorts[i]);
|
||||||
sPorts[i].id = sNextPort++;
|
sPorts[i].id = sNextPort++;
|
||||||
@@ -461,7 +484,7 @@ close_port(port_id id)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
// walk through the sem list, trying to match name
|
// walk through the sem list, trying to match name
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
@@ -497,7 +520,7 @@ delete_port(port_id id)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
@@ -553,7 +576,7 @@ find_port(const char *name)
|
|||||||
// the port lock in question, not the port list lock
|
// the port lock in question, not the port list lock
|
||||||
|
|
||||||
// loop over list
|
// loop over list
|
||||||
for (i = 0; i < gMaxPorts && portFound < B_OK; i++) {
|
for (i = 0; i < sMaxPorts && portFound < B_OK; i++) {
|
||||||
// lock every individual port before comparing
|
// lock every individual port before comparing
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[i]);
|
GRAB_PORT_LOCK(sPorts[i]);
|
||||||
@@ -605,7 +628,7 @@ _get_port_info(port_id id, port_info *info, size_t size)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
@@ -639,7 +662,7 @@ _get_next_port_info(team_id team, int32 *_cookie, struct port_info *info, size_t
|
|||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = *_cookie;
|
slot = *_cookie;
|
||||||
if (slot >= gMaxPorts)
|
if (slot >= sMaxPorts)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
if (team == B_CURRENT_TEAM)
|
if (team == B_CURRENT_TEAM)
|
||||||
@@ -651,7 +674,7 @@ _get_next_port_info(team_id team, int32 *_cookie, struct port_info *info, size_t
|
|||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LIST_LOCK();
|
GRAB_PORT_LIST_LOCK();
|
||||||
|
|
||||||
while (slot < gMaxPorts) {
|
while (slot < sMaxPorts) {
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
if (sPorts[slot].id != -1 && sPorts[slot].capacity != 0 && sPorts[slot].owner == team) {
|
if (sPorts[slot].id != -1 && sPorts[slot].capacity != 0 && sPorts[slot].owner == team) {
|
||||||
// found one!
|
// found one!
|
||||||
@@ -695,7 +718,7 @@ port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
@@ -761,7 +784,7 @@ port_count(port_id id)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
@@ -814,7 +837,7 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
@@ -922,7 +945,7 @@ write_port_etc(port_id id, int32 msgCode, const void *msgBuffer,
|
|||||||
|
|
||||||
// mask irrelevant flags (for acquire_sem() usage)
|
// mask irrelevant flags (for acquire_sem() usage)
|
||||||
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
if (bufferSize > PORT_MAX_MESSAGE_SIZE)
|
if (bufferSize > PORT_MAX_MESSAGE_SIZE)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@@ -1020,7 +1043,7 @@ set_port_owner(port_id id, team_id team)
|
|||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
|
|
||||||
slot = id % gMaxPorts;
|
slot = id % sMaxPorts;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_PORT_LOCK(sPorts[slot]);
|
GRAB_PORT_LOCK(sPorts[slot]);
|
||||||
|
|||||||
+42
-19
@@ -52,7 +52,7 @@ struct sem_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Todo: Compute based on the amount of available memory.
|
// Todo: Compute based on the amount of available memory.
|
||||||
#define MAX_SEMS 4096
|
static int32 sMaxSems = 4096;
|
||||||
|
|
||||||
static struct sem_entry *gSems = NULL;
|
static struct sem_entry *gSems = NULL;
|
||||||
static region_id gSemRegion = 0;
|
static region_id gSemRegion = 0;
|
||||||
@@ -80,7 +80,7 @@ dump_sem_list(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_SEMS; i++) {
|
for (i = 0; i < sMaxSems; i++) {
|
||||||
if (gSems[i].id >= 0)
|
if (gSems[i].id >= 0)
|
||||||
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &gSems[i], gSems[i].id,
|
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &gSems[i], gSems[i].id,
|
||||||
gSems[i].u.used.name);
|
gSems[i].u.used.name);
|
||||||
@@ -126,7 +126,7 @@ dump_sem_info(int argc, char **argv)
|
|||||||
dump_sem((struct sem_entry *)num);
|
dump_sem((struct sem_entry *)num);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
unsigned slot = num % MAX_SEMS;
|
unsigned slot = num % sMaxSems;
|
||||||
if (gSems[slot].id != (int)num) {
|
if (gSems[slot].id != (int)num) {
|
||||||
dprintf("sem 0x%lx doesn't exist!\n", num);
|
dprintf("sem 0x%lx doesn't exist!\n", num);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -137,7 +137,7 @@ dump_sem_info(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// walk through the sem list, trying to match name
|
// walk through the sem list, trying to match name
|
||||||
for (i = 0; i < MAX_SEMS; i++) {
|
for (i = 0; i < sMaxSems; i++) {
|
||||||
if (gSems[i].u.used.name != NULL
|
if (gSems[i].u.used.name != NULL
|
||||||
&& strcmp(argv[1], gSems[i].u.used.name) == 0) {
|
&& strcmp(argv[1], gSems[i].u.used.name) == 0) {
|
||||||
dump_sem(&gSems[i]);
|
dump_sem(&gSems[i]);
|
||||||
@@ -185,12 +185,12 @@ sem_init(kernel_args *ka)
|
|||||||
|
|
||||||
// create and initialize semaphore table
|
// create and initialize semaphore table
|
||||||
gSemRegion = create_area("sem_table", (void **)&gSems, B_ANY_KERNEL_ADDRESS,
|
gSemRegion = create_area("sem_table", (void **)&gSems, B_ANY_KERNEL_ADDRESS,
|
||||||
sizeof(struct sem_entry) * MAX_SEMS, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
if (gSemRegion < 0)
|
if (gSemRegion < 0)
|
||||||
panic("unable to allocate semaphore table!\n");
|
panic("unable to allocate semaphore table!\n");
|
||||||
|
|
||||||
memset(gSems, 0, sizeof(struct sem_entry) * MAX_SEMS);
|
memset(gSems, 0, sizeof(struct sem_entry) * sMaxSems);
|
||||||
for (i = 0; i < MAX_SEMS; i++) {
|
for (i = 0; i < sMaxSems; i++) {
|
||||||
gSems[i].id = -1;
|
gSems[i].id = -1;
|
||||||
free_sem_slot(i, i);
|
free_sem_slot(i, i);
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ delete_sem_etc(sem_id id, status_t return_code, bool interrupted)
|
|||||||
if (id < 0)
|
if (id < 0)
|
||||||
return B_BAD_SEM_ID;
|
return B_BAD_SEM_ID;
|
||||||
|
|
||||||
slot = id % MAX_SEMS;
|
slot = id % sMaxSems;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
@@ -331,7 +331,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 + MAX_SEMS);
|
free_sem_slot(slot, id + sMaxSems);
|
||||||
RELEASE_SEM_LIST_LOCK();
|
RELEASE_SEM_LIST_LOCK();
|
||||||
|
|
||||||
if (released_threads > 0) {
|
if (released_threads > 0) {
|
||||||
@@ -365,7 +365,7 @@ sem_timeout(timer *data)
|
|||||||
t = thread_get_thread_struct(args->blocked_thread);
|
t = thread_get_thread_struct(args->blocked_thread);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return B_HANDLED_INTERRUPT;
|
return B_HANDLED_INTERRUPT;
|
||||||
slot = args->blocked_sem_id % MAX_SEMS;
|
slot = args->blocked_sem_id % sMaxSems;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
@@ -406,7 +406,7 @@ acquire_sem(sem_id id)
|
|||||||
status_t
|
status_t
|
||||||
acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
|
acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
|
||||||
{
|
{
|
||||||
int slot = id % MAX_SEMS;
|
int slot = id % sMaxSems;
|
||||||
int state;
|
int state;
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ release_sem(sem_id id)
|
|||||||
status_t
|
status_t
|
||||||
release_sem_etc(sem_id id, int32 count, uint32 flags)
|
release_sem_etc(sem_id id, int32 count, uint32 flags)
|
||||||
{
|
{
|
||||||
int slot = id % MAX_SEMS;
|
int slot = id % sMaxSems;
|
||||||
int state;
|
int state;
|
||||||
int released_threads = 0;
|
int released_threads = 0;
|
||||||
struct thread_queue release_queue;
|
struct thread_queue release_queue;
|
||||||
@@ -630,7 +630,7 @@ get_sem_count(sem_id id, int32 *thread_count)
|
|||||||
if (thread_count == NULL)
|
if (thread_count == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
slot = id % MAX_SEMS;
|
slot = id % sMaxSems;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
@@ -689,7 +689,7 @@ _get_sem_info(sem_id id, struct sem_info *info, size_t size)
|
|||||||
if (info == NULL || size != sizeof(sem_info))
|
if (info == NULL || size != sizeof(sem_info))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
slot = id % MAX_SEMS;
|
slot = id % sMaxSems;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
@@ -732,13 +732,13 @@ _get_next_sem_info(team_id team, int32 *_cookie, struct sem_info *info, size_t s
|
|||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
|
|
||||||
slot = *_cookie;
|
slot = *_cookie;
|
||||||
if (slot >= MAX_SEMS)
|
if (slot >= sMaxSems)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LIST_LOCK();
|
GRAB_SEM_LIST_LOCK();
|
||||||
|
|
||||||
while (slot < MAX_SEMS) {
|
while (slot < sMaxSems) {
|
||||||
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
||||||
@@ -778,7 +778,7 @@ set_sem_owner(sem_id id, team_id team)
|
|||||||
if (team < 0 || !team_is_valid(team))
|
if (team < 0 || !team_is_valid(team))
|
||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
|
|
||||||
slot = id % MAX_SEMS;
|
slot = id % sMaxSems;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
@@ -822,7 +822,7 @@ sem_interrupt_thread(struct thread *t)
|
|||||||
if (!(t->sem_flags & B_CAN_INTERRUPT))
|
if (!(t->sem_flags & B_CAN_INTERRUPT))
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
slot = t->sem_blocking % MAX_SEMS;
|
slot = t->sem_blocking % sMaxSems;
|
||||||
|
|
||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
|
|
||||||
@@ -898,7 +898,7 @@ sem_delete_owned_sems(team_id owner)
|
|||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LIST_LOCK();
|
GRAB_SEM_LIST_LOCK();
|
||||||
|
|
||||||
for (i = 0; i < MAX_SEMS; i++) {
|
for (i = 0; i < sMaxSems; i++) {
|
||||||
if (gSems[i].id != -1 && gSems[i].u.used.owner == owner) {
|
if (gSems[i].id != -1 && gSems[i].u.used.owner == owner) {
|
||||||
sem_id id = gSems[i].id;
|
sem_id id = gSems[i].id;
|
||||||
|
|
||||||
@@ -920,6 +920,29 @@ sem_delete_owned_sems(team_id owner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
sem_max_sems(void)
|
||||||
|
{
|
||||||
|
return sMaxSems;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <kimage.h>
|
#include <kimage.h>
|
||||||
#include <ksignal.h>
|
#include <ksignal.h>
|
||||||
#include <real_time_clock.h>
|
#include <real_time_clock.h>
|
||||||
|
#include <system_info.h>
|
||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <user_atomic.h>
|
#include <user_atomic.h>
|
||||||
@@ -451,7 +452,9 @@ syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret)
|
|||||||
case SYSCALL_SET_ALARM:
|
case SYSCALL_SET_ALARM:
|
||||||
*call_ret = user_set_alarm((bigtime_t)INT32TOINT64(arg0, arg1), (uint32)arg2);
|
*call_ret = user_set_alarm((bigtime_t)INT32TOINT64(arg0, arg1), (uint32)arg2);
|
||||||
break;
|
break;
|
||||||
|
case SYSCALL_GET_SYSTEM_INFO:
|
||||||
|
*call_ret = _user_get_system_info((system_info *)arg0, (size_t)arg1);
|
||||||
|
break;
|
||||||
// 32 bit atomic functions
|
// 32 bit atomic functions
|
||||||
#ifdef ATOMIC_FUNCS_ARE_SYSCALLS
|
#ifdef ATOMIC_FUNCS_ARE_SYSCALLS
|
||||||
case SYSCALL_ATOMIC_SET:
|
case SYSCALL_ATOMIC_SET:
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2004, Stefano Ceccherini. All rights reserved.
|
||||||
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <system_info.h>
|
||||||
|
#include <vm.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <port.h>
|
||||||
|
#include <real_time_clock.h>
|
||||||
|
#include <sem.h>
|
||||||
|
#include <smp.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
const static int64 kKernelVersion = 0x1;
|
||||||
|
const static char kKernelName[] = "kernel_" OBOS_ARCH;
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_get_system_info(system_info *info, size_t size)
|
||||||
|
{
|
||||||
|
if (size != sizeof(system_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
memset(info, 0, sizeof(system_info));
|
||||||
|
// TODO: Add:
|
||||||
|
// - max_pages
|
||||||
|
// - used_pages
|
||||||
|
// - page_faults
|
||||||
|
// - max_threads
|
||||||
|
// - used_threads
|
||||||
|
// - max_teams
|
||||||
|
// - used_teams
|
||||||
|
|
||||||
|
info->boot_time = rtc_boot_time();
|
||||||
|
info->cpu_count = smp_get_num_cpus();
|
||||||
|
info->used_ports = port_used_ports();
|
||||||
|
info->max_ports = port_max_ports();
|
||||||
|
info->used_sems = sem_used_sems();
|
||||||
|
info->max_sems = sem_max_sems();
|
||||||
|
|
||||||
|
info->kernel_version = kKernelVersion;
|
||||||
|
strlcpy(info->kernel_name, kKernelName, B_FILE_NAME_LENGTH);
|
||||||
|
strlcpy(info->kernel_build_date, __DATE__, B_OS_NAME_LENGTH);
|
||||||
|
strlcpy(info->kernel_build_time, __TIME__, B_OS_NAME_LENGTH);
|
||||||
|
|
||||||
|
// TODO: Add arch specific stuff (arch_get_system_info() ?)
|
||||||
|
// - cpu_type
|
||||||
|
// - cpu_revision
|
||||||
|
// - various cpu_info
|
||||||
|
// - cpu_clock_speed
|
||||||
|
// - bus_clock_speed
|
||||||
|
// - platform_type
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_user_get_system_info(system_info *userInfo, size_t size)
|
||||||
|
{
|
||||||
|
system_info info;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
// The BeBook says get_system_info() always returns B_OK,
|
||||||
|
// but that ain't true with invalid addresses
|
||||||
|
if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
status = _get_system_info(&info, size);
|
||||||
|
if (status == B_OK) {
|
||||||
|
if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user