Basic VM and other minor improvements.
Not complete, probably not fully debugged or optimized.
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
# Makefile for lib/utils.
|
||||
# Makefile for lib/sysutil.
|
||||
|
||||
CFLAGS="-O -D_MINIX -D_POSIX_SOURCE"
|
||||
|
||||
LIBRARIES=libsysutil
|
||||
LIBRARIES=libsys
|
||||
|
||||
libsysutil_FILES=" \
|
||||
libsys_FILES=" \
|
||||
asynsend.c \
|
||||
kmalloc.c \
|
||||
kprintf.c \
|
||||
kputc.c \
|
||||
@@ -21,6 +22,8 @@ libsysutil_FILES=" \
|
||||
taskcall.c \
|
||||
read_tsc.s \
|
||||
read_tsc_64.c \
|
||||
stacktrace.c \
|
||||
sys_hz.c \
|
||||
profile_extern.c \
|
||||
profile.c"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
static char print_buf[80]; /* output is buffered here */
|
||||
static char print_buf[80*25]; /* output is buffered here */
|
||||
|
||||
int kputc_use_private_grants= 0;
|
||||
|
||||
@@ -56,15 +56,22 @@ int c;
|
||||
|
||||
for(p = 0; procs[p] != NONE; p++) {
|
||||
/* Send the buffer to this output driver. */
|
||||
int may_asyn = 0;
|
||||
m.DIAG_BUF_COUNT = buf_count;
|
||||
if(GRANT_VALID(printgrants[p])) {
|
||||
m.m_type = DIAGNOSTICS_S;
|
||||
m.DIAG_PRINT_BUF_G = (char *) printgrants[p];
|
||||
may_asyn = 1;
|
||||
} else {
|
||||
m.m_type = DIAGNOSTICS;
|
||||
m.DIAG_PRINT_BUF_G = print_buf;
|
||||
}
|
||||
(void) _sendrec(procs[p], &m);
|
||||
if(may_asyn && procs[p] == LOG_PROC_NR) {
|
||||
m.m_type = ASYN_DIAGNOSTICS;
|
||||
(void) asynsend(procs[p], &m);
|
||||
} else {
|
||||
sendrec(procs[p], &m);
|
||||
}
|
||||
}
|
||||
|
||||
buf_count = 0;
|
||||
|
||||
@@ -10,20 +10,31 @@
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
#define CALIBRATE_TICKS (HZ/5)
|
||||
#define CALIBRATE_TICKS(h) ((h)/5)
|
||||
#define MICROHZ 1000000 /* number of micros per second */
|
||||
#define MICROSPERTICK (MICROHZ/HZ) /* number of micros per HZ tick */
|
||||
#define MICROSPERTICK(h) (MICROHZ/(h)) /* number of micros per HZ tick */
|
||||
|
||||
static u32_t calib_tsc;
|
||||
#define CALIBRATE \
|
||||
if(!calibrated) { \
|
||||
int r; \
|
||||
if((r=micro_delay_calibrate()) != OK) \
|
||||
panic(__FILE__, "micro_delay: calibrate failed\n", r); \
|
||||
}
|
||||
|
||||
static u32_t calib_tsc, Hz = 0;
|
||||
static int calibrated = 0;
|
||||
|
||||
int
|
||||
micro_delay_calibrate(void)
|
||||
{
|
||||
u64_t start, end, diff, hz;
|
||||
u64_t start, end, diff;
|
||||
struct tms tms;
|
||||
unsigned long t = 0;
|
||||
|
||||
/* Get HZ. */
|
||||
if(sys_getinfo(GET_HZ, &Hz, sizeof(Hz), 0, 0) != OK)
|
||||
Hz = HZ;
|
||||
|
||||
/* Wait for clock to tick. */
|
||||
while(!t || (t == times(&tms)))
|
||||
t = times(&tms);
|
||||
@@ -34,7 +45,7 @@ micro_delay_calibrate(void)
|
||||
* this using the TSC.
|
||||
*/
|
||||
read_tsc_64(&start);
|
||||
while(times(&tms) < t+CALIBRATE_TICKS) ;
|
||||
while(times(&tms) < t+CALIBRATE_TICKS(Hz)) ;
|
||||
read_tsc_64(&end);
|
||||
|
||||
diff = sub64(end, start);
|
||||
@@ -43,10 +54,12 @@ micro_delay_calibrate(void)
|
||||
"micro_delay_calibrate: CALIBRATE_TICKS too high "
|
||||
"for TSC frequency\n", NO_NUM);
|
||||
calib_tsc = ex64lo(diff);
|
||||
#if 0
|
||||
printf("micro_delay_calibrate: "
|
||||
"%lu cycles/%d ticks of %d Hz; %lu cycles/s\n",
|
||||
calib_tsc, CALIBRATE_TICKS, HZ,
|
||||
div64u(mul64u(calib_tsc, HZ), CALIBRATE_TICKS));
|
||||
calib_tsc, CALIBRATE_TICKS(Hz), Hz,
|
||||
div64u(mul64u(calib_tsc, Hz), CALIBRATE_TICKS(Hz)));
|
||||
#endif
|
||||
calibrated = 1;
|
||||
|
||||
return OK;
|
||||
@@ -60,17 +73,11 @@ micro_delay(u32_t micros)
|
||||
/* Start of delay. */
|
||||
read_tsc_64(&now);
|
||||
|
||||
/* We have to be calibrated. */
|
||||
if(!calibrated) {
|
||||
int r;
|
||||
printf("micro_delay: calibrating\n");
|
||||
if((r=micro_delay_calibrate()) != OK)
|
||||
panic(__FILE__, "micro_delay: calibrate failed\n", r);
|
||||
}
|
||||
CALIBRATE;
|
||||
|
||||
/* We have to know when to end the delay. */
|
||||
end = add64u(now, div64u(mul64u(calib_tsc,
|
||||
micros * HZ / CALIBRATE_TICKS), MICROHZ));
|
||||
micros * Hz / CALIBRATE_TICKS(Hz)), MICROHZ));
|
||||
|
||||
/* If we have to wait for at least one HZ tick, use the regular
|
||||
* tickdelay first. Round downwards on purpose, so the average
|
||||
@@ -78,8 +85,8 @@ micro_delay(u32_t micros)
|
||||
* we call tickdelay). We can correct for both overhead of tickdelay
|
||||
* itself and the short wait in the busywait later.
|
||||
*/
|
||||
if(micros >= MICROSPERTICK)
|
||||
tickdelay(micros*HZ/MICROHZ);
|
||||
if(micros >= MICROSPERTICK(Hz))
|
||||
tickdelay(micros*Hz/MICROHZ);
|
||||
|
||||
/* Wait (the rest) of the delay time using busywait. */
|
||||
while(cmp64(now, end) < 0)
|
||||
@@ -87,3 +94,4 @@ micro_delay(u32_t micros)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
63
lib/sysutil/stacktrace.c
Normal file
63
lib/sysutil/stacktrace.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
stacktrace.c
|
||||
|
||||
Created: Jan 19, 1993 by Philip Homburg
|
||||
|
||||
Copyright 1995 Philip Homburg
|
||||
*/
|
||||
|
||||
typedef unsigned int reg_t;
|
||||
|
||||
#define FUNC_STACKTRACE(statement) \
|
||||
{ \
|
||||
reg_t bp, pc, hbp; \
|
||||
extern reg_t get_bp(void); \
|
||||
\
|
||||
bp= get_bp(); \
|
||||
while(bp) \
|
||||
{ \
|
||||
pc= ((reg_t *)bp)[1]; \
|
||||
hbp= ((reg_t *)bp)[0]; \
|
||||
statement; \
|
||||
if (hbp != 0 && hbp <= bp) \
|
||||
{ \
|
||||
pc = -1; \
|
||||
statement; \
|
||||
break; \
|
||||
} \
|
||||
bp= hbp; \
|
||||
} \
|
||||
}
|
||||
|
||||
void util_nstrcat(char *str, unsigned long number)
|
||||
{
|
||||
int n = 10, lead = 1;
|
||||
char nbuf[12], *p;
|
||||
p = nbuf;
|
||||
*p++ = '0';
|
||||
*p++ = 'x';
|
||||
for(n = 0; n < 8; n++) {
|
||||
int i;
|
||||
i = (number >> ((7-n)*4)) & 0xF;
|
||||
if(!lead || i) {
|
||||
*p++ = i < 10 ? '0' + i : 'a' + i - 10;
|
||||
lead = 0;
|
||||
}
|
||||
}
|
||||
if(lead) *p++ = '0';
|
||||
*p++ = ' ';
|
||||
*p++ = '\0';
|
||||
strcat(str, nbuf);
|
||||
}
|
||||
|
||||
void util_stacktrace(void)
|
||||
{
|
||||
FUNC_STACKTRACE(printf("0x%lx ", (unsigned long) pc));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void util_stacktrace_strcat(char *str)
|
||||
{
|
||||
FUNC_STACKTRACE(util_nstrcat(str, pc));
|
||||
}
|
||||
|
||||
41
lib/sysutil/sys_hz.c
Normal file
41
lib/sysutil/sys_hz.c
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/types.h>
|
||||
#include <minix/u64.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
static u32_t Hz;
|
||||
|
||||
u32_t
|
||||
sys_hz(void)
|
||||
{
|
||||
if(Hz <= 0) {
|
||||
int r;
|
||||
/* Get HZ. */
|
||||
if((r=sys_getinfo(GET_HZ, &Hz, sizeof(Hz), 0, 0)) != OK) {
|
||||
Hz = HZ;
|
||||
printf("sys_hz: %d: reverting to HZ = %d\n", r, Hz);
|
||||
}
|
||||
}
|
||||
|
||||
return Hz;
|
||||
}
|
||||
|
||||
u32_t
|
||||
micros_to_ticks(u32_t micros)
|
||||
{
|
||||
u32_t ticks;
|
||||
|
||||
ticks = div64u(mul64u(micros, sys_hz()), 1000000);
|
||||
if(ticks < 1) ticks = 1;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user