linux內核之系統調用nanosleep與pause()


nanosleep()使得進程進入睡眠狀態,指定時候后喚醒進程,sleep()基於其實現
   
   
   
           
  1. asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)//第一個指針rqtp指向給定所需睡眠時間的數據結構;第二個指針rmtp,指向返回剩余時間的數據結構,可能收到信號提前喚醒.
  2. {
  3. struct timespec t;//tv_sec單位秒,tv_nsec單位好微妙
  4. unsigned long expire;
  5. if(copy_from_user(&t, rqtp, sizeof(struct timespec)))//所需睡眠時間從用戶空間復制到內核空間
  6. return -EFAULT;
  7. if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
  8. return -EINVAL;
  9. if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
  10. current->policy != SCHED_OTHER)//由於時鍾中斷只能達到10毫秒的精度,如果要求睡眠的時間小於2毫秒,而要求睡眠的進程又是個實時要求的進程,那就不能真的讓這個進程進入睡眠,因為那樣有可能10毫秒以后才能將其喚醒,對於實時進程來說是不能接受的
  11. {
  12. /*
  13. * Short delay requests up to 2 ms will be handled with
  14. * high precision by a busy wait for all real-time processes.
  15. *
  16. * Its important on SMP not to do this holding locks.
  17. */
  18. udelay((t.tv_nsec + 999) / 1000);//延遲兩秒
  19. return 0;
  20. }
  21. expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);//將數據結構t中的數值換算成時鍾中斷的次數<span style="white-space:pre"> </span>
  22. current->state = TASK_INTERRUPTIBLE;//將當期進程的狀態設置為TASK_INTERRUPTIBLE
  23. expire = schedule_timeout(expire);//讓當期進程睡眠給定的時間;返回剩余的時鍾中斷次數,如果沒有,返回0
  24. if (expire) {
  25. if (rmtp) {
  26. jiffies_to_timespec(expire, &t);//剩余的時鍾中斷次數轉換成數據結構t的數值
  27. if (copy_to_user(rmtp, &t, sizeof(struct timespec)))//剩余時間從內核空間復制到用戶空間
  28. return -EFAULT;
  29. }
  30. return -EINTR;
  31. }
  32. return 0;
  33. }


pause()實現,只有信號才可以喚醒
   
   
   
           
  1. asmlinkage int sys_pause(void)
  2. {
  3. current->state = TASK_INTERRUPTIBLE;//設置為睡眠狀態
  4. schedule();//schdule運行調度
  5. return -ERESTARTNOHAND;
  6. }






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM