1
0
Fork 0
mirror of https://gitlab.com/sortix/sortix.git synced 2023-02-13 20:55:38 -05:00

Add alarm(2) and alarmns(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-05-12 01:24:42 +02:00
parent df5deac29b
commit 2d94cd1246
11 changed files with 213 additions and 8 deletions

View file

@ -161,6 +161,8 @@ wctype.o \
HOSTEDOBJS=\ HOSTEDOBJS=\
access.o \ access.o \
alarmns.o \
alarm.o \
arpa/inet/inet_addr.o \ arpa/inet/inet_addr.o \
arpa/inet/inet_ntoa.o \ arpa/inet/inet_ntoa.o \
arpa/inet/inet_ntop.o \ arpa/inet/inet_ntop.o \

35
libc/alarm.cpp Normal file
View file

@ -0,0 +1,35 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
alarm.cpp
Set an alarm clock for delivery of a signal.
*******************************************************************************/
#include <timespec.h>
#include <unistd.h>
extern "C" unsigned int alarm(unsigned int seconds)
{
struct timespec delay = timespec_make(seconds, 0);
struct timespec odelay;
if ( alarmns(&delay, &odelay) < 0 )
return 0;
return odelay.tv_sec + (odelay.tv_nsec ? 1 : 0);
}

35
libc/alarmns.cpp Normal file
View file

@ -0,0 +1,35 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
alarmns.cpp
Set an alarm clock for delivery of a signal.
*******************************************************************************/
#include <sys/syscall.h>
#include <timespec.h>
#include <unistd.h>
DEFN_SYSCALL2(int, sys_alarmns, SYSCALL_ALARMNS, const struct timespec*, struct timespec*)
extern "C" int alarmns(const struct timespec* delay, struct timespec* odelay)
{
return sys_alarmns(delay, odelay);
}

View file

@ -34,6 +34,10 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <sortix/fork.h> #include <sortix/fork.h>
__BEGIN_DECLS
@include(time_t.h)
__END_DECLS
#include <sortix/timespec.h>
#endif #endif
#include <sortix/seek.h> #include <sortix/seek.h>
#include <sortix/unistd.h> #include <sortix/unistd.h>
@ -259,7 +263,6 @@ extern char** environ;
/* TODO: These are not implemented in sortix libc yet. */ /* TODO: These are not implemented in sortix libc yet. */
#if defined(__SORTIX_SHOW_UNIMPLEMENTED) #if defined(__SORTIX_SHOW_UNIMPLEMENTED)
unsigned alarm(unsigned);
char* crypt(const char*, const char*); char* crypt(const char*, const char*);
char* ctermid(char*); char* ctermid(char*);
void encrypt(char [64], int); void encrypt(char [64], int);
@ -296,6 +299,7 @@ extern int opterr, optind, optopt;
#endif #endif
int access(const char*, int); int access(const char*, int);
unsigned alarm(unsigned);
int chdir(const char*); int chdir(const char*);
int chown(const char*, uid_t, gid_t); int chown(const char*, uid_t, gid_t);
int close(int); int close(int);
@ -355,6 +359,7 @@ int unlink(const char*);
ssize_t write(int, const void*, size_t); ssize_t write(int, const void*, size_t);
#if defined(_SORTIX_SOURCE) #if defined(_SORTIX_SOURCE)
int alarmns(const struct timespec* delay, struct timespec* odelay);
int execvpe(const char*, char* const [], char* const []); int execvpe(const char*, char* const [], char* const []);
int getdtablesize(void); int getdtablesize(void);
size_t getpagesize(void); size_t getpagesize(void);

View file

@ -72,6 +72,7 @@ LIBS=\
OBJS=\ OBJS=\
$(CPUOBJS) \ $(CPUOBJS) \
addralloc.o \ addralloc.o \
alarm.o \
ata.o \ ata.o \
bga.o \ bga.o \
calltrace.o \ calltrace.o \

73
sortix/alarm.cpp Normal file
View file

@ -0,0 +1,73 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
Sortix. If not, see <http://www.gnu.org/licenses/>.
alarm.cpp
Sends a signal after a certain amount of time has passed.
*******************************************************************************/
#include <errno.h>
#include <timespec.h>
#include <sortix/itimerspec.h>
#include <sortix/signal.h>
#include <sortix/kernel/platform.h>
#include <sortix/kernel/clock.h>
#include <sortix/kernel/copy.h>
#include <sortix/kernel/timer.h>
#include <sortix/kernel/syscall.h>
#include "process.h"
namespace Sortix {
namespace Alarm {
static void alarm_handler(Clock* /*clock*/, Timer* /*timer*/, void* user)
{
Process* process = (Process*) user;
ScopedLock lock(&process->user_timers_lock);
process->DeliverSignal(SIGALRM);
}
int sys_alarmns(const struct timespec* user_delay, struct timespec* user_odelay)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->user_timers_lock);
struct itimerspec delay, odelay;
if ( !CopyFromUser(&delay.it_value, user_delay, sizeof(*user_delay)) )
return -1;
delay.it_interval = timespec_nul();
process->alarm_timer.Set(&delay, &odelay, 0, alarm_handler, (void*) process);
if ( !CopyToUser(user_odelay, &odelay.it_value, sizeof(*user_odelay)) )
return -1;
return 0;
}
void Init()
{
Syscall::Register(SYSCALL_ALARMNS, (void*) sys_alarmns);
}
} // namespace Alarm
} // namespace Sortix

