Renamed sforkr(2) to tfork(2).
It's a much better name if you think of it as task-fork or thread-fork in the sense that it either modifies this task or creates a new one. This call will be used to provide user-space threads as well as fork(2).
This commit is contained in:
parent
111e359482
commit
755e855c08
|
@ -194,7 +194,7 @@ size_t pwriteleast(int fd, const void* buf, size_t least, size_t max, off_t off)
|
||||||
size_t readall(int fd, void* buf, size_t count);
|
size_t readall(int fd, void* buf, size_t count);
|
||||||
size_t readleast(int fd, void* buf, size_t least, size_t max);
|
size_t readleast(int fd, void* buf, size_t least, size_t max);
|
||||||
pid_t sfork(int flags);
|
pid_t sfork(int flags);
|
||||||
pid_t sforkr(int flags, sforkregs_t* regs);
|
pid_t tfork(int flags, tforkregs_t* regs);
|
||||||
int uptime(uintmax_t* usecssinceboot);
|
int uptime(uintmax_t* usecssinceboot);
|
||||||
int vexecl(const char*, va_list args);
|
int vexecl(const char*, va_list args);
|
||||||
int vexecle(const char*, va_list args);
|
int vexecle(const char*, va_list args);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
||||||
|
|
||||||
This file is part of LibMaxsi.
|
This file is part of LibMaxsi.
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace Maxsi
|
||||||
{
|
{
|
||||||
DEFN_SYSCALL1_VOID(SysExit, SYSCALL_EXIT, int);
|
DEFN_SYSCALL1_VOID(SysExit, SYSCALL_EXIT, int);
|
||||||
DEFN_SYSCALL3(int, SysExecVE, SYSCALL_EXEC, const char*, char* const*, char* const*);
|
DEFN_SYSCALL3(int, SysExecVE, SYSCALL_EXEC, const char*, char* const*, char* const*);
|
||||||
DEFN_SYSCALL2(pid_t, SysSForkR, SYSCALL_SFORKR, int, sforkregs_t*);
|
DEFN_SYSCALL2(pid_t, SysTFork, SYSCALL_TFORK, int, tforkregs_t*);
|
||||||
DEFN_SYSCALL0(pid_t, SysGetPID, SYSCALL_GETPID);
|
DEFN_SYSCALL0(pid_t, SysGetPID, SYSCALL_GETPID);
|
||||||
DEFN_SYSCALL0(pid_t, SysGetParentPID, SYSCALL_GETPPID);
|
DEFN_SYSCALL0(pid_t, SysGetParentPID, SYSCALL_GETPPID);
|
||||||
DEFN_SYSCALL3(pid_t, SysWait, SYSCALL_WAIT, pid_t, int*, int);
|
DEFN_SYSCALL3(pid_t, SysWait, SYSCALL_WAIT, pid_t, int*, int);
|
||||||
|
@ -184,16 +184,16 @@ namespace Maxsi
|
||||||
_exit(status);
|
_exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" pid_t sforkr(int flags, sforkregs_t* regs)
|
extern "C" pid_t tfork(int flags, tforkregs_t* regs)
|
||||||
{
|
{
|
||||||
return SysSForkR(flags, regs);
|
return SysTFork(flags, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" pid_t __call_sforkr_with_regs(int flags);
|
extern "C" pid_t __call_tfork_with_regs(int flags);
|
||||||
|
|
||||||
extern "C" pid_t sfork(int flags)
|
extern "C" pid_t sfork(int flags)
|
||||||
{
|
{
|
||||||
return __call_sforkr_with_regs(flags);
|
return __call_tfork_with_regs(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DUAL_FUNCTION(pid_t, fork, Fork, ())
|
DUAL_FUNCTION(pid_t, fork, Fork, ())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2012.
|
||||||
|
|
||||||
This file is part of LibMaxsi.
|
This file is part of LibMaxsi.
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
.globl __call_sforkr_with_regs
|
.globl __call_tfork_with_regs
|
||||||
.type __call_sforkr_with_regs, @function
|
.type __call_tfork_with_regs, @function
|
||||||
__call_sforkr_with_regs:
|
__call_tfork_with_regs:
|
||||||
pushq %rbp
|
pushq %rbp
|
||||||
movq %rsp, %rbp
|
movq %rsp, %rbp
|
||||||
|
|
||||||
# The actual system call expects a struct sforkregs_x64 containing the state
|
# The actual system call expects a struct tforkregs_x64 containing the state
|
||||||
# of each register in the child. Since we create an identical copy, we
|
# of each register in the child. Since we create an identical copy, we
|
||||||
# simply set each member of the structure to our own state. Note that since
|
# simply set each member of the structure to our own state. Note that since
|
||||||
# the stack goes downwards, we create it in the reverse order.
|
# the stack goes downwards, we create it in the reverse order.
|
||||||
|
@ -53,10 +53,10 @@ __call_sforkr_with_regs:
|
||||||
pushq $0 # rax, result of sfork is 0 for the child.
|
pushq $0 # rax, result of sfork is 0 for the child.
|
||||||
pushq $after_fork # rip, child will start execution from here.
|
pushq $after_fork # rip, child will start execution from here.
|
||||||
|
|
||||||
# Call sforkr with a nice pointer to our structure. Note that %rdi contains
|
# Call tfork with a nice pointer to our structure. Note that %rdi contains
|
||||||
# the flag parameter that this function accepted.
|
# the flag parameter that this function accepted.
|
||||||
movq %rsp, %rsi
|
movq %rsp, %rsi
|
||||||
call sforkr
|
call tfork
|
||||||
|
|
||||||
after_fork:
|
after_fork:
|
||||||
# The value in %rax determines whether we are child or parent. There is no
|
# The value in %rax determines whether we are child or parent. There is no
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2012.
|
||||||
|
|
||||||
This file is part of LibMaxsi.
|
This file is part of LibMaxsi.
|
||||||
|
|
||||||
|
@ -24,15 +24,15 @@
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
.globl __call_sforkr_with_regs
|
.globl __call_tfork_with_regs
|
||||||
.type __call_sforkr_with_regs, @function
|
.type __call_tfork_with_regs, @function
|
||||||
__call_sforkr_with_regs:
|
__call_tfork_with_regs:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
|
|
||||||
movl 8(%ebp), %edx # flags parameter, edx need not be preserved.
|
movl 8(%ebp), %edx # flags parameter, edx need not be preserved.
|
||||||
|
|
||||||
# The actual system call expects a struct sforkregs_x86 containing the state
|
# The actual system call expects a struct tforkregs_x86 containing the state
|
||||||
# of each register in the child. Since we create an identical copy, we
|
# of each register in the child. Since we create an identical copy, we
|
||||||
# simply set each member of the structure to our own state. Note that since
|
# simply set each member of the structure to our own state. Note that since
|
||||||
# the stack goes downwards, we create it in the reverse order.
|
# the stack goes downwards, we create it in the reverse order.
|
||||||
|
@ -47,11 +47,11 @@ __call_sforkr_with_regs:
|
||||||
pushl $0 # rax, result of sfork is 0 for the child.
|
pushl $0 # rax, result of sfork is 0 for the child.
|
||||||
pushl $after_fork # rip, child will start execution from here.
|
pushl $after_fork # rip, child will start execution from here.
|
||||||
|
|
||||||
# Call sforkr with a nice pointer to our structure. Note that %edi contains
|
# Call tfork with a nice pointer to our structure. Note that %edi contains
|
||||||
# the flag parameter that this function accepted.
|
# the flag parameter that this function accepted.
|
||||||
pushl %esp
|
pushl %esp
|
||||||
pushl %edx
|
pushl %edx
|
||||||
call sforkr
|
call tfork
|
||||||
|
|
||||||
after_fork:
|
after_fork:
|
||||||
# The value in %eax determines whether we are child or parent. There is no
|
# The value in %eax determines whether we are child or parent. There is no
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2012.
|
||||||
|
|
||||||
This file is part of Sortix.
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
/* TODO: These doesn't belong in this header! */
|
||||||
#define R_OK 4 /* Test for read permission. */
|
#define R_OK 4 /* Test for read permission. */
|
||||||
#define W_OK 2 /* Test for write permission. */
|
#define W_OK 2 /* Test for write permission. */
|
||||||
#define X_OK 1 /* Test for execute permission. */
|
#define X_OK 1 /* Test for execute permission. */
|
||||||
|
@ -43,9 +44,9 @@ __BEGIN_DECLS
|
||||||
you wish to fork certain items simply set the proper flags. Note that since
|
you wish to fork certain items simply set the proper flags. Note that since
|
||||||
flags may be added from time to time, you should use various compound flags
|
flags may be added from time to time, you should use various compound flags
|
||||||
defined below such as SFFORK and SFALL. It can be useful do combine these
|
defined below such as SFFORK and SFALL. It can be useful do combine these
|
||||||
compount flags with bitoperations, for instance "I want traditional fork,
|
compound flags with bit operations, for instance "I want traditional fork,
|
||||||
except share the working dir pointer" is sfork(SFFORK & ~SFCWD). */
|
except share the working dir pointer" is sfork(SFFORK & ~SFCWD). */
|
||||||
#define SFPROC (1<<0) /* Creates child, otherwise affect current process. */
|
#define SFPROC (1<<0) /* Creates child, otherwise affect current task. */
|
||||||
#define SFPID (1<<1) /* Allocates new PID. */
|
#define SFPID (1<<1) /* Allocates new PID. */
|
||||||
#define SFFD (1<<2) /* Fork file descriptor table. */
|
#define SFFD (1<<2) /* Fork file descriptor table. */
|
||||||
#define SFMEM (1<<3) /* Forks address space. */
|
#define SFMEM (1<<3) /* Forks address space. */
|
||||||
|
@ -56,10 +57,11 @@ __BEGIN_DECLS
|
||||||
#define SFCSIG (1<<8) /* Child will have no pending signals, like fork(2). */
|
#define SFCSIG (1<<8) /* Child will have no pending signals, like fork(2). */
|
||||||
|
|
||||||
/* Creates a new thread in this process. Beware that it will share the stack of
|
/* Creates a new thread in this process. Beware that it will share the stack of
|
||||||
the parent thread and that various threading featues may not have been set up
|
the parent thread and that various threading features may not have been set
|
||||||
properly. You should use the standard threading API unless you know what you
|
up properly. You should use the standard threading API unless you know what
|
||||||
are doing; remember that you can always sfork more stuff after the standard
|
you are doing; remember that you can always sfork more stuff after the
|
||||||
threading API returns control to you. */
|
standard threading API returns control to you. This is useful combined with
|
||||||
|
the tfork System call that lets you control the registers of the new task. */
|
||||||
#define SFTHREAD (SFPROC | SFCSIG)
|
#define SFTHREAD (SFPROC | SFCSIG)
|
||||||
|
|
||||||
/* Provides traditional fork(2) behavior; use this instead of the above values
|
/* Provides traditional fork(2) behavior; use this instead of the above values
|
||||||
|
@ -75,15 +77,19 @@ __BEGIN_DECLS
|
||||||
are reserved and must not be set. */
|
are reserved and must not be set. */
|
||||||
#define SFALL ((1<<20)-1)
|
#define SFALL ((1<<20)-1)
|
||||||
|
|
||||||
|
/* This structure tells tfork the initial values of the registers in the new
|
||||||
|
task. It is ignored if no new task is created. sfork works by recording its
|
||||||
|
own state into such a structure and calling tfork. Note that this structure
|
||||||
|
is highly platform specific, portable code should use the standard threading
|
||||||
|
facilities combined with sfork if possible. */
|
||||||
#ifdef PLATFORM_X86
|
#ifdef PLATFORM_X86
|
||||||
typedef struct sforkregs_x86 sforkregs_t;
|
typedef struct tforkregs_x86 tforkregs_t;
|
||||||
#elif defined(PLATFORM_X64)
|
#elif defined(PLATFORM_X64)
|
||||||
typedef struct sforkregs_x64 sforkregs_t;
|
typedef struct tforkregs_x64 tforkregs_t;
|
||||||
#else
|
#else
|
||||||
#warning No sforkresgs_cpu structure declared
|
#warning No tforkregs_cpu structure declared
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
#define SYSCALL_KERNELINFO 48
|
#define SYSCALL_KERNELINFO 48
|
||||||
#define SYSCALL_PREAD 49
|
#define SYSCALL_PREAD 49
|
||||||
#define SYSCALL_PWRITE 50
|
#define SYSCALL_PWRITE 50
|
||||||
#define SYSCALL_SFORKR 51
|
#define SYSCALL_TFORK 51
|
||||||
#define SYSCALL_TCGETWINSIZE 52
|
#define SYSCALL_TCGETWINSIZE 52
|
||||||
#define SYSCALL_RAISE 53
|
#define SYSCALL_RAISE 53
|
||||||
#define SYSCALL_MAX_NUM 54 /* index of highest constant + 1 */
|
#define SYSCALL_MAX_NUM 54 /* index of highest constant + 1 */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2012.
|
||||||
|
|
||||||
This file is part of Sortix.
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
struct sforkregs_x64
|
struct tforkregs_x64
|
||||||
{
|
{
|
||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
uint64_t rax;
|
uint64_t rax;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
struct sforkregs_x86
|
struct tforkregs_x86
|
||||||
{
|
{
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
uint32_t eax;
|
uint32_t eax;
|
||||||
|
|
|
@ -661,11 +661,11 @@ namespace Sortix
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t SysSForkR(int flags, sforkregs_t* regs)
|
pid_t SysTFork(int flags, tforkregs_t* regs)
|
||||||
{
|
{
|
||||||
if ( Signal::IsPending() ) { Error::Set(EINTR); return -1; }
|
if ( Signal::IsPending() ) { Error::Set(EINTR); return -1; }
|
||||||
|
|
||||||
// TODO: Properly support sforkr(2).
|
// TODO: Properly support tfork(2).
|
||||||
if ( flags != SFFORK ) { Error::Set(ENOSYS); return -1; }
|
if ( flags != SFFORK ) { Error::Set(ENOSYS); return -1; }
|
||||||
|
|
||||||
CPU::InterruptRegisters cpuregs;
|
CPU::InterruptRegisters cpuregs;
|
||||||
|
@ -832,7 +832,7 @@ namespace Sortix
|
||||||
void Process::Init()
|
void Process::Init()
|
||||||
{
|
{
|
||||||
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE);
|
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE);
|
||||||
Syscall::Register(SYSCALL_SFORKR, (void*) SysSForkR);
|
Syscall::Register(SYSCALL_TFORK, (void*) SysTFork);
|
||||||
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
||||||
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
||||||
Syscall::Register(SYSCALL_EXIT, (void*) SysExit);
|
Syscall::Register(SYSCALL_EXIT, (void*) SysExit);
|
||||||
|
|
|
@ -147,7 +147,7 @@ namespace Sortix
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
||||||
const sforkregs_t* requested);
|
const tforkregs_t* requested);
|
||||||
Process* CurrentProcess();
|
Process* CurrentProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Sortix
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
||||||
const sforkregs_t* requested)
|
const tforkregs_t* requested)
|
||||||
{
|
{
|
||||||
Maxsi::Memory::Set(regs, 0, sizeof(*regs));
|
Maxsi::Memory::Set(regs, 0, sizeof(*regs));
|
||||||
regs->rip = requested->rip;
|
regs->rip = requested->rip;
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Sortix
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
void InitializeThreadRegisters(CPU::InterruptRegisters* regs,
|
||||||
const sforkregs_t* requested)
|
const tforkregs_t* requested)
|
||||||
{
|
{
|
||||||
Maxsi::Memory::Set(regs, 0, sizeof(*regs));
|
Maxsi::Memory::Set(regs, 0, sizeof(*regs));
|
||||||
regs->eip = requested->eip;
|
regs->eip = requested->eip;
|
||||||
|
|
Loading…
Reference in New Issue