Index: components/nacl/loader/nonsfi/irt/irt_basic.cc |
diff --git a/components/nacl/loader/nonsfi/irt/irt_basic.cc b/components/nacl/loader/nonsfi/irt/irt_basic.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..075e861fd096ce3771d0c24c0b0b35201770a055 |
--- /dev/null |
+++ b/components/nacl/loader/nonsfi/irt/irt_basic.cc |
@@ -0,0 +1,97 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <errno.h> |
+#include <sched.h> |
+#include <stdlib.h> |
+#include <sys/time.h> |
+#include <time.h> |
+#include <unistd.h> |
+ |
+#include "components/nacl/loader/nonsfi/irt/irt_interfaces.h" |
+#include "native_client/src/trusted/service_runtime/include/sys/time.h" |
+ |
+namespace nacl { |
+namespace nonsfi { |
+namespace { |
+ |
+void IrtExit(int status) { |
+ // Note: when we start to support threads, here we need to join them. |
Mark Seaborn
2014/01/07 09:45:06
That's not the case. There's no need to join thre
hidehiko
2014/01/07 11:52:29
Oops, I misunderstood. Done.
|
+ ::exit(status); |
Mark Seaborn
2014/01/07 09:45:06
This should really call _exit(), because exit() do
hidehiko
2014/01/07 11:52:29
Done.
|
+ while (1) *(volatile int *) 0 = 0; // Crash. |
Mark Seaborn
2014/01/07 09:45:06
Not really necessary, since _exit() is generally d
hidehiko
2014/01/07 11:52:29
Ok, removed. This is extracted from native_client/
|
+} |
+ |
+int IrtGetToD(struct nacl_abi_timeval* tv) { |
+ struct timeval host_tv; |
+ int result = ::gettimeofday(&host_tv, NULL); |
+ if (result) |
+ return errno; |
+ tv->nacl_abi_tv_sec = host_tv.tv_sec; |
+ tv->nacl_abi_tv_usec = host_tv.tv_usec; |
+ return 0; |
+} |
+ |
+int IrtClock(nacl_abi_clock_t* ticks) { |
+ *ticks = ::clock(); // No failure. |
Mark Seaborn
2014/01/07 09:45:06
The man page says this can return (clock_t)-1 on f
hidehiko
2014/01/07 11:52:29
Good catch. I just mimic'ed native_client/src/trus
Mark Seaborn
2014/01/10 05:12:20
Oh, you're right. http://pubs.opengroup.org/onlin
hidehiko
2014/01/10 07:27:47
Done.
|
+ return 0; |
+} |
+ |
+int IrtNanoSleep(const struct nacl_abi_timespec* req, |
+ struct nacl_abi_timespec* rem) { |
+ // We should be able to call nanosleep(NULL, &host_rem) for this. |
Mark Seaborn
2014/01/07 09:45:06
Why do you expect req==NULL to work? This isn't p
hamaji
2014/01/07 11:32:09
Let me reply as I wrote this.
I think both linux
hidehiko
2014/01/07 11:52:29
Thank you for your comment, Shinichiro.
So, accord
Mark Seaborn
2014/01/10 05:12:20
Out of curiosity, what's the case you need the wor
hidehiko
2014/01/10 07:27:47
It turned out that it was just our test code. We'l
|
+ // However, the user mode qemu-arm does not handle this case |
+ // properly. It just runs nanosleep with the parameter for the |
+ // previous nanosleep call. To work-around this issue, we handle |
+ // this case by ourselves. |
+ if (!req) |
+ return EFAULT; |
+ |
+ struct timespec host_req; |
+ host_req.tv_sec = req->tv_sec; |
+ host_req.tv_nsec = req->tv_nsec; |
+ struct timespec host_rem; |
+ int result = ::nanosleep(&host_req, &host_rem); |
+ if (result) |
+ return errno; |
+ |
+ if (rem) { |
+ rem->tv_sec = host_rem.tv_sec; |
+ rem->tv_nsec = host_rem.tv_nsec; |
+ } |
+ return 0; |
+} |
+ |
+int IrtSchedYield() { |
+ int result = ::sched_yield(); |
+ if (result) |
+ return errno; |
+ |
+ return 0; |
+} |
+ |
+int IrtSysconf(int name, int* value) { |
+ errno = 0; |
+ *value = ::sysconf(name); |
Mark Seaborn
2014/01/07 09:45:06
Calling through to sysconf() isn't valid because t
hidehiko
2014/01/07 11:52:29
Great to know. Done.
|
+ if (*value == -1 && errno == EINVAL) |
+ return EINVAL; |
+ return 0; |
+} |
+ |
+} // namespace |
+ |
+// For gettod, clock and nanosleep, their argument types should be nacl_abi_X, |
+// rather than host type, such as timeval or clock_t etc. However, the |
+// definition of nacl_irt_basic uses host types, so here we need to cast them. |
+const nacl_irt_basic kIrtBasic = { |
+ IrtExit, |
+ reinterpret_cast<int(*)(struct timeval*)>(IrtGetToD), |
+ reinterpret_cast<int(*)(clock_t*)>(IrtClock), |
+ reinterpret_cast<int(*)(const struct timespec*, struct timespec*)>( |
+ IrtNanoSleep), |
+ IrtSchedYield, |
+ IrtSysconf, |
+}; |
+ |
+} // namespace nonsfi |
+} // namespace nacl |