blob: b3668e86f7c05fdc54e9abd9212a1cbc74e9c286 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include "aos/atom_code/init.h"
2
3#include <stdio.h>
4#include <string.h>
5#include <sys/mman.h>
6#include <errno.h>
7#include <sched.h>
8#include <sys/resource.h>
9#include <asm-generic/resource.h> // for RLIMIT_RTTIME
10#include <sys/types.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include <stdint.h>
14
brians343bc112013-02-10 01:53:46 +000015#include "aos/common/die.h"
Brian Silvermanf665d692013-02-17 22:11:39 -080016#include "aos/atom_code/logging/atom_logging.h"
17#include "aos/atom_code/ipc_lib/shared_mem.h"
brians343bc112013-02-10 01:53:46 +000018
19namespace aos {
20
21namespace {
22
Brian Silverman80353cb2013-03-19 18:27:53 -070023void SetSoftRLimit(int resource, rlim64_t soft, bool set_for_root) {
24 bool am_root = getuid() == 0;
25 if (set_for_root || !am_root) {
brians343bc112013-02-10 01:53:46 +000026 struct rlimit64 rlim;
27 if (getrlimit64(resource, &rlim) == -1) {
28 Die("%s-init: getrlimit64(%d) failed with %d (%s)\n",
29 program_invocation_short_name, resource, errno, strerror(errno));
30 }
31 rlim.rlim_cur = soft;
32 if (setrlimit64(resource, &rlim) == -1) {
33 Die("%s-init: setrlimit64(%d, {cur=%jd,max=%jd})"
34 " failed with %d (%s)\n", program_invocation_short_name,
35 resource, (intmax_t)rlim.rlim_cur, (intmax_t)rlim.rlim_max,
36 errno, strerror(errno));
37 }
38 }
39}
40
41// Common stuff that needs to happen at the beginning of both the realtime and
42// non-realtime initialization sequences. May be called twice.
43void InitStart() {
44 // Allow locking as much as we want into RAM.
Brian Silverman80353cb2013-03-19 18:27:53 -070045 SetSoftRLimit(RLIMIT_MEMLOCK, RLIM_INFINITY, false);
46
47 // Do create core files of unlimited size.
48 SetSoftRLimit(RLIMIT_CORE, RLIM_INFINITY, true);
brians343bc112013-02-10 01:53:46 +000049}
50
51int LockAllMemory() {
52 InitStart();
53 if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
54 Die("%s-init: mlockall failed with %d (%s)\n",
55 program_invocation_short_name, errno, strerror(errno));
56 }
57
58 // Forces the memory pages for all the stack space that we're ever going to
59 // use to be loaded into memory (so it can be locked there).
60 uint8_t data[4096 * 8];
61 // Not 0 because linux might optimize that to a 0-filled page.
62 memset(data, 1, sizeof(data));
63
64 return 0;
65}
66
67// Do the initialization code that is necessary for both realtime and
68// non-realtime processes.
69void DoInitNRT(aos_core_create create) {
70 InitStart();
71 if (aos_core_create_shared_mem(create)) {
72 Die("%s-init: creating shared memory reference failed\n",
73 program_invocation_short_name);
74 }
Brian Silvermanf665d692013-02-17 22:11:39 -080075 logging::atom::Register();
brians343bc112013-02-10 01:53:46 +000076}
77
78const char *const kNoRealtimeEnvironmentVariable = "AOS_NO_REALTIME";
79
80} // namespace
81
82void InitNRT() { DoInitNRT(aos_core_create::reference); }
83void InitCreate() { DoInitNRT(aos_core_create::create); }
Brian Silvermanf3cfbd72013-10-28 16:26:09 -070084void Init(int relative_priority) {
brians343bc112013-02-10 01:53:46 +000085 if (getenv(kNoRealtimeEnvironmentVariable) == NULL) { // if nobody set it
86 LockAllMemory();
87 // Only let rt processes run for 1 second straight.
Brian Silverman80353cb2013-03-19 18:27:53 -070088 SetSoftRLimit(RLIMIT_RTTIME, 1000000, true);
brians343bc112013-02-10 01:53:46 +000089 // Allow rt processes up to priority 40.
Brian Silverman80353cb2013-03-19 18:27:53 -070090 SetSoftRLimit(RLIMIT_RTPRIO, 40, false);
brians343bc112013-02-10 01:53:46 +000091 // Set our process to priority 40.
92 struct sched_param param;
Brian Silvermanf3cfbd72013-10-28 16:26:09 -070093 param.sched_priority = 30 + relative_priority;
brians343bc112013-02-10 01:53:46 +000094 if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
95 Die("%s-init: setting SCHED_FIFO failed with %d (%s)\n",
96 program_invocation_short_name, errno, strerror(errno));
97 }
98 } else {
99 fprintf(stderr, "%s not doing realtime initialization because environment"
100 " variable %s is set\n", program_invocation_short_name,
101 kNoRealtimeEnvironmentVariable);
102 printf("no realtime for %s. see stderr\n", program_invocation_short_name);
103 }
104
105 InitNRT();
106}
107
108void Cleanup() {
109 if (aos_core_free_shared_mem()) {
110 Die("%s-init: freeing shared mem failed\n",
111 program_invocation_short_name);
112 }
113}
114
115} // namespace aos