Fork me on GitHub

root/kernel/syscalls/nanosleep.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_nanosleep

   1 /*
   2  * fiwix/kernel/syscalls/nanosleep.c
   3  *
   4  * Copyright 2018, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/asm.h>
   9 #include <fiwix/fs.h>
  10 #include <fiwix/time.h>
  11 #include <fiwix/timer.h>
  12 #include <fiwix/process.h>
  13 #include <fiwix/sched.h>
  14 #include <fiwix/sleep.h>
  15 #include <fiwix/errno.h>
  16 
  17 #ifdef __DEBUG__
  18 #include <fiwix/stdio.h>
  19 #endif /*__DEBUG__ */
  20 
  21 int sys_nanosleep(const struct timespec *req, struct timespec *rem)
  22 {
  23         int errno;
  24         long int nsec;
  25 
  26 #ifdef __DEBUG__
  27         printk("(pid %d) sys_nanosleep(0x%08x, 0x%08x)\n", current->pid, (unsigned int)req, (unsigned int)rem);
  28 #endif /*__DEBUG__ */
  29 
  30         if((errno = check_user_area(VERIFY_READ, req, sizeof(struct timespec)))) {
  31                 return errno;
  32         }
  33         if(req->tv_sec < 0 || req->tv_nsec >= 1000000000L || req->tv_nsec < 0) {
  34                 return -EINVAL;
  35         }
  36 
  37         /*
  38          * Since the current maximum precision of the kernel is only 10ms, we
  39          * need to convert any lower request to a minimum of 10ms, even knowing
  40          * that this might increase the sleep a bit more than the requested.
  41          */
  42         nsec = req->tv_nsec;
  43         if(nsec < 10000000L) {
  44                 nsec *= 10;
  45         }
  46 
  47         current->timeout = (req->tv_sec * HZ) + (nsec * HZ / 1000000000L);
  48         if(current->timeout) {
  49                 sleep(&sys_nanosleep, PROC_INTERRUPTIBLE);
  50                 if(current->timeout) {
  51                         if(rem) {
  52                                 if((errno = check_user_area(VERIFY_WRITE, rem, sizeof(struct timespec)))) {
  53                                         return errno;
  54                                 }
  55                                 rem->tv_sec = current->timeout / HZ;
  56                                 rem->tv_nsec = (current->timeout % HZ) * 1000000000L / HZ;
  57                         }
  58                         return -EINTR;
  59                 }
  60         }
  61         return 0;
  62 }

/* [previous][next][first][last][top][bottom][index][help] */