1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:57:45 +00:00

Add gettimeofday() syscall and LibC wrappers gettimeofday() and time().

This only has second accuracy right now, I'll work out subseconds later.
This commit is contained in:
Andreas Kling 2018-10-25 17:29:49 +02:00
parent 5978185242
commit dc6f57f19c
20 changed files with 188 additions and 8 deletions

View file

@ -35,7 +35,8 @@ cpuid: smap=false, mwait=true
print_timestamps: enabled=0
port_e9_hack: enabled=1
private_colormap: enabled=0
clock: sync=none, time0=local, rtc_sync=0
#clock: sync=realtime, time0=local, rtc_sync=1
clock: sync=none, time0=local, rtc_sync=1
# no cmosimage
log: -
logprefix: %t%e%d

View file

@ -19,7 +19,8 @@ KERNEL_OBJS = \
Console.o \
IRQHandler.o \
kprintf.o \
ProcFileSystem.o
ProcFileSystem.o \
RTC.o
VFS_OBJS = \
../VirtualFileSystem/DiskDevice.o \

90
Kernel/RTC.cpp Normal file
View file

@ -0,0 +1,90 @@
#include "RTC.h"
#include "CMOS.h"
namespace RTC {
static time_t s_bootTime;
void initialize()
{
byte cmosMode = CMOS::read(0x0b);
cmosMode |= 2; // 24 hour mode
cmosMode |= 4; // No BCD mode
CMOS::write(0x0b, cmosMode);
s_bootTime = now();
}
time_t bootTime()
{
return s_bootTime;
}
static bool updateInProgress()
{
return CMOS::read(0x0a) & 0x80;
}
inline bool isLeapYear(unsigned year)
{
return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400) == 0));
}
static unsigned daysInMonthsSinceStartOfYear(unsigned month, unsigned year)
{
switch (month) {
case 11: return 30;
case 10: return 31;
case 9: return 30;
case 8: return 31;
case 7: return 31;
case 6: return 30;
case 5: return 31;
case 4: return 30;
case 3: return 31;
case 2:
if (isLeapYear(year))
return 29;
return 28;
case 1: return 31;
default: return 0;
}
}
static unsigned daysInYearsSinceEpoch(unsigned year)
{
unsigned days = 0;
while (year > 1969) {
days += 365;
if (isLeapYear(year))
++days;
--year;
}
return days;
}
time_t now()
{
// FIXME: We should probably do something more robust here.
// Perhaps read all the values twice and verify that they were identical.
// We don't want to be caught in the middle of an RTC register update.
while (updateInProgress())
;
unsigned year = (CMOS::read(0x32) * 100) + CMOS::read(0x09);
unsigned month = CMOS::read(0x08);
unsigned day = CMOS::read(0x07);
unsigned hour = CMOS::read(0x04);
unsigned minute = CMOS::read(0x02);
unsigned second = CMOS::read(0x00);
return daysInYearsSinceEpoch(year - 1) * 86400
+ daysInMonthsSinceStartOfYear(month - 1, year) * 86400
+ day * 86400
+ hour * 3600
+ minute * 60
+ second;
}
}

12
Kernel/RTC.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include "types.h"
namespace RTC {
void initialize();
time_t now();
time_t bootTime();
}

View file

@ -61,8 +61,9 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
Console::the().putChar(arg1 & 0xff);
break;
case Syscall::Sleep:
current->sys$sleep(arg1);
break;
return current->sys$sleep(arg1);
case Syscall::PosixGettimeofday:
return current->sys$gettimeofday((timeval*)arg1);
case Syscall::Spawn:
return current->sys$spawn((const char*)arg1);
case Syscall::GetDirEntries:

View file

@ -29,6 +29,7 @@ enum Function {
GetDirEntries = 0x1997,
PosixLstat = 0x1998,
PosixGetcwd = 0x1999,
PosixGettimeofday = 0x2000,
};
void initialize();

View file

@ -11,6 +11,7 @@
#include "MemoryManager.h"
#include "errno.h"
#include "i8253.h"
#include "RTC.h"
//#define DEBUG_IO
//#define TASK_DEBUG
@ -728,6 +729,15 @@ int Task::sys$sleep(unsigned seconds)
return 0;
}
int Task::sys$gettimeofday(timeval* tv)
{
InterruptDisabler disabler;
auto now = RTC::now();
tv->tv_sec = now;
tv->tv_usec = 0;
return 0;
}
uid_t Task::sys$getuid()
{
return m_uid;

View file

@ -99,6 +99,7 @@ public:
int sys$get_dir_entries(int fd, void*, size_t);
int sys$getcwd(char*, size_t);
int sys$sleep(unsigned seconds);
int sys$gettimeofday(timeval*);
static void initialize();

Binary file not shown.

View file

@ -25,6 +25,7 @@
#include <ELFLoader/ELFLoader.h>
#include "Console.h"
#include "ProcFileSystem.h"
#include "RTC.h"
#define TEST_VFS
//#define STRESS_TEST_SPAWNING
@ -179,6 +180,7 @@ void init()
auto console = make<Console>();
RTC::initialize();
PIC::initialize();
gdt_init();
idt_init();
@ -191,6 +193,7 @@ void init()
PIT::initialize();
memset(&system, 0, sizeof(system));
WORD base_memory = (CMOS::read(0x16) << 8) | CMOS::read(0x15);
WORD ext_memory = (CMOS::read(0x18) << 8) | CMOS::read(0x17);

View file

@ -1,5 +1,3 @@
#pragma once
#include "kprintf.h"
#include "Console.h"
#include <stdarg.h>

View file

@ -6,5 +6,6 @@ cp ../Userland/ps mnt/bin/ps
cp ../Userland/ls mnt/bin/ls
cp ../Userland/pwd mnt/bin/pwd
cp ../Userland/sleep mnt/bin/sleep
cp ../Userland/date mnt/bin/date
umount mnt
sync

View file

@ -23,8 +23,14 @@ typedef DWORD uid_t;
typedef DWORD gid_t;
typedef int pid_t;
typedef DWORD time_t;
typedef DWORD suseconds_t;
typedef DWORD size_t;
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
struct FarPtr {
DWORD offset { 0 };
WORD selector { 0 };