libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
scheduler_priorities.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2019 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "../core/application.hpp"
20 
21 #include <boost/exception/diagnostic_information.hpp>
22 #include <boost/program_options.hpp>
23 
24 #include <filesystem>
25 #include <fstream>
26 #include <iostream>
27 
28 #include <sys/time.h>
29 #include <sys/resource.h>
30 
31 constexpr const char copyright[]=
32 "/******************************************************************************\n"
33 "** Copyright © 2019 by J.M.McGuiness, coder@hussar.me.uk\n"
34 "**\n"
35 "** This library is free software; you can redistribute it and/or\n"
36 "** modify it under the terms of the GNU Lesser General Public\n"
37 "** License as published by the Free Software Foundation; either\n"
38 "** version 2.1 of the License, or (at your option) any later version.\n"
39 "**\n"
40 "** This library is distributed in the hope that it will be useful,\n"
41 "** but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
42 "** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
43 "** Lesser General Public License for more details.\n"
44 "**\n"
45 "** You should have received a copy of the GNU Lesser General Public\n"
46 "** License along with this library; if not, write to the Free Software\n"
47 "** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
48 "*/\n";
49 constexpr const char header_guard_postfix[]="#endif\n";
50 
51 /**
52  \todo This cannot be set unless CAP_SYS_RESOURCE is applied.
53 
54  const int schedule_policy=SCHED_FIFO;
55 
56  This may be done thus:
57 
58  sudo setcap 'CAP_SYS_RESOURCE=+ep' /path/to/executable
59 
60  If SCHED_OTHER is used then basically one cannot set the priority, as the min & max are both set to zero.
61 */
62 const int schedule_policy=SCHED_OTHER;
63 
64 using namespace jmmcg::LIBJMMCG_VER_NAMESPACE;
65 
67  std::ostream &os;
68 
69  header_guard_t(std::string const &exe, std::string const &fname, std::ostream &s) noexcept(false)
70  : os(s) {
71  os
72  <<"#ifndef LIBJMMCG_UNIX_"<<std::filesystem::path(fname).stem().string()<<"_HPP\n"
73  "#define LIBJMMCG_UNIX_"<<std::filesystem::path(fname).stem().string()<<"_HPP\n"
74  <<copyright
75  <<"// Auto-generated header file.\n"
76  "// DO NOT EDIT. IT WILL BE OVERWRITTEN.\n"
77  "// Version: " LIBJMMCG_VERSION_NUMBER "\n"
78  "// O/S info: '" LIBJMMCG_SYSTEM_NAME << "', specifically: '" LIBJMMCG_SYSTEM "'\n"
79  "/**\n"
80  "\t\\file The constants created in this file are used in api_threading_traits::set_kernel_priority(), so must not be manually doctored! To re-generate this file for your O/S, run '"<<exe<<"' in the installation directory as a suitable user.\n"
81  "*/\n"
82  "namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace private_ {\n";
83  }
84  ~header_guard_t() noexcept(false) {
85  os<<"} } } }\n"
87  }
88 };
89 
90 auto get_sched_min_max() noexcept(false) {
91  rlimit lim{};
92  int err=::getrlimit(RLIMIT_NICE, &lim);
93  if (err==-1) {
94  throw std::runtime_error("Failed to get the rlimit of the priorities.");
95  }
96  lim.rlim_cur=lim.rlim_max;
97  err=::setrlimit(RLIMIT_NICE, &lim);
98  if (err==-1) {
99  throw std::runtime_error("Failed to update the rlimit of the priorities.");
100  }
101  const int max_priority=sched_get_priority_max(schedule_policy);
102  const int min_priority=sched_get_priority_min(schedule_policy);
103  if ((max_priority!=-1) && (min_priority!=-1)) {
104  return std::make_pair(min_priority, max_priority);
105  } else {
106  throw std::runtime_error("Failed to get the max & min priorities of the scheduler.");
107  }
108 }
109 
110 /// Discover the minimum and maximum scheduler-priorities on the current system.
111 int
112 main(int argc, char const * const *argv) noexcept(true) {
113  try {
114  boost::program_options::options_description general(
115  "A program to discover the minimum and maximum scheduler-priorities on the current system and put them into a C++ header-file. For details regarding the properties of this program, see the documentation that came with the distribution. Copyright © J.M.McGuiness, coder@hussar.me.uk. http://libjmmcg.sf.net/ Distributed under the terms of the GPL v2.1.\n"+exit_codes::to_string()+"Arguments"
116  );
117  general.add_options()
118  ("help", "Print this help message.")
119  ("version", "Print the build number of this program.")
120  ;
121  boost::program_options::options_description prog_opts("Program options.");
122  prog_opts.add_options()
123  ("cpp_header", boost::program_options::value<std::string>()->required(), "The file-path of the output C++ header-file.")
124  ;
125  boost::program_options::options_description all("All options.");
126  all.add(general).add(prog_opts);
127  boost::program_options::variables_map vm;
128  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, all), vm);
129  if (vm.count("help")) {
130  std::cout<<all<<std::endl;
132  }
133  if (vm.count("version")) {
134  std::cout<<LIBJMMCG_DETAILED_VERSION_INFO<<std::endl;
136  }
137  boost::program_options::notify(vm);
138 
139  std::ofstream cpp_header(vm["cpp_header"].as<std::string>().c_str());
140  const header_guard_t header_guard(std::filesystem::path(argv[0]).filename().string(), vm["cpp_header"].as<std::string>(), cpp_header);
141  auto const &sched_min_max=get_sched_min_max();
142  cpp_header
143  <<"\nenum scheduler_policy : int {\n"
144  <<"\tschedule_policy="<<schedule_policy<<"\n"
145  "};\n"
146  "\nenum scheduler_min_max_priorities : int {\n"
147  "\tscheduler_min_priority="<<sched_min_max.first<<",\n"
148  "\tscheduler_max_priority="<<sched_min_max.second<<"\n"
149  "};\n\n";
150 
152  } catch (std::exception const &ex) {
153  std::cerr<<"STL-derived exception. Details: "<<boost::diagnostic_information(ex)<<std::endl;
155  } catch (...) {
156  std::cerr<<"Unknown exception."<<std::endl;
158  }
160 }