操作系统课程设计之消息函数的分析论文(编辑修改稿)内容摘要:
goto out_err。 } len = alen。 14 src = ((char*)src)+alen。 pseg = amp。 msgnext。 while(len 0) { struct msg_msgseg* seg。 alen = len。 if(alen DATALEN_SEG) alen = DATALEN_SEG。 seg = (struct msg_msgseg *) kmalloc (sizeof(*seg) + alen, GFP_KERNEL)。 if(seg==NULL) { err=ENOMEM。 goto out_err。 } *pseg = seg。 segnext = NULL。 if(copy_from_user (seg+1, src, alen)) { err = EFAULT。 goto out_err。 } pseg = amp。 segnext。 len = alen。 src = ((char*)src)+alen。 } return msg。 out_err: free_msg(msg)。 return ERR_PTR(err)。 } static int store_msg(void* dest, struct msg_msg* msg, int len)/*存储消息 */ { int alen。 struct msg_msgseg *seg。 15 alen = len。 if(alen DATALEN_MSG) alen = DATALEN_MSG。 if(copy_to_user (dest, msg+1, alen)) return 1。 len = alen。 dest = ((char*)dest)+alen。 seg = msgnext。 while(len 0) { alen = len。 if(alen DATALEN_SEG) alen = DATALEN_SEG。 if(copy_to_user (dest, seg+1, alen)) return 1。 len = alen。 dest = ((char*)dest)+alen。 seg=segnext。 } return 0。 } static inline void ss_add(struct msg_queue* msq, struct msg_sender* mss)/*将一个消息添加到消息队 列尾部 */ { msstsk=current。 currentstate=TASK_INTERRUPTIBLE。 list_add_tail(amp。 msslist,amp。 msqq_senders)。 } static inline void ss_del(struct msg_sender* mss)/*删除一个发送者的消息 */ { if(mss != NULL) list_del(amp。 msslist)。 } static void ss_wakeup(struct list_head* h, int kill)/*唤醒一个消息 */ 16 { struct list_head *tmp。 tmp = hnext。 while (tmp != h) { struct msg_sender* mss。 mss = list_entry(tmp,struct msg_sender,list)。 tmp = tmpnext。 if(kill) mss=NULL。 wake_up_process(msstsk)。 } } static void expunge_all(struct msg_queue* msq, int res) /*去除所有消息 */ { struct list_head *tmp。 tmp = msq。 while (tmp != amp。 msqq_receivers) { struct msg_receiver* msr。 msr = list_entry(tmp,struct msg_receiver,r_list)。 tmp = tmpnext。 msrr_msg = ERR_PTR(res)。 wake_up_process(msrr_tsk)。 } } 函数 sys_msgget 的分析 代码及注释 asmlinkage int sys_msgget (key_t key, int msgflg) { int id, ret = EPERM。 struct msqid_ds *msq。 lock_kernel()。 //锁内核 if (key == IPC_PRIVATE) //判断调用的参数 key中是否指定了 IPC_PRIVATE 即 17 判断调用者需要一个新队列; ret = newque(key, msgflg)。 //如果调用的参数 key 中指定了 IPC_PRIVATE则调用 newque 函数新建一个队列,并返回新建队列的序列号 ID else if ((id = findkey (key)) == 1) { //如果调用的参数 key 中没有指定IPC_PRIVATE,则调用 findkey 函数来搜索一下是否有这个键值指定的队列,并用把函数的返回值赋给参数 ID if (!(msgflg amp。 IPC_CREAT)) //如果 key 键值未被使用,则判断调用的参数msgflg 中是否设置了 IPC_CREAT(00001000)位 ret = ENOENT。 //如果调用的参数 msgflg 中设置了 IPC_CREAT(00001000)位,则返回错误,错误类型 ENOENT(No such file or directory) else ret = newque(key, msgflg)。 //如果调用的参数 msgflg 中没有设置IPC_CREAT(00001000)位 ,则调用 newque 函数新建一个队列,并返回新建队列的序列号 ID } else if (msgflg amp。 IPC_CREAT amp。 amp。 msgflg amp。 IPC_EXCL) { //key 这个键值已被使用。 判断调用的参数 msgflg 是 否 标 志 了 IPC_CREAT(00001000) 位和IPC_EXCL(00002020)位 ret = EEXIST。 //如果调用的参数 msgflg 中既设置了 IPC_CREAT(00001000)位,又设置了 IPC_EXCL(00002020)位,则返回错误,错误类型 EEXIST(File exists) } else { //如果有 key 这个键值指定的队列,则使用这个键值所指明的队列作为当前消息队列 msq = msgque[id]。 //把用 findkey 返回的这个键值所指明的队列指针赋给当前消息队列 if (msq == IPC_UNUSED || msq == IPC_NOID) //判断当前消息队列 (msgque)项目是否被设置 IPC_UNUSED 或 IPC_NOID ret = EIDRM。 //如果当前消息队列 (msgque)项目指向被设置 IPC_UNUSED或被设置 IPC_NOID,则该地方没有消息队列 (msgque)或者调用者缺少访问它的权限返回错误,错误类型 EACCES(Identifier removed) else if (ipcperms(amp。 msqmsg_perm, msgflg)) //如果当前消息队列指针指既没有向 IPC_UNUSED 又没有指向 IPC_NOID,判断是否允许访问进程间通讯资源 IPC ret = EACCES。 //如果返回值非 0,则不允许访问进程间通讯资源 IPC,返回错误,错误类型 EACCES(Permission denied) else ret = (unsigned int) msq * MSGMNI + id。 //如果返回 18 值 ID 为 0,则允许访问进程间通讯资源 IPC,序列编号和 msgque 下标被编码在返回值里。 这个编号将成为调用者要传递给 sys_msgsnd、 sys_msgrcv,以及 sys_msgctl的 msgid 参数。 } unlock_kernel()。 //释放内核 return ret。 //返回 ret 值 } 流程图: 19 定位消息队列函数 findkey 的分析: static int findkey (key_t key) //定位具有给定键值的消息队列 { int id。 struct msqid_ds *msq。 for (id = 0。 id = max_msqid。 id++) //开始对消息队列 (msgque)里所有可能被占据的消息单元进行循环搜索, max_msqid 表示消息队列里被占据的最大数组元素 { while ((msq = msgque[id]) == IPC_NOID) //如果当前数组元素值是IPC_NOID,那么就会在那里创建一个消息队列 interruptible_sleep_on (amp。 msg_lock)。 //这个新创建的消息队列可能具有正在被搜索的键值,调用 interruptible_sleep_on 函数使 findkey 函数等待该队列的创建工作完成 if (msq == IPC_UNUSED) //判断该消息队列 (msgque)的项目是否未被使用 continue。 //如果该消息队列 (msgque)的项目未被使用,那么该消息队列 (msgque)明显不具有匹配的键值 if (key == msq) //判断键值是否匹配 return id。 //如果匹配的键值被找到,则返回相应的数组下标 } return 1。 //循环结束,但是仍然未找到相互匹配的键值,则返回值- 1 以表示失败 } 流程图: 20 创建消息队列函数 newque 的分析: static int newque (key_t key, int msgflg) //定位 一个没有使用的 msgque项,并尝试在那里创建一个新的消息队列 { int id。 /* 定义一个局部变量用于循环搜索消息队列 */ struct msqid_ds *msq。 struct ipc_perm *ipcp。 for (id = 0。 id MSGMNI。 id++) //循环对消息队列进行搜索 21 if (msgque[id] == IPC_UNUSED) { //判断消息队列中是否有未使用的指针 msgque[id] = (struct msqid_ds *) IPC_NOID。 //如果找到了未使用的 msgque 项,就用 IPC_NOID 来标记它 goto found。 //跳转到 found 处进行初始化设置 } return ENOSPC。 //如果循环结束但是消息队列 (msgque)中没有未使用的指针,则返回错误,错误类型 ENOSPC(No space left on device)表示没有剩余的空间 found: //对未使用的这个指针进行初始化设置 msq = (struct msqid_ds *) kmalloc (sizeof (*msq), GFP_KERNEL)。 //调用 kmalloc 函数分配一个 struct msqid_ds 来代表一个新的队列 if (!msq) { //分配失败 msgque[id] = (struct msqid_ds *) IPC_UNUSED。 //如果分配失败,该消息队列 (msgque)项目被设置回 IPC_UNUSED 标志 wake_up (amp。 msg_lock)。 //一旦发现有 IPC_NOID 就激活任何已经休眠的findkey return ENOMEM。 //分配失败,则返回错误,错误类型 ENOMEM(Out of memory)超出内存界限 } //分配成功,初始化新的消息队列 ipcp = amp。 msqmsg_perm。 ipcpmode = (msgflg am。操作系统课程设计之消息函数的分析论文(编辑修改稿)
相关推荐
脂,其中用得最多 的是对水中有机污染物和臭味有较强吸附作用的疏水性物质 — 活性炭。 活性炭( AC)具有丰富微孔结构和表面憎水性,其对水中某些污染物有极强的亲和力,是有效的去除方法。 美国大多数水处理工作者认为,活性炭吸附是从水中去除多种有机物的“最佳实用技术”,可作为其它深度处理技术的一个参照标准。 活性炭可经济有效的去除嗅、味、色度、氯化有机物、农药、放射性污染物及其它人工合成有机物。
打造阳光旅游贡献力量。 攀枝花学院本科毕业论文 一、绪 论 2 (三)研究内容和方法 研究内容 一是明确 攀枝 花早春 批把产业发展的 现状及存在的问题;二是对攀枝花早春枇杷产业进行 SWOT 分析;三是提出具体的策略 措施。 研究方法 ( 1)调查研究法 为 了系统地 了解 攀枝花早春枇杷 的 现状 , 我 通过深入 基地 、公司,与相关人员座谈和 沟通 ,充分 地 了解 了攀枝花早春
填料深度( m) 填料 设计值 检测值 1 DK20+ 涵洞 孔位 1 级配碎石 孔位 2 2 DK23+500 涵洞 孔位 1 级配碎石 孔位 2 3 DK25+220 涵洞 孔位 1 级配碎石 孔位 2 4 DK27+554 涵洞 孔位 1 级配碎石 孔位 2 5 DK29+638 涵洞 孔位 1 级配碎石 孔位 2 14 基底地基承载力检测结果 表 10 涵洞 过渡段
= Tn/9550 式 2— 3 由光杠的传动直径 D,以及收线盘的直径 D1 及转速 30r/min,得: n=π D1 n/π d =( 600 30)/( 60) =300r/min 其中 Tn = 105 查表得齿轮啮合效率η 1=, V带传动效率η 2=,滚动轴承效率η 3=,链传动效率η 4=。 总效率η η =η 1*η 1*η 2*η 3 *η 3 *η 3*η 4 = =
………… 9( 可行性研究报告项目建议书营销策划商业策划书组织设计公务员考试可行性分析报告环境影响报告书连锁店加盟店运营手册作业指导书招标投标招聘绩效管理薪酬管理物业管理经营企划商务礼仪创业金点子销售指 南营销创新经济管理选拔企业文化项目管理 )经济管理市场分析国内外市场情况预测……………………竞争力分析…………资金筹措投资估算效益分析 02020 04 10某科技公司
( 330) 因此小孔节流产生的局部阻尼力为 : .39。 3 2 2 2 2 21 ( ) ( ) / 12 8 ( )f ni ni so fP pA d d d x t A ( 331) 式中 : 39。 A 为活塞的截面积, 2m。 减震液流过补偿阀的流动可看作环形 缝隙的流动,环形缝隙的进出口端压差与流量之间的关系为 : 39。 312