signal (part 2) sigpending
This commit is contained in:
@@ -84,6 +84,18 @@ struct sig_handler {
|
||||
struct k_sigaction action[_NSIG];
|
||||
};
|
||||
|
||||
struct sig_pending {
|
||||
struct list_head list;
|
||||
sigset_t sigmask;
|
||||
// TODO: siginfo
|
||||
};
|
||||
|
||||
struct sig_shared {
|
||||
ihk_spinlock_t lock;
|
||||
ihk_atomic_t use;
|
||||
struct list_head sigpending;
|
||||
};
|
||||
|
||||
typedef void pgio_func_t(void *arg);
|
||||
|
||||
struct process {
|
||||
@@ -110,10 +122,10 @@ struct process {
|
||||
|
||||
int tid;
|
||||
sigset_t sigmask;
|
||||
int signal;
|
||||
// sigset_t sigpend;
|
||||
ihk_spinlock_t sigpendinglock;
|
||||
struct list_head sigpending;
|
||||
struct sig_shared *sigshared;
|
||||
struct sig_handler *sighandler;
|
||||
// ihk_mc_kernel_context_t sigctx;
|
||||
char sigstack[512]; // TODO: 1. move to user stack
|
||||
// TODO: 2. backup FR and MMX regs
|
||||
unsigned long sigrc; // return code of rt_sigreturn (x86_64: rax reg.)
|
||||
|
||||
@@ -83,9 +83,20 @@ struct process *create_process(unsigned long user_pc)
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
return NULL;
|
||||
}
|
||||
proc->sigshared = kmalloc(sizeof(struct sig_shared), IHK_MC_AP_NOWAIT);
|
||||
if(!proc->sigshared){
|
||||
ihk_mc_free_pages(proc->sighandler, KERNEL_STACK_NR_PAGES);
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
return NULL;
|
||||
}
|
||||
memset(proc->sighandler, '\0', sizeof(struct sig_handler));
|
||||
ihk_atomic_set(&proc->sighandler->use, 1);
|
||||
ihk_mc_spinlock_init(&proc->sighandler->lock);
|
||||
ihk_atomic_set(&proc->sigshared->use, 1);
|
||||
ihk_mc_spinlock_init(&proc->sigshared->lock);
|
||||
INIT_LIST_HEAD(&proc->sigshared->sigpending);
|
||||
ihk_mc_spinlock_init(&proc->sigpendinglock);
|
||||
INIT_LIST_HEAD(&proc->sigpending);
|
||||
|
||||
ihk_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||
((char *)proc) +
|
||||
@@ -133,6 +144,12 @@ struct process *clone_process(struct process *org, unsigned long pc,
|
||||
proc->sighandler = org->sighandler;
|
||||
ihk_atomic_inc(&org->sighandler->use);
|
||||
|
||||
proc->sigshared = org->sigshared;
|
||||
ihk_atomic_inc(&org->sigshared->use);
|
||||
|
||||
ihk_mc_spinlock_init(&proc->sigpendinglock);
|
||||
INIT_LIST_HEAD(&proc->sigpending);
|
||||
|
||||
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||
proc->spin_sleep = 0;
|
||||
|
||||
@@ -1339,9 +1356,23 @@ void hold_process(struct process *proc)
|
||||
|
||||
void destroy_process(struct process *proc)
|
||||
{
|
||||
struct sig_pending *pending;
|
||||
struct sig_pending *next;
|
||||
if(ihk_atomic_dec_and_test(&proc->sighandler->use)){
|
||||
kfree(proc->sighandler);
|
||||
}
|
||||
if(ihk_atomic_dec_and_test(&proc->sigshared->use)){
|
||||
list_for_each_entry_safe(pending, next, &proc->sigshared->sigpending, list){
|
||||
list_del(&pending->list);
|
||||
kfree(pending);
|
||||
}
|
||||
list_del(&proc->sigshared->sigpending);
|
||||
kfree(proc->sigshared);
|
||||
}
|
||||
list_for_each_entry_safe(pending, next, &proc->sigpending, list){
|
||||
list_del(&pending->list);
|
||||
kfree(pending);
|
||||
}
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
}
|
||||
|
||||
|
||||
@@ -1075,7 +1075,7 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
||||
const sigset_t *set = (const sigset_t *)ihk_mc_syscall_arg1(ctx);
|
||||
sigset_t *oldset = (sigset_t *)ihk_mc_syscall_arg2(ctx);
|
||||
struct process *proc = cpu_local_var(current);
|
||||
int irqstate;
|
||||
int flag;
|
||||
|
||||
if(set &&
|
||||
how != SIG_BLOCK &&
|
||||
@@ -1083,7 +1083,7 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
||||
how != SIG_SETMASK)
|
||||
return -EINVAL;
|
||||
|
||||
irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
||||
flag = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
||||
if(oldset)
|
||||
oldset->__val[0] = proc->sigmask.__val[0];
|
||||
if(set){
|
||||
@@ -1099,12 +1099,38 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigpending)
|
||||
{
|
||||
int flag;
|
||||
struct sig_pending *pending;
|
||||
struct list_head *head;
|
||||
ihk_spinlock_t *lock;
|
||||
__sigset_t w = 0;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
sigset_t *set = (sigset_t *)ihk_mc_syscall_arg0(ctx);
|
||||
|
||||
lock = &proc->sigshared->lock;
|
||||
head = &proc->sigshared->sigpending;
|
||||
flag = ihk_mc_spinlock_lock(lock);
|
||||
list_for_each_entry(pending, head, list){
|
||||
w |= pending->sigmask.__val[0];
|
||||
}
|
||||
ihk_mc_spinlock_unlock(lock, flag);
|
||||
|
||||
lock = &proc->sigpendinglock;
|
||||
head = &proc->sigpending;
|
||||
flag = ihk_mc_spinlock_lock(lock);
|
||||
list_for_each_entry(pending, head, list){
|
||||
w |= pending->sigmask.__val[0];
|
||||
}
|
||||
ihk_mc_spinlock_unlock(lock, flag);
|
||||
|
||||
set->__val[0] = w;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user