blob: d8864fe94042f1da44b7a16182f5962802665b7b [file] [log] [blame]
Brian Silverman14fd0fb2014-01-14 21:42:01 -08001#include "aos/linux_code/init.h"
brians343bc112013-02-10 01:53:46 +00002
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>
brians343bc112013-02-10 01:53:46 +00009#include <sys/types.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <stdint.h>
13
brians343bc112013-02-10 01:53:46 +000014#include "aos/common/die.h"
Brian Silverman14fd0fb2014-01-14 21:42:01 -080015#include "aos/linux_code/logging/linux_logging.h"
16#include "aos/linux_code/ipc_lib/shared_mem.h"
brians343bc112013-02-10 01:53:46 +000017
18namespace aos {
19
20namespace {
21
Brian Silverman80353cb2013-03-19 18:27:53 -070022void SetSoftRLimit(int resource, rlim64_t soft, bool set_for_root) {
23 bool am_root = getuid() == 0;
24 if (set_for_root || !am_root) {
brians343bc112013-02-10 01:53:46 +000025 struct rlimit64 rlim;
26 if (getrlimit64(resource, &rlim) == -1) {
Brian Silverman01be0002014-05-10 15:44:38 -070027 PDie("%s-init: getrlimit64(%d) failed",
28 program_invocation_short_name, resource);
brians343bc112013-02-10 01:53:46 +000029 }
30 rlim.rlim_cur = soft;
31 if (setrlimit64(resource, &rlim) == -1) {
Brian Silverman01be0002014-05-10 15:44:38 -070032 PDie("%s-init: setrlimit64(%d, {cur=%ju,max=%ju}) failed",
33 program_invocation_short_name, resource, (uintmax_t)rlim.rlim_cur,
34 (uintmax_t)rlim.rlim_max);
brians343bc112013-02-10 01:53:46 +000035 }
36 }
37}
38
39// Common stuff that needs to happen at the beginning of both the realtime and
40// non-realtime initialization sequences. May be called twice.
41void InitStart() {
42 // Allow locking as much as we want into RAM.
Brian Silverman80353cb2013-03-19 18:27:53 -070043 SetSoftRLimit(RLIMIT_MEMLOCK, RLIM_INFINITY, false);
Brian Silvermanfe1ef172014-04-12 17:12:45 -070044 WriteCoreDumps();
brians343bc112013-02-10 01:53:46 +000045}
46
Brian Silverman6da04272014-05-18 18:47:48 -070047void LockAllMemory() {
brians343bc112013-02-10 01:53:46 +000048 InitStart();
49 if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
Brian Silverman01be0002014-05-10 15:44:38 -070050 PDie("%s-init: mlockall failed", program_invocation_short_name);
brians343bc112013-02-10 01:53:46 +000051 }
52
53 // Forces the memory pages for all the stack space that we're ever going to
54 // use to be loaded into memory (so it can be locked there).
55 uint8_t data[4096 * 8];
56 // Not 0 because linux might optimize that to a 0-filled page.
57 memset(data, 1, sizeof(data));
brians343bc112013-02-10 01:53:46 +000058}
59
60// Do the initialization code that is necessary for both realtime and
61// non-realtime processes.
62void DoInitNRT(aos_core_create create) {
63 InitStart();
Brian Silverman01be0002014-05-10 15:44:38 -070064 aos_core_create_shared_mem(create);
Brian Silverman14fd0fb2014-01-14 21:42:01 -080065 logging::linux_code::Register();
brians343bc112013-02-10 01:53:46 +000066}
67
68const char *const kNoRealtimeEnvironmentVariable = "AOS_NO_REALTIME";
69
70} // namespace
71
72void InitNRT() { DoInitNRT(aos_core_create::reference); }
73void InitCreate() { DoInitNRT(aos_core_create::create); }
Brian Silvermanf3cfbd72013-10-28 16:26:09 -070074void Init(int relative_priority) {
brians343bc112013-02-10 01:53:46 +000075 if (getenv(kNoRealtimeEnvironmentVariable) == NULL) { // if nobody set it
76 LockAllMemory();
Brian Silverman6da04272014-05-18 18:47:48 -070077
Brian Silverman8dc9fd42014-02-10 13:35:43 -080078 // Only let rt processes run for 3 seconds straight.
79 SetSoftRLimit(RLIMIT_RTTIME, 3000000, true);
Brian Silverman6da04272014-05-18 18:47:48 -070080
brians343bc112013-02-10 01:53:46 +000081 // Allow rt processes up to priority 40.
Brian Silverman80353cb2013-03-19 18:27:53 -070082 SetSoftRLimit(RLIMIT_RTPRIO, 40, false);
Brian Silverman6da04272014-05-18 18:47:48 -070083
84 // Set our process to the appropriate priority.
brians343bc112013-02-10 01:53:46 +000085 struct sched_param param;
Brian Silvermanf3cfbd72013-10-28 16:26:09 -070086 param.sched_priority = 30 + relative_priority;
brians343bc112013-02-10 01:53:46 +000087 if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
Brian Silverman01be0002014-05-10 15:44:38 -070088 PDie("%s-init: setting SCHED_FIFO failed", program_invocation_short_name);
brians343bc112013-02-10 01:53:46 +000089 }
90 } else {
91 fprintf(stderr, "%s not doing realtime initialization because environment"
92 " variable %s is set\n", program_invocation_short_name,
93 kNoRealtimeEnvironmentVariable);
94 printf("no realtime for %s. see stderr\n", program_invocation_short_name);
95 }
96
97 InitNRT();
98}
99
100void Cleanup() {
Brian Silverman01be0002014-05-10 15:44:38 -0700101 aos_core_free_shared_mem();
brians343bc112013-02-10 01:53:46 +0000102}
103
Brian Silvermanfe1ef172014-04-12 17:12:45 -0700104void WriteCoreDumps() {
105 // Do create core files of unlimited size.
106 SetSoftRLimit(RLIMIT_CORE, RLIM_INFINITY, true);
107}
108
brians343bc112013-02-10 01:53:46 +0000109} // namespace aos