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:
Jonas 'Sortie' Termansen 2012-08-05 17:35:19 +02:00
parent 111e359482
commit 755e855c08
12 changed files with 48 additions and 42 deletions

View File

@ -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);

View File

@ -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, ())

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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();
} }

View File

@ -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;

View File

@ -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;