31
sortix/alarm.h Normal file
View file

@ -0,0 +1,31 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
Sortix. If not, see <http://www.gnu.org/licenses/>.
alarm.h
Sends a signal after a certain amount of time has passed.
*******************************************************************************/
namespace Sortix {
namespace Alarm {
void Init();
} // namespace Alarm
} // namespace Sortix

View file

@ -123,6 +123,7 @@
#define SYSCALL_TIMER_GETOVERRUN 99 #define SYSCALL_TIMER_GETOVERRUN 99
#define SYSCALL_TIMER_GETTIME 100 #define SYSCALL_TIMER_GETTIME 100
#define SYSCALL_TIMER_SETTIME 101 #define SYSCALL_TIMER_SETTIME 101
#define SYSCALL_MAX_NUM 102 /* index of highest constant + 1 */ #define SYSCALL_ALARMNS 102
#define SYSCALL_MAX_NUM 103 /* index of highest constant + 1 */
#endif #endif

View file

@ -65,6 +65,7 @@
#include "thread.h" #include "thread.h"
#include "process.h" #include "process.h"
#include "signal.h" #include "signal.h"
#include "alarm.h"
#include "ata.h" #include "ata.h"
#include "com.h" #include "com.h"
#include "uart.h" #include "uart.h"
@ -429,6 +430,9 @@ static void BootThread(void* /*user*/)
// Initialize per-process timers. // Initialize per-process timers.
UserTimer::Init(); UserTimer::Init();
// Initialize per-process alarm timer.
Alarm::Init();
// Initialize the kernel information query syscall. // Initialize the kernel information query syscall.
Info::Init(); Info::Init();

View file

@ -37,6 +37,7 @@
#include <sortix/kernel/sortedlist.h> #include <sortix/kernel/sortedlist.h>
#include <sortix/kernel/scheduler.h> #include <sortix/kernel/scheduler.h>
#include <sortix/clock.h>
#include <sortix/signal.h> #include <sortix/signal.h>
#include <sortix/unistd.h> #include <sortix/unistd.h>
#include <sortix/fcntl.h> #include <sortix/fcntl.h>
@ -129,11 +130,14 @@ namespace Sortix
pid = AllocatePID(); pid = AllocatePID();
uid = euid = 0; uid = euid = 0;
gid = egid = 0; gid = egid = 0;
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
Put(this); Put(this);
} }
Process::~Process() Process::~Process()
{ {
if ( alarm_timer.IsAttached() )
alarm_timer.Detach();
if ( program_image_path ) if ( program_image_path )
delete[] program_image_path; delete[] program_image_path;
assert(!zombiechild); assert(!zombiechild);
@ -221,6 +225,18 @@ namespace Sortix
((Thread*) user)->SwitchAddressSpace(addrspace); ((Thread*) user)->SwitchAddressSpace(addrspace);
} }
void Process::DeleteTimers()
{
for ( timer_t i = 0; i < PROCESS_TIMER_NUM_MAX; i++ )
{
if ( user_timers[i].timer.IsAttached() )
{
user_timers[i].timer.Cancel();
user_timers[i].timer.Detach();
}
}
}
void Process::LastPrayer() void Process::LastPrayer()
{ {
assert(this); assert(this);
@ -236,13 +252,11 @@ namespace Sortix
assert(!firstthread); assert(!firstthread);
// Disarm and detach all the timers in the process. // Disarm and detach all the timers in the process.
for ( timer_t i = 0; i < PROCESS_TIMER_NUM_MAX; i++ ) DeleteTimers();
if ( alarm_timer.IsAttached() )
{ {
if ( user_timers[i].timer.IsAttached() ) alarm_timer.Cancel();
{ alarm_timer.Detach();
user_timers[i].timer.Cancel();
user_timers[i].timer.Detach();
}
} }
// We need to temporarily reload the correct addrese space of the dying // We need to temporarily reload the correct addrese space of the dying
@ -617,6 +631,8 @@ namespace Sortix
{ {
// TODO: Delete all threads and their stacks. // TODO: Delete all threads and their stacks.
DeleteTimers();
ResetAddressSpace(); ResetAddressSpace();
} }

View file

@ -145,6 +145,7 @@ namespace Sortix
public: public:
kthread_mutex_t user_timers_lock; kthread_mutex_t user_timers_lock;
UserTimer user_timers[PROCESS_TIMER_NUM_MAX]; UserTimer user_timers[PROCESS_TIMER_NUM_MAX];
Timer alarm_timer;
public: public:
int Execute(const char* programname, const uint8_t* program, int Execute(const char* programname, const uint8_t* program,
@ -172,6 +173,7 @@ namespace Sortix
void LastPrayer(); void LastPrayer();
void NotifyChildExit(Process* child, bool zombify); void NotifyChildExit(Process* child, bool zombify);
void NotifyNewZombies(); void NotifyNewZombies();
void DeleteTimers();
public: public:
void ResetForExecute(); void ResetForExecute();