Basic time functions and fix time system call
This commit is contained in:
parent
79a55fc518
commit
266dfcc857
@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
// Castor Only
|
// Castor Only
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
@ -34,6 +35,7 @@ Cmd_Help(int argc, const char *argv[])
|
|||||||
printf("exit Exit shell\n");
|
printf("exit Exit shell\n");
|
||||||
printf("help Display the list of commands\n");
|
printf("help Display the list of commands\n");
|
||||||
printf("ls List files in a directory\n");
|
printf("ls List files in a directory\n");
|
||||||
|
printf("date Print current date and time\n");
|
||||||
printf("bkpt Trigger a kernel breakpoint\n");
|
printf("bkpt Trigger a kernel breakpoint\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +112,13 @@ Cmd_Cat(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Cmd_Date(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
time_t t = time(NULL);
|
||||||
|
fputs(ctime(&t), stdout);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Cmd_Hexdump(int argc, const char *argv[])
|
Cmd_Hexdump(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
@ -146,21 +155,23 @@ DispatchCommand(char *buf)
|
|||||||
|
|
||||||
// execute command
|
// execute command
|
||||||
if (strcmp(argv[0], "help") == 0) {
|
if (strcmp(argv[0], "help") == 0) {
|
||||||
Cmd_Help(argc, (const char **)argv);
|
Cmd_Help(argc, (const char **)argv);
|
||||||
} else if (strcmp(argv[0], "bkpt") == 0) {
|
} else if (strcmp(argv[0], "bkpt") == 0) {
|
||||||
asm volatile("int3");
|
asm volatile("int3");
|
||||||
} else if (strcmp(argv[0], "cat") == 0) {
|
} else if (strcmp(argv[0], "cat") == 0) {
|
||||||
Cmd_Cat(argc, (const char **)argv);
|
Cmd_Cat(argc, (const char **)argv);
|
||||||
|
} else if (strcmp(argv[0], "date") == 0) {
|
||||||
|
Cmd_Date(argc, (const char **)argv);
|
||||||
} else if (strcmp(argv[0], "echo") == 0) {
|
} else if (strcmp(argv[0], "echo") == 0) {
|
||||||
Cmd_Echo(argc, (const char **)argv);
|
Cmd_Echo(argc, (const char **)argv);
|
||||||
} else if (strcmp(argv[0], "exit") == 0) {
|
} else if (strcmp(argv[0], "exit") == 0) {
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if (strcmp(argv[0], "ls") == 0) {
|
} else if (strcmp(argv[0], "ls") == 0) {
|
||||||
Cmd_List(argc, (const char **)argv);
|
Cmd_List(argc, (const char **)argv);
|
||||||
} else if (strcmp(argv[0], "#") == 0) {
|
} else if (strcmp(argv[0], "#") == 0) {
|
||||||
// Ignore comments
|
// Ignore comments
|
||||||
} else if (buf[0] != '\0') {
|
} else if (buf[0] != '\0') {
|
||||||
printf("Unknown command '%s'\n", buf);
|
printf("Unknown command '%s'\n", buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,5 +2,47 @@
|
|||||||
#ifndef __TIME_H__
|
#ifndef __TIME_H__
|
||||||
#define __TIME_H__
|
#define __TIME_H__
|
||||||
|
|
||||||
|
typedef uint64_t time_t;
|
||||||
|
typedef uint64_t suseconds_t;
|
||||||
|
|
||||||
|
struct tm {
|
||||||
|
int tm_sec;
|
||||||
|
int tm_min;
|
||||||
|
int tm_hour;
|
||||||
|
int tm_mday;
|
||||||
|
int tm_mon;
|
||||||
|
int tm_year;
|
||||||
|
int tm_wday;
|
||||||
|
int tm_yday;
|
||||||
|
int tm_isdst;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeval
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timezone {
|
||||||
|
int tz_minuteswest;
|
||||||
|
int tz_dsttime;
|
||||||
|
};
|
||||||
|
|
||||||
|
time_t time(time_t *t);
|
||||||
|
char *asctime_r(const struct tm *tm, char *buf);
|
||||||
|
char *asctime(const struct tm *tm);
|
||||||
|
char *ctime_r(const time_t *timep, char *buf);
|
||||||
|
char *ctime(const time_t *timep);
|
||||||
|
struct tm *gmtime(const time_t *timep);
|
||||||
|
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||||
|
struct tm *localtime(const time_t *timep);
|
||||||
|
struct tm *localtime_r(const time_t *timep, struct tm *result);
|
||||||
|
time_t mktime(struct tm *tm);
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||||
|
|
||||||
|
// XXX: Not implemented
|
||||||
|
int settimeofday(const struct timeval *tv, const struct timezone *tz);
|
||||||
|
|
||||||
#endif /* __TIME_H__ */
|
#endif /* __TIME_H__ */
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ src_common = [
|
|||||||
"file.c",
|
"file.c",
|
||||||
"string.c",
|
"string.c",
|
||||||
"syscall.c",
|
"syscall.c",
|
||||||
|
"time.c",
|
||||||
"printf.c",
|
"printf.c",
|
||||||
"posix/mman.c",
|
"posix/mman.c",
|
||||||
]
|
]
|
||||||
|
@ -234,3 +234,57 @@ int fprintf(FILE *stream, const char *fmt, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct StrState {
|
||||||
|
char *buf;
|
||||||
|
char *cur;
|
||||||
|
size_t maxlen;
|
||||||
|
} StrState;
|
||||||
|
|
||||||
|
static void strputc(int c, void *handle)
|
||||||
|
{
|
||||||
|
StrState *state = (StrState *)handle;
|
||||||
|
|
||||||
|
if ((state->maxlen != -1) &&
|
||||||
|
(state->cur - state->buf >= state->maxlen)) {
|
||||||
|
state->cur[0] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->cur[0] = c;
|
||||||
|
state->cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf(char *str, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
StrState state;
|
||||||
|
|
||||||
|
state.buf = str;
|
||||||
|
state.cur = str;
|
||||||
|
state.maxlen = -1;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = kvprintf(fmt, strputc, &state, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snprintf(char *str, size_t n, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
StrState state;
|
||||||
|
|
||||||
|
state.buf = str;
|
||||||
|
state.cur = str;
|
||||||
|
state.maxlen = n;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = kvprintf(fmt, strputc, &state, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
214
lib/libc/time.c
Normal file
214
lib/libc/time.c
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
#define TZ_OFFSET_SECS 0
|
||||||
|
|
||||||
|
static const char *dayOfWeek[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||||
|
static const char *months[12] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
|
||||||
|
time_t
|
||||||
|
time(time_t *t)
|
||||||
|
{
|
||||||
|
uint64_t nsec = SystemTime();
|
||||||
|
time_t sec = nsec / 1000000000;
|
||||||
|
|
||||||
|
printf("%ld\n", nsec);
|
||||||
|
|
||||||
|
if (t)
|
||||||
|
*t = sec;
|
||||||
|
|
||||||
|
return sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||||
|
{
|
||||||
|
uint64_t nsec = SystemTime();
|
||||||
|
|
||||||
|
tv->tv_sec = nsec / 1000000000;
|
||||||
|
tv->tv_usec = (nsec % 1000000000) / 1000;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
settimeofday(const struct timeval *tv, const struct timezone *tz)
|
||||||
|
{
|
||||||
|
// set errno
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
asctime_r(const struct tm *tm, char *buf)
|
||||||
|
{
|
||||||
|
// assert(tm->tm_wday < 7);
|
||||||
|
// assert(tm->tm_mon < 12);
|
||||||
|
|
||||||
|
snprintf(buf, 26, "%s %s %2d %2d:%02d:%02d %4d\n",
|
||||||
|
dayOfWeek[tm->tm_wday], months[tm->tm_mon],
|
||||||
|
tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||||||
|
tm->tm_sec, tm->tm_year + 1900);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
asctime(const struct tm *tm)
|
||||||
|
{
|
||||||
|
static char buf[26];
|
||||||
|
return asctime_r(tm, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ctime_r(const time_t *timep, char *buf)
|
||||||
|
{
|
||||||
|
struct tm tm;
|
||||||
|
return asctime_r(localtime_r(timep, &tm), buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ctime(const time_t *timep)
|
||||||
|
{
|
||||||
|
return asctime(localtime(timep));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
Time_IsLeapYear(uint64_t year)
|
||||||
|
{
|
||||||
|
if ((year % 4) != 0)
|
||||||
|
return false;
|
||||||
|
if ((year % 100) != 0)
|
||||||
|
return true;
|
||||||
|
if ((year % 400) != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
Time_DaysInMonth(uint64_t year, uint64_t month)
|
||||||
|
{
|
||||||
|
static const uint64_t days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
|
||||||
|
if ((month == 2) && Time_IsLeapYear(year))
|
||||||
|
return 29;
|
||||||
|
else
|
||||||
|
return days[month];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct tm *
|
||||||
|
gmtime_r(const time_t *timep, struct tm *tm)
|
||||||
|
{
|
||||||
|
uint64_t secs, mins, hours;
|
||||||
|
uint64_t days;
|
||||||
|
uint64_t y, m;
|
||||||
|
|
||||||
|
// Compute seconds
|
||||||
|
secs = *timep % (60 * 60 * 24);
|
||||||
|
days = *timep / (60 * 60 * 24);
|
||||||
|
mins = secs / 60;
|
||||||
|
secs = secs % 60;
|
||||||
|
|
||||||
|
// Compute minutes
|
||||||
|
hours = mins / 60;
|
||||||
|
mins = mins % 60;
|
||||||
|
|
||||||
|
// Compute hours
|
||||||
|
hours = hours % 24;
|
||||||
|
|
||||||
|
tm->tm_sec = secs;
|
||||||
|
tm->tm_min = mins;
|
||||||
|
tm->tm_hour = hours;
|
||||||
|
|
||||||
|
tm->tm_wday = (days + 3) % 7;
|
||||||
|
|
||||||
|
for (y = 1970; ; y++) {
|
||||||
|
uint64_t daysOfYear;
|
||||||
|
if (Time_IsLeapYear(y)) {
|
||||||
|
daysOfYear = 366;
|
||||||
|
} else {
|
||||||
|
daysOfYear = 365;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days < daysOfYear) {
|
||||||
|
tm->tm_yday = days;
|
||||||
|
tm->tm_year = y - 1900;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
days -= daysOfYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (m = 0; ; m++) {
|
||||||
|
uint64_t daysOfMonth = Time_DaysInMonth(tm->tm_year + 1900, m);
|
||||||
|
|
||||||
|
if (days < daysOfMonth) {
|
||||||
|
tm->tm_mday = days;
|
||||||
|
tm->tm_mon = m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
days -= daysOfMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm *
|
||||||
|
gmtime(const time_t *timep)
|
||||||
|
{
|
||||||
|
static struct tm tm;
|
||||||
|
return gmtime_r(timep, &tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm *
|
||||||
|
localtime_r(const time_t *timep, struct tm *result)
|
||||||
|
{
|
||||||
|
time_t t = *timep - TZ_OFFSET_SECS;
|
||||||
|
return gmtime_r(&t, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm *
|
||||||
|
localtime(const time_t *timep)
|
||||||
|
{
|
||||||
|
static struct tm tm;
|
||||||
|
return localtime_r(timep, &tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
mktime(struct tm *tm)
|
||||||
|
{
|
||||||
|
uint64_t days = 0;
|
||||||
|
uint64_t secs = 0;
|
||||||
|
uint64_t y, m;
|
||||||
|
|
||||||
|
// Convert to UNIX epoch
|
||||||
|
for (y = 70; y < tm->tm_year; y++) {
|
||||||
|
if (Time_IsLeapYear(y))
|
||||||
|
days += 366;
|
||||||
|
else
|
||||||
|
days += 365;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t yday = 0;
|
||||||
|
for (m = 0; m < tm->tm_mon; m++) {
|
||||||
|
yday += Time_DaysInMonth(tm->tm_year + 1900, m);
|
||||||
|
}
|
||||||
|
yday += tm->tm_mday;
|
||||||
|
days += yday;
|
||||||
|
|
||||||
|
secs = 24 * days + tm->tm_hour;
|
||||||
|
secs = secs * 60 + tm->tm_min;
|
||||||
|
secs = secs * 60 + tm->tm_sec;
|
||||||
|
|
||||||
|
secs += TZ_OFFSET_SECS;
|
||||||
|
|
||||||
|
return secs;
|
||||||
|
}
|
||||||
|
|
@ -204,9 +204,11 @@ KTime_GetEpochNS()
|
|||||||
Spinlock_Lock(&ktimeLock);
|
Spinlock_Lock(&ktimeLock);
|
||||||
tscDiff = Time_GetTSC() - ktimeLastTSC;
|
tscDiff = Time_GetTSC() - ktimeLastTSC;
|
||||||
if (ticksPerSecondStable)
|
if (ticksPerSecondStable)
|
||||||
epoch = ktimeLastEpoch + tscDiff / (ticksPerSecondStable / 1000000);
|
epoch = ktimeLastEpoch * 1000000000
|
||||||
|
+ tscDiff * 1000000000 / ticksPerSecondStable;
|
||||||
else
|
else
|
||||||
epoch = ktimeLastEpoch + tscDiff / (ticksPerSecond / 1000000);
|
epoch = ktimeLastEpoch * 1000000000
|
||||||
|
+ tscDiff * 1000000000 / ticksPerSecond;
|
||||||
Spinlock_Unlock(&ktimeLock);
|
Spinlock_Unlock(&ktimeLock);
|
||||||
|
|
||||||
return epoch;
|
return epoch;
|
||||||
|
Loading…
Reference in New Issue
Block a user