📄 4.html
字号:
{<br>
return current->euid;<br>
}<br>
int sys_getgid(void)<br>
{<br>
return current->gid;<br>
}<br>
int sys_getegid(void)<br>
{<br>
return current->egid;<br>
}<br>
int sys_nice(long increment)<br>
{<br>
if (current->priority-increment>0)<br>
current->priority -= increment;<br>
return 0;<br>
}<br>
int sys_signal(long signal,long addr,long restorer)<br>
{<br>
long i;<br>
switch (signal) {<br>
case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:<br>
case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:<br>
case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:<br>
case SIGCHLD:<br>
i=(long) current->sig_fn[signal-1];<br>
current->sig_fn[signal-1] = (fn_ptr) addr;<br>
current->sig_restorer = (fn_ptr) restorer;<br>
return i;<br>
default: return -1;<br>
}<br>
}<br>
void sched_init(void)<br>
{<br>
int i;<br>
struct desc_struct * p;<br>
set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));@@init task tss<br>
set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));@@init ldt<br>
p = gdt+2+FIRST_TSS_ENTRY;<br>
for(i=1;i task[i] = NULL;<br>
p->a=p->b=0;<br>
p++;<br>
p->a=p->b=0;<br>
p++;<br>
}<br>
ltr(0); @@调入task 0的tss<br>
lldt(0); @@调入task 0的ldt<br>
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */<br>
outb_p(LATCH & 0xff , 0x40); /* LSB */<br>
outb(LATCH >> 8 , 0x40); /* MSB */<br>
set_intr_gate(0x20,&timer_interrupt); @@irq 0 时钟中断<br>
outb(inb_p(0x21)&~0x01,0x21);<br>
set_system_gate(0x80,&system_call);<br>
}<p>
<p>
<br>
<center><A HREF="#Content">[目录]</A></center>
<hr><br><A NAME="I410" ID="I410"></A><center><b><font size=+2>进程信号队列</font></b></center><br>
每个进程具有一个sigpending结构所描述的信号队列,它有3个成员,head指向第一个sigqueue成员,tail指向最末的sigqueue成员的next指针,signal描述了此队列中的信号集.<p>
static int<br>
send_signal(int sig, struct siginfo *info, struct sigpending *signals);<br>
将信号sig和对应的消息结构info添加到信号队列signal中.<br>
static int<br>
collect_signal(int sig, struct sigpending *list, siginfo_t *info);<br>
返回信号sig在队列list中的信息info.<p>
<br>
struct task_struct {<br>
...<br>
struct sigpending pending;<br>
...<br>
};<br>
struct sigpending {<br>
struct sigqueue *head, **tail;<br>
sigset_t signal;<br>
};<br>
struct sigqueue {<br>
struct sigqueue *next;<br>
siginfo_t info;<br>
};<br>
// kernel/signal.c<br>
static int<br>
send_signal(int sig, struct siginfo *info, struct sigpending *signals)<br>
{<br>
struct sigqueue * q = NULL;<br>
/* Real-time signals must be queued if sent by sigqueue, or<br>
some other real-time mechanism. It is implementation<br>
defined whether kill() does so. We attempt to do so, on<br>
the principle of least surprise, but since kill is not<br>
allowed to fail with EAGAIN when low on memory we just<br>
make sure at least one signal gets delivered and don't<br>
pass on the info struct. */<p>
if (atomic_read(&nr_queued_signals) < max_queued_signals) {<br>
q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);<br>
}<br>
// nr_queued_signals和max_queued_signals用来限制全局sigqueue成员的数目<br>
if (q) {<br>
atomic_inc(&nr_queued_signals);<br>
q->next = NULL;<br>
*signals->tail = q;<br>
signals->tail = &q->next; tail总是指向最末的信号成员的next指针 switch ((unsign<br>
ed long) info)<br>
{<br>
case 0:<br>
// info参数如果为0,表示信号来源于当前用户进程 q->info.si_signo =<br>
sig;<br>
q->info.si_errno = 0;<br>
q->info.si_code = SI_USER;<br>
q->info.si_pid = current->pid;<br>
q->info.si_uid = current->uid;<br>
break;<br>
case 1:<br>
// info参数如果为1,表示信号来源于内核本身 q->info.si_signo = sig;<br>
q->info.si_errno = 0;<br>
q->info.si_code = SI_KERNEL;<br>
q->info.si_pid = 0;<br>
q->info.si_uid = 0;<br>
break;<br>
default:<br>
// 否则从info指针中拷贝信号<br>
copy_siginfo(&q->info, info);<br>
break;<br>
}<br>
}<br>
else if (sig >= SIGRTMIN && info && (unsigned long)info != 1 && info-><br>
si_code != SI_USER)<br>
{<br>
; 如果该信号是内核发出的实时信号,就返回错误码<br>
/*<br>
* Queue overflow, abort. We may abort if the signal was rt<br>
* and sent by user using something other than kill().<br>
*/<br>
return -EAGAIN;<br>
}<br>
sigaddset(&signals->signal, sig); 将sig号标记在队列的信号集上<br>
return 0;<br>
}<br>
static int<br>
collect_signal(int sig, struct sigpending *list, siginfo_t *info)<br>
{<br>
if (sigismember(&list->signal, sig)) {<br>
/* Collect the siginfo appropriate to this signal. */ struct sigqueue *q, **<br>
pp;<br>
pp = &list->head; pp指向第一个信号成员的next指针<br>
while ((q = *pp) != NULL) {<br>
if (q->info.si_signo == sig) goto found_it;<br>
pp = &q->next;<br>
}<br>
/* Ok, it wasn't in the queue. We must have<br>
been out of queue space. So zero out the<br>
info.<br>
*/<br>
sigdelset(&list->signal, sig);<br>
info->si_signo = sig;<br>
info->si_errno = 0;<br>
info->si_code = 0;<br>
info->si_pid = 0;<br>
info->si_uid = 0;<br>
return 1;<br>
found_it:<br>
// 将找到信号成员从信号队列中删除<br>
if ((*pp = q->next) == NULL)<br>
list->tail = pp;<br>
/* Copy the sigqueue information and free the queue entry */<br>
copy_siginfo(info, &q->info);<br>
kmem_cache_free(sigqueue_cachep,q);<br>
atomic_dec(&nr_queued_signals);<br>
/* Non-RT signals can exist multiple times.. */<br>
if (sig >= SIGRTMIN) {<br>
while ((q = *pp) != NULL) {<br>
if (q->info.si_signo == sig) goto found_another;<br>
pp = &q->next;<br>
}<br>
}<br>
sigdelset(&list->signal, sig);<br>
found_another:<br>
return 1;<br>
}<br>
return 0;<br>
}<p>
<p>
<p>
<center><A HREF="#Content">[目录]</A></center>
<hr><br><A NAME="I411" ID="I411"></A><center><b><font size=+2>SMP</font></b></center><br>
多处理机系统正在变得越来越普通。尽管大多数用户空间代码仍将完美地运行,而且有些情况下不需要增加额外的代码就能利用SMP特性的优势,但是内核空间代码必须编写成具备“SMP意识”且是“SMP安全的”。以下几段文字解释如何去做。<p>
问题<p>
当有多个CPU时,同样的代码可能同时在两个或多个CPU上执行。这在如下所示用于初始化某个图像设备的例程中可能会出问题。<br>
void init_hardware(void)<br>
{<br>
outb(0x1, hardware_base + 0x30);<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -