⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4.html

📁 介绍linux下文件和设备编程
💻 HTML
📖 第 1 页 / 共 5 页
字号:
int sys_getgid(void)<br>{<br>return current-&gt;gid;<br>}<br>int sys_getegid(void)<br>{<br>return current-&gt;egid;<br>}<br>int sys_nice(long increment)<br>{<br>if (current-&gt;priority-increment&gt;0)<br>current-&gt;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-&gt;sig_fn[signal-1];<br>current-&gt;sig_fn[signal-1] = (fn_ptr) addr;<br>current-&gt;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,&amp;(init_task.task.tss));@@init task tss<br>set_ldt_desc(gdt+FIRST_LDT_ENTRY,&amp;(init_task.task.ldt));@@init ldt<br>p = gdt+2+FIRST_TSS_ENTRY;<br>for(i=1;i task[i] = NULL;<br>p-&gt;a=p-&gt;b=0;<br>p++;<br>p-&gt;a=p-&gt;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 &amp; 0xff , 0x40); /* LSB */<br>outb(LATCH &gt;&gt; 8 , 0x40); /* MSB */<br>set_intr_gate(0x20,&amp;timer_interrupt); @@irq 0 时钟中断<br>outb(inb_p(0x21)&amp;~0x01,0x21);<br>set_system_gate(0x80,&amp;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>&nbsp;&nbsp;&nbsp; 每个进程具有一个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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigpending pending;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>};<br>struct sigpending {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *head, **tail;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigset_t signal;<br>};<br>struct sigqueue {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; siginfo_t info;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>// kernel/signal.c<br>static int<br>send_signal(int sig, struct siginfo *info, struct sigpending *signals)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue * q = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp; /* Real-time signals must be queued if sent by sigqueue, or<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; some other real-time mechanism.&nbsp; It is implementation<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defined whether kill() does so.&nbsp; We attempt to do so, on<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the principle of least surprise, but since kill is not<br>&nbsp;&nbsp;&nbsp;&nbsp; allowed to fail with EAGAIN when low on memory we just<br>&nbsp;&nbsp;&nbsp;&nbsp; make sure at least one signal gets delivered and don't<br>&nbsp;&nbsp;&nbsp;&nbsp; pass on the info struct.&nbsp; */<p>&nbsp;&nbsp;&nbsp; if (atomic_read(&amp;nr_queued_signals) &lt; max_queued_signals) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; // nr_queued_signals和max_queued_signals用来限制全局sigqueue成员的数目<br>&nbsp;&nbsp;&nbsp; if (q) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic_inc(&amp;nr_queued_signals);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;next = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *signals-&gt;tail = q;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signals-&gt;tail = &amp;q-&gt;next; tail总是指向最末的信号成员的next指针&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch ((unsign<br>ed long) info)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // info参数如果为0,表示信号来源于当前用户进程&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_signo =<br>sig;<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_errno = 0;<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_code = SI_USER;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_pid = current-&gt;pid;<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_uid = current-&gt;uid;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // info参数如果为1,表示信号来源于内核本身&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_signo = sig;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_errno = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_code = SI_KERNEL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;info.si_pid = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_uid = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 否则从info指针中拷贝信号<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy_siginfo(&amp;q-&gt;info, info);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (sig &gt;= SIGRTMIN &amp;&amp; info &amp;&amp; (unsigned long)info != 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &amp;&amp; info-&gt;<br>si_code != SI_USER)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 如果该信号是内核发出的实时信号,就返回错误码<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Queue overflow, abort.&nbsp; We may abort if the signal was rt<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * and sent by user using something other than kill().<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EAGAIN;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigaddset(&amp;signals-&gt;signal, sig); 将sig号标记在队列的信号集上<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br>static int<br>collect_signal(int sig, struct sigpending *list, siginfo_t *info)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sigismember(&amp;list-&gt;signal, sig)) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Collect the siginfo appropriate to this signal.&nbsp; */&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *q, **<br>pp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pp = &amp;list-&gt;head; pp指向第一个信号成员的next指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((q = *pp) != NULL) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (q-&gt;info.si_signo == sig)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto found_it;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pp = &amp;q-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Ok, it wasn't in the queue.&nbsp; We must have<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; been out of queue space.&nbsp; So zero out the<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigdelset(&amp;list-&gt;signal, sig);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_signo = sig;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_errno = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_code = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_pid = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_uid = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>&nbsp;&nbsp; found_it:<br>&nbsp;&nbsp; // 将找到信号成员从信号队列中删除<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((*pp = q-&gt;next) == NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list-&gt;tail = pp;<br>&nbsp; /* Copy the sigqueue information and free the queue entry */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy_siginfo(info, &amp;q-&gt;info);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kmem_cache_free(sigqueue_cachep,q);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic_dec(&amp;nr_queued_signals);<br>&nbsp; /* Non-RT signals can exist multiple times.. */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sig &gt;= SIGRTMIN) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((q = *pp) != NULL) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (q-&gt;info.si_signo == sig)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; goto found_another;<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; pp = &amp;q-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigdelset(&amp;list-&gt;signal, sig);<br>&nbsp;&nbsp;&nbsp; found_another:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp; 多处理机系统正在变得越来越普通。尽管大多数用户空间代码仍将完美地运行,而且有些情况下不需要增加额外的代码就能利用SMP特性的优势,但是内核空间代码必须编写成具备“SMP意识”且是“SMP安全的”。以下几段文字解释如何去做。<p>问题<p>&nbsp;&nbsp;&nbsp; 当有多个CPU时,同样的代码可能同时在两个或多个CPU上执行。这在如下所示用于初始化某个图像设备的例程中可能会出问题。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void init_hardware(void)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outb(0x1, hardware_base + 0x30);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outb(0x2, hardware_base + 0x30);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outb(0x3, hardware_base + 0x30);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outb(0x4, hardware_base + 0x30);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -