2021-05-09 13:15:17 +08:00
|
|
|
#include "selfdrive/common/util.h"
|
|
|
|
|
2020-10-18 03:40:01 +08:00
|
|
|
#include <errno.h>
|
|
|
|
|
2021-06-01 22:53:12 +08:00
|
|
|
#include <cassert>
|
|
|
|
#include <cstring>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <fstream>
|
2021-05-09 13:15:17 +08:00
|
|
|
#include <sstream>
|
2021-06-01 22:53:12 +08:00
|
|
|
#include <iomanip>
|
2021-03-09 11:17:46 +08:00
|
|
|
|
2020-01-18 03:01:02 +08:00
|
|
|
#ifdef __linux__
|
|
|
|
#include <sys/prctl.h>
|
|
|
|
#include <sys/syscall.h>
|
2020-10-18 03:40:01 +08:00
|
|
|
#ifndef __USE_GNU
|
2020-06-06 05:09:41 +08:00
|
|
|
#define __USE_GNU
|
2020-01-18 03:01:02 +08:00
|
|
|
#endif
|
2020-10-18 03:40:01 +08:00
|
|
|
#include <sched.h>
|
2021-05-09 13:15:17 +08:00
|
|
|
#endif // __linux__
|
2020-01-18 03:01:02 +08:00
|
|
|
|
|
|
|
void set_thread_name(const char* name) {
|
|
|
|
#ifdef __linux__
|
|
|
|
// pthread_setname_np is dumb (fails instead of truncates)
|
|
|
|
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int set_realtime_priority(int level) {
|
|
|
|
#ifdef __linux__
|
|
|
|
long tid = syscall(SYS_gettid);
|
|
|
|
|
|
|
|
// should match python using chrt
|
|
|
|
struct sched_param sa;
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
|
|
sa.sched_priority = level;
|
|
|
|
return sched_setscheduler(tid, SCHED_FIFO, &sa);
|
|
|
|
#else
|
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-06-06 05:09:41 +08:00
|
|
|
int set_core_affinity(int core) {
|
2020-09-02 23:52:41 +08:00
|
|
|
#ifdef __linux__
|
2020-06-06 05:09:41 +08:00
|
|
|
long tid = syscall(SYS_gettid);
|
|
|
|
cpu_set_t rt_cpu;
|
|
|
|
|
|
|
|
CPU_ZERO(&rt_cpu);
|
|
|
|
CPU_SET(core, &rt_cpu);
|
|
|
|
return sched_setaffinity(tid, sizeof(rt_cpu), &rt_cpu);
|
|
|
|
#else
|
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
2021-04-14 02:43:43 +08:00
|
|
|
|
|
|
|
namespace util {
|
|
|
|
|
|
|
|
std::string read_file(const std::string& fn) {
|
|
|
|
std::ifstream ifs(fn, std::ios::binary | std::ios::ate);
|
|
|
|
if (ifs) {
|
|
|
|
std::ifstream::pos_type pos = ifs.tellg();
|
2021-04-14 04:56:08 +08:00
|
|
|
if (pos != std::ios::beg) {
|
|
|
|
std::string result;
|
|
|
|
result.resize(pos);
|
|
|
|
ifs.seekg(0, std::ios::beg);
|
|
|
|
ifs.read(result.data(), pos);
|
|
|
|
if (ifs) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
2021-04-14 02:43:43 +08:00
|
|
|
}
|
2021-04-14 05:40:40 +08:00
|
|
|
ifs.close();
|
|
|
|
|
|
|
|
// fallback for files created on read, e.g. procfs
|
|
|
|
std::ifstream f(fn);
|
|
|
|
std::stringstream buffer;
|
|
|
|
buffer << f.rdbuf();
|
|
|
|
return buffer.str();
|
2021-04-14 02:43:43 +08:00
|
|
|
}
|
|
|
|
|
2021-05-12 17:15:54 +08:00
|
|
|
int read_files_in_dir(std::string path, std::map<std::string, std::string> *contents) {
|
|
|
|
DIR *d = opendir(path.c_str());
|
|
|
|
if (!d) return -1;
|
|
|
|
|
|
|
|
struct dirent *de = NULL;
|
|
|
|
while ((de = readdir(d))) {
|
|
|
|
if (isalnum(de->d_name[0])) {
|
|
|
|
(*contents)[de->d_name] = util::read_file(path + "/" + de->d_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-15 08:33:46 +08:00
|
|
|
closedir(d);
|
2021-05-12 17:15:54 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-04-14 02:43:43 +08:00
|
|
|
int write_file(const char* path, const void* data, size_t size, int flags, mode_t mode) {
|
|
|
|
int fd = open(path, flags, mode);
|
|
|
|
if (fd == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ssize_t n = write(fd, data, size);
|
|
|
|
close(fd);
|
|
|
|
return (n >= 0 && (size_t)n == size) ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
2021-06-01 22:53:12 +08:00
|
|
|
std::string readlink(const std::string &path) {
|
|
|
|
char buff[4096];
|
|
|
|
ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
|
|
|
|
if (len != -1) {
|
|
|
|
buff[len] = '\0';
|
|
|
|
return std::string(buff);
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool file_exists(const std::string& fn) {
|
|
|
|
std::ifstream f(fn);
|
|
|
|
return f.good();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string getenv_default(const char* env_var, const char * suffix, const char* default_val) {
|
|
|
|
const char* env_val = getenv(env_var);
|
|
|
|
if (env_val != NULL){
|
|
|
|
return std::string(env_val) + std::string(suffix);
|
|
|
|
} else {
|
|
|
|
return std::string(default_val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string tohex(const uint8_t *buf, size_t buf_size) {
|
|
|
|
std::unique_ptr<char[]> hexbuf(new char[buf_size * 2 + 1]);
|
|
|
|
for (size_t i = 0; i < buf_size; i++) {
|
|
|
|
sprintf(&hexbuf[i * 2], "%02x", buf[i]);
|
|
|
|
}
|
|
|
|
hexbuf[buf_size * 2] = 0;
|
|
|
|
return std::string(hexbuf.get(), hexbuf.get() + buf_size * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string hexdump(const std::string& in) {
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << std::hex << std::setfill('0');
|
|
|
|
for (size_t i = 0; i < in.size(); i++) {
|
|
|
|
ss << std::setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(in[i]));
|
|
|
|
}
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string base_name(std::string const &path) {
|
|
|
|
size_t pos = path.find_last_of("/");
|
|
|
|
if (pos == std::string::npos) return path;
|
|
|
|
return path.substr(pos + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string dir_name(std::string const &path) {
|
|
|
|
size_t pos = path.find_last_of("/");
|
|
|
|
if (pos == std::string::npos) return "";
|
|
|
|
return path.substr(0, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct tm get_time(){
|
|
|
|
time_t rawtime;
|
|
|
|
time(&rawtime);
|
|
|
|
|
|
|
|
struct tm sys_time;
|
|
|
|
gmtime_r(&rawtime, &sys_time);
|
|
|
|
|
|
|
|
return sys_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool time_valid(struct tm sys_time){
|
|
|
|
int year = 1900 + sys_time.tm_year;
|
|
|
|
int month = 1 + sys_time.tm_mon;
|
|
|
|
return (year > 2020) || (year == 2020 && month >= 10);
|
|
|
|
}
|
2021-05-12 17:15:54 +08:00
|
|
|
|
2021-04-14 02:43:43 +08:00
|
|
|
} // namespace util
|