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:
parent
f6a31876ce
commit
9fac193453
@ -1,37 +1,47 @@
|
||||
SubDir OBOS_TOP src kernel core ;
|
||||
|
||||
{
|
||||
local defines =
|
||||
OBOS_ARCH=\\\"$(OBOS_ARCH)\\\"
|
||||
;
|
||||
|
||||
defines = [ FDefines $(defines) ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
}
|
||||
|
||||
KernelMergeObject kernel_core.o :
|
||||
<$(SOURCE_GRIST)>cbuf.c
|
||||
<$(SOURCE_GRIST)>console.c
|
||||
<$(SOURCE_GRIST)>cpu.c
|
||||
<$(SOURCE_GRIST)>debug.c
|
||||
<$(SOURCE_GRIST)>elf.c
|
||||
<$(SOURCE_GRIST)>elf.c
|
||||
<$(SOURCE_GRIST)>faults.c
|
||||
<$(SOURCE_GRIST)>gdb.c
|
||||
<$(SOURCE_GRIST)>heap.c
|
||||
<$(SOURCE_GRIST)>image.c
|
||||
<$(SOURCE_GRIST)>int.c
|
||||
<$(SOURCE_GRIST)>kernel_daemon.c
|
||||
<$(SOURCE_GRIST)>khash.c
|
||||
<$(SOURCE_GRIST)>linkhack.c
|
||||
<$(SOURCE_GRIST)>lock.c
|
||||
<$(SOURCE_GRIST)>main.c
|
||||
<$(SOURCE_GRIST)>misc.c
|
||||
<$(SOURCE_GRIST)>module.c
|
||||
# <$(SOURCE_GRIST)>pools.c
|
||||
<$(SOURCE_GRIST)>port.c
|
||||
<$(SOURCE_GRIST)>gdb.c
|
||||
<$(SOURCE_GRIST)>heap.c
|
||||
<$(SOURCE_GRIST)>image.c
|
||||
<$(SOURCE_GRIST)>int.c
|
||||
<$(SOURCE_GRIST)>kernel_daemon.c
|
||||
<$(SOURCE_GRIST)>khash.c
|
||||
<$(SOURCE_GRIST)>linkhack.c
|
||||
<$(SOURCE_GRIST)>lock.c
|
||||
<$(SOURCE_GRIST)>main.c
|
||||
<$(SOURCE_GRIST)>misc.c
|
||||
<$(SOURCE_GRIST)>module.c
|
||||
<$(SOURCE_GRIST)>port.c
|
||||
<$(SOURCE_GRIST)>queue.c
|
||||
<$(SOURCE_GRIST)>real_time_clock.c
|
||||
<$(SOURCE_GRIST)>scheduler.c
|
||||
<$(SOURCE_GRIST)>scheduler.c
|
||||
<$(SOURCE_GRIST)>sem.c
|
||||
<$(SOURCE_GRIST)>signal.c
|
||||
<$(SOURCE_GRIST)>system_info.c
|
||||
<$(SOURCE_GRIST)>smp.c
|
||||
<$(SOURCE_GRIST)>syscalls.c
|
||||
<$(SOURCE_GRIST)>syscalls.c
|
||||
<$(SOURCE_GRIST)>sysctl.c
|
||||
<$(SOURCE_GRIST)>team.c
|
||||
<$(SOURCE_GRIST)>thread.c
|
||||
<$(SOURCE_GRIST)>timer.c
|
||||
:
|
||||
<$(SOURCE_GRIST)>team.c
|
||||
<$(SOURCE_GRIST)>thread.c
|
||||
<$(SOURCE_GRIST)>timer.c
|
||||
:
|
||||
-fno-pic -D_KERNEL_MODE
|
||||
;
|
||||
|
||||
|
@ -54,8 +54,8 @@ static int dump_port_info(int argc, char **argv);
|
||||
static void _dump_port_info(struct port_entry *port);
|
||||
|
||||
|
||||
// gMaxPorts must be power of 2
|
||||
int32 gMaxPorts = 4096;
|
||||
// sMaxPorts must be power of 2
|
||||
static int32 sMaxPorts = 4096;
|
||||
|
||||
#define MAX_QUEUE_LENGTH 4096
|
||||
#define PORT_MAX_MESSAGE_SIZE 65536
|
||||
@ -77,7 +77,7 @@ status_t
|
||||
port_init(kernel_args *ka)
|
||||
{
|
||||
int i;
|
||||
int size = sizeof(struct port_entry) * gMaxPorts;
|
||||
int size = sizeof(struct port_entry) * sMaxPorts;
|
||||
|
||||
// create and initialize ports table
|
||||
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 :-)
|
||||
|
||||
memset(sPorts, 0, size);
|
||||
for (i = 0; i < gMaxPorts; i++)
|
||||
for (i = 0; i < sMaxPorts; i++)
|
||||
sPorts[i].id = -1;
|
||||
|
||||
// add debugger commands
|
||||
@ -212,7 +212,7 @@ dump_port_list(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gMaxPorts; i++) {
|
||||
for (i = 0; i < sMaxPorts; i++) {
|
||||
if (sPorts[i].id >= 0)
|
||||
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))) {
|
||||
// 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);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned slot = num % gMaxPorts;
|
||||
unsigned slot = num % sMaxPorts;
|
||||
if(sPorts[slot].id != (int)num) {
|
||||
dprintf("port 0x%lx doesn't exist!\n", num);
|
||||
return 0;
|
||||
@ -266,7 +266,7 @@ dump_port_info(int argc, char **argv)
|
||||
}
|
||||
|
||||
// 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
|
||||
&& strcmp(argv[1], sPorts[i].name) == 0) {
|
||||
_dump_port_info(&sPorts[i]);
|
||||
@ -296,7 +296,7 @@ delete_owned_ports(team_id owner)
|
||||
state = disable_interrupts();
|
||||
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) {
|
||||
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 -
|
||||
// public kernel API
|
||||
|
||||
@ -407,13 +430,13 @@ create_port(int32 queueLength, const char *name)
|
||||
GRAB_PORT_LIST_LOCK();
|
||||
|
||||
// find the first empty spot
|
||||
for (i = 0; i < gMaxPorts; i++) {
|
||||
for (i = 0; i < sMaxPorts; i++) {
|
||||
if (sPorts[i].id == -1) {
|
||||
// make the port_id be a multiple of the slot it's in
|
||||
if (i >= sNextPort % gMaxPorts)
|
||||
sNextPort += i - sNextPort % gMaxPorts;
|
||||
if (i >= sNextPort % sMaxPorts)
|
||||
sNextPort += i - sNextPort % sMaxPorts;
|
||||
else
|
||||
sNextPort += gMaxPorts - (sNextPort % gMaxPorts - i);
|
||||
sNextPort += sMaxPorts - (sNextPort % sMaxPorts - i);
|
||||
|
||||
GRAB_PORT_LOCK(sPorts[i]);
|
||||
sPorts[i].id = sNextPort++;
|
||||
@ -461,7 +484,7 @@ close_port(port_id id)
|
||||
if (!sPortsActive || id < 0)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
// walk through the sem list, trying to match name
|
||||
state = disable_interrupts();
|
||||
@ -497,7 +520,7 @@ delete_port(port_id id)
|
||||
if (!sPortsActive || id < 0)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_PORT_LOCK(sPorts[slot]);
|
||||
@ -553,7 +576,7 @@ find_port(const char *name)
|
||||
// the port lock in question, not the port list lock
|
||||
|
||||
// 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
|
||||
state = disable_interrupts();
|
||||
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)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
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;
|
||||
|
||||
slot = *_cookie;
|
||||
if (slot >= gMaxPorts)
|
||||
if (slot >= sMaxPorts)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
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();
|
||||
GRAB_PORT_LIST_LOCK();
|
||||
|
||||
while (slot < gMaxPorts) {
|
||||
while (slot < sMaxPorts) {
|
||||
GRAB_PORT_LOCK(sPorts[slot]);
|
||||
if (sPorts[slot].id != -1 && sPorts[slot].capacity != 0 && sPorts[slot].owner == team) {
|
||||
// found one!
|
||||
@ -695,7 +718,7 @@ port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
||||
if (!sPortsActive || id < 0)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_PORT_LOCK(sPorts[slot]);
|
||||
@ -761,7 +784,7 @@ port_count(port_id id)
|
||||
if (!sPortsActive || id < 0)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
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;
|
||||
|
||||
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
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)
|
||||
flags = flags & (B_CAN_INTERRUPT | B_TIMEOUT);
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
if (bufferSize > PORT_MAX_MESSAGE_SIZE)
|
||||
return EINVAL;
|
||||
@ -1020,7 +1043,7 @@ set_port_owner(port_id id, team_id team)
|
||||
if (!sPortsActive || id < 0)
|
||||
return B_BAD_PORT_ID;
|
||||
|
||||
slot = id % gMaxPorts;
|
||||
slot = id % sMaxPorts;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_PORT_LOCK(sPorts[slot]);
|
||||
|
@ -52,7 +52,7 @@ struct sem_entry {
|
||||
};
|
||||
|
||||
// Todo: Compute based on the amount of available memory.
|
||||
#define MAX_SEMS 4096
|
||||
static int32 sMaxSems = 4096;
|
||||
|
||||
static struct sem_entry *gSems = NULL;
|
||||
static region_id gSemRegion = 0;
|
||||
@ -80,7 +80,7 @@ dump_sem_list(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SEMS; i++) {
|
||||
for (i = 0; i < sMaxSems; i++) {
|
||||
if (gSems[i].id >= 0)
|
||||
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &gSems[i], gSems[i].id,
|
||||
gSems[i].u.used.name);
|
||||
@ -126,7 +126,7 @@ dump_sem_info(int argc, char **argv)
|
||||
dump_sem((struct sem_entry *)num);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned slot = num % MAX_SEMS;
|
||||
unsigned slot = num % sMaxSems;
|
||||
if (gSems[slot].id != (int)num) {
|
||||
dprintf("sem 0x%lx doesn't exist!\n", num);
|
||||
return 0;
|
||||
@ -137,7 +137,7 @@ dump_sem_info(int argc, char **argv)
|
||||
}
|
||||
|
||||
// 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
|
||||
&& strcmp(argv[1], gSems[i].u.used.name) == 0) {
|
||||
dump_sem(&gSems[i]);
|
||||
@ -185,12 +185,12 @@ sem_init(kernel_args *ka)
|
||||
|
||||
// create and initialize semaphore table
|
||||
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)
|
||||
panic("unable to allocate semaphore table!\n");
|
||||
|
||||
memset(gSems, 0, sizeof(struct sem_entry) * MAX_SEMS);
|
||||
for (i = 0; i < MAX_SEMS; i++) {
|
||||
memset(gSems, 0, sizeof(struct sem_entry) * sMaxSems);
|
||||
for (i = 0; i < sMaxSems; i++) {
|
||||
gSems[i].id = -1;
|
||||
free_sem_slot(i, i);
|
||||
}
|
||||
@ -298,7 +298,7 @@ delete_sem_etc(sem_id id, status_t return_code, bool interrupted)
|
||||
if (id < 0)
|
||||
return B_BAD_SEM_ID;
|
||||
|
||||
slot = id % MAX_SEMS;
|
||||
slot = id % sMaxSems;
|
||||
|
||||
state = disable_interrupts();
|
||||
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
|
||||
GRAB_SEM_LIST_LOCK();
|
||||
free_sem_slot(slot, id + MAX_SEMS);
|
||||
free_sem_slot(slot, id + sMaxSems);
|
||||
RELEASE_SEM_LIST_LOCK();
|
||||
|
||||
if (released_threads > 0) {
|
||||
@ -365,7 +365,7 @@ sem_timeout(timer *data)
|
||||
t = thread_get_thread_struct(args->blocked_thread);
|
||||
if (t == NULL)
|
||||
return B_HANDLED_INTERRUPT;
|
||||
slot = args->blocked_sem_id % MAX_SEMS;
|
||||
slot = args->blocked_sem_id % sMaxSems;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_SEM_LOCK(gSems[slot]);
|
||||
@ -406,7 +406,7 @@ acquire_sem(sem_id id)
|
||||
status_t
|
||||
acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
|
||||
{
|
||||
int slot = id % MAX_SEMS;
|
||||
int slot = id % sMaxSems;
|
||||
int state;
|
||||
status_t status = B_OK;
|
||||
|
||||
@ -538,7 +538,7 @@ release_sem(sem_id id)
|
||||
status_t
|
||||
release_sem_etc(sem_id id, int32 count, uint32 flags)
|
||||
{
|
||||
int slot = id % MAX_SEMS;
|
||||
int slot = id % sMaxSems;
|
||||
int state;
|
||||
int released_threads = 0;
|
||||
struct thread_queue release_queue;
|
||||
@ -630,7 +630,7 @@ get_sem_count(sem_id id, int32 *thread_count)
|
||||
if (thread_count == NULL)
|
||||
return EINVAL;
|
||||
|
||||
slot = id % MAX_SEMS;
|
||||
slot = id % sMaxSems;
|
||||
|
||||
state = disable_interrupts();
|
||||
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))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
slot = id % MAX_SEMS;
|
||||
slot = id % sMaxSems;
|
||||
|
||||
state = disable_interrupts();
|
||||
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;
|
||||
|
||||
slot = *_cookie;
|
||||
if (slot >= MAX_SEMS)
|
||||
if (slot >= sMaxSems)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_SEM_LIST_LOCK();
|
||||
|
||||
while (slot < MAX_SEMS) {
|
||||
while (slot < sMaxSems) {
|
||||
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
||||
GRAB_SEM_LOCK(gSems[slot]);
|
||||
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))
|
||||
return B_BAD_TEAM_ID;
|
||||
|
||||
slot = id % MAX_SEMS;
|
||||
slot = id % sMaxSems;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_SEM_LOCK(gSems[slot]);
|
||||
@ -822,7 +822,7 @@ sem_interrupt_thread(struct thread *t)
|
||||
if (!(t->sem_flags & B_CAN_INTERRUPT))
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
slot = t->sem_blocking % MAX_SEMS;
|
||||
slot = t->sem_blocking % sMaxSems;
|
||||
|
||||
GRAB_SEM_LOCK(gSems[slot]);
|
||||
|
||||
@ -898,7 +898,7 @@ sem_delete_owned_sems(team_id owner)
|
||||
state = disable_interrupts();
|
||||
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) {
|
||||
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 -
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <kimage.h>
|
||||
#include <ksignal.h>
|
||||
#include <real_time_clock.h>
|
||||
#include <system_info.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/socket.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:
|
||||
*call_ret = user_set_alarm((bigtime_t)INT32TOINT64(arg0, arg1), (uint32)arg2);
|
||||
break;
|
||||
|
||||
case SYSCALL_GET_SYSTEM_INFO:
|
||||
*call_ret = _user_get_system_info((system_info *)arg0, (size_t)arg1);
|
||||
break;
|
||||
// 32 bit atomic functions
|
||||
#ifdef ATOMIC_FUNCS_ARE_SYSCALLS
|
||||
case SYSCALL_ATOMIC_SET:
|
||||
|
85
src/kernel/core/system_info.c
Normal file
85
src/kernel/core/system_info.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user