Home | History | Annotate | Download | only in nonsfi
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <errno.h>
      6 #include <sched.h>
      7 #include <stdlib.h>
      8 #include <sys/time.h>
      9 #include <time.h>
     10 #include <unistd.h>
     11 
     12 #include "components/nacl/loader/nonsfi/abi_conversion.h"
     13 #include "components/nacl/loader/nonsfi/irt_interfaces.h"
     14 #include "components/nacl/loader/nonsfi/irt_util.h"
     15 #include "native_client/src/trusted/service_runtime/include/sys/time.h"
     16 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
     17 
     18 namespace nacl {
     19 namespace nonsfi {
     20 namespace {
     21 
     22 void IrtExit(int status) {
     23   _exit(status);
     24 }
     25 
     26 int IrtGetToD(struct nacl_abi_timeval* tv) {
     27   struct timeval host_tv;
     28   if (gettimeofday(&host_tv, NULL))
     29     return errno;
     30   tv->nacl_abi_tv_sec = host_tv.tv_sec;
     31   tv->nacl_abi_tv_usec = host_tv.tv_usec;
     32   return 0;
     33 }
     34 
     35 int IrtClock(nacl_abi_clock_t* ticks) {
     36   // There is no definition of errno when clock is failed.
     37   // So we assume it always succeeds.
     38   *ticks = clock();
     39   return 0;
     40 }
     41 
     42 int IrtNanoSleep(const struct nacl_abi_timespec* req,
     43                  struct nacl_abi_timespec* rem) {
     44   struct timespec host_req;
     45   NaClAbiTimeSpecToTimeSpec(*req, &host_req);
     46   struct timespec host_rem;
     47   if (nanosleep(&host_req, &host_rem))
     48     return errno;
     49 
     50   if (rem)
     51     TimeSpecToNaClAbiTimeSpec(host_rem, rem);
     52   return 0;
     53 }
     54 
     55 int IrtSchedYield() {
     56   return CheckError(sched_yield());
     57 }
     58 
     59 int IrtSysconf(int name, int* value) {
     60   int result;
     61   switch (name) {
     62     case NACL_ABI__SC_NPROCESSORS_ONLN:
     63       errno = 0;
     64       result = sysconf(_SC_NPROCESSORS_ONLN);
     65       break;
     66     case NACL_ABI__SC_PAGESIZE:
     67       errno = 0;
     68       result = sysconf(_SC_PAGESIZE);
     69       break;
     70     default:
     71       return EINVAL;
     72   }
     73 
     74   if (result == -1 && errno == EINVAL)
     75     return EINVAL;
     76 
     77   *value = result;
     78   return 0;
     79 }
     80 
     81 }  // namespace
     82 
     83 // For gettod, clock and nanosleep, their argument types should be nacl_abi_X,
     84 // rather than host type, such as timeval or clock_t etc. However, the
     85 // definition of nacl_irt_basic uses host types, so here we need to cast them.
     86 const nacl_irt_basic kIrtBasic = {
     87   IrtExit,
     88   reinterpret_cast<int(*)(struct timeval*)>(IrtGetToD),
     89   reinterpret_cast<int(*)(clock_t*)>(IrtClock),
     90   reinterpret_cast<int(*)(const struct timespec*, struct timespec*)>(
     91       IrtNanoSleep),
     92   IrtSchedYield,
     93   IrtSysconf,
     94 };
     95 
     96 }  // namespace nonsfi
     97 }  // namespace nacl
     98