2 // Copyright (C) 2008 Francesco Salvestrini
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program 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
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "libs/misc/debug.h"
29 #include "libs/misc/constant.h"
30 #include "libs/misc/environment.h"
31 #include "libs/misc/utility.h"
32 #include "libs/conf/configuration.h"
33 #include "libs/vm/vm.h"
35 #include "libs/vm/lua.h"
37 #include "libs/net/uuid.h"
39 #define PROGRAM_NAME "beacon"
44 << PROGRAM_NAME
<< " (" << PACKAGE_NAME
<< ") " << PACKAGE_VERSION
<< std::endl
46 << "Copyright (C) 2008 Francesco Salvestrini" << std::endl
48 << "This is free software. You may redistribute copies of it under the terms of" << std::endl
49 << "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>." << std::endl
50 << "There is NO WARRANTY, to the extent permitted by law." << std::endl
;
54 #define DEFAULT_MAX_MEM 16 * KB
55 #define DEFAULT_MAX_JOBS 8
60 << "Usage: " << PROGRAM_NAME
<< " [OPTION]... " << std::endl
62 << "Options: " << std::endl
63 << " -m, --max-mem maximum usable memory in KB (default " << DEFAULT_MAX_MEM
/ KB
<< " KB)" << std::endl
64 << " -j, --max-jobs maximum number of parallel jobs (default " << DEFAULT_MAX_JOBS
<< ")" << std::endl
65 << " -d, --debug enable debugging traces" << std::endl
66 << " -h, --help print this help, then exit" << std::endl
67 << " -V, --version print version number, then exit" << std::endl
69 << "Report bugs to <" << PACKAGE_BUGREPORT
<< ">" << std::endl
;
72 void hint(const std::string
& message
)
74 BUG_ON(message
.size() == 0);
77 << message
<< std::endl
78 << "Try `" << PROGRAM_NAME
<< " -h' for more information." << std::endl
;
81 int main(int argc
, char * argv
[])
83 TR_CONFIG_LVL(TR_LVL_DEFAULT
);
84 TR_CONFIG_PFX(PROGRAM_NAME
);
87 std::string conffile
= "";
89 int max_mem
= DEFAULT_MAX_MEM
;
90 bool max_mem_set
= false;
91 int max_jobs
= DEFAULT_MAX_JOBS
;
92 bool max_jobs_set
= false;
95 //int digit_optind = 0;
97 //int this_option_optind = optind ? optind : 1;
100 static struct option long_options
[] = {
101 { "config", 1, 0, 'c' },
102 { "max-mem", 1, 0, 'm' },
103 { "max-jobs", 1, 0, 'j' },
104 { "debug", 0, 0, 'd' },
105 { "verbose", 0, 0, 'v' },
106 { "version", 0, 0, 'V' },
107 { "help", 0, 0, 'h' },
111 c
= getopt_long(argc
, argv
, "c:m:j:dvVh",
112 long_options
, &option_index
);
124 // The current solution is ugly.
125 // Add modifiers (KB, MB, GB) to
126 // this option in order to use
127 // different memory granularity.
129 max_mem
= atoi(optarg
);
131 hint("Wrong max memory value");
134 max_mem
= max_mem
* 1024;
138 max_jobs
= atoi(optarg
);
140 hint("Wrong max jobs value");
146 TR_CONFIG_LVL(TR_LVL_DEBUG
);
149 TR_CONFIG_LVL(TR_LVL_VERBOSE
);
158 hint("Unrecognized option");
167 // Options related checks
168 BUG_ON(max_mem
<= 0);
169 BUG_ON(max_jobs
<= 0);
171 // Build configuration file path
172 if (conffile
.size() == 0) {
173 std::string homedir
= Environment::get("HOME");
174 std::string confdir
=
178 std::string(PACKAGE_TARNAME
);
182 std::string(PROGRAM_NAME
);
184 TR_DBG("Configuration file overridden\n");
187 BUG_ON(conffile
.size() == 0);
189 TR_DBG("Initial (configuration file) values:\n");
190 TR_DBG(" Max mem: '%d'\n", max_mem
);
191 TR_DBG(" Max jobs: '%d'\n", max_jobs
);
193 // Read configuration file (if available)
195 TR_DBG("Reading configuration file from '%s'\n",
198 Configuration::File config
;
199 std::ifstream
instream(conffile
.c_str());
204 if (config
.get
<int>(conf_max_mem
, "max-mem")) {
205 TR_DBG("Found 'max-mem' key, value '%d'\n",
208 // Check gathered configuration
209 if (conf_max_mem
< 0) {
210 TR_ERR("Wrong max-mem value in "
211 "configuration file");
216 TR_DBG("Updating 'max-mem' key\n");
218 // Configuration value not specified
219 // in command line ...
220 max_mem
= conf_max_mem
;
225 if (config
.get
<int>(conf_max_jobs
, "max-jobs")) {
226 TR_DBG("Found 'max-jobs' key, value '%d'\n",
229 // Check gathered configuration
230 if (conf_max_jobs
< 0) {
231 TR_ERR("Wrong max-jobs value in "
232 "configuration file");
237 TR_DBG("Updating 'max-jobs' key\n");
239 // Configuration value not specified
240 // in command line ...
241 max_jobs
= conf_max_jobs
;
244 } catch (std::exception
& e
) {
245 TR_ERR("%s\n", e
.what());
250 // Options related checks
251 BUG_ON(max_mem
<= 0);
252 BUG_ON(max_jobs
<= 0);
254 TR_DBG("Final (configuration file) values:\n");
255 TR_DBG(" Max mem: '%d'\n", max_mem
);
256 TR_DBG(" Max jobs: '%d'\n", max_jobs
);
258 size_t mem_for_vm
= max_mem
/ max_jobs
;
260 // Dump (acquired and derived) infos
261 TR_DBG("Max mem: '%d'\n", max_mem
);
262 TR_DBG("Max jobs '%d'\n", max_jobs
);
263 TR_DBG("Mem for VM '%d'\n", mem_for_vm
);
264 TR_DBG("Configuration file: '%s'\n", conffile
.c_str());
266 if (mem_for_vm
< MIN_MEM_FOR_VM
) {
267 TR_CRT("Memory for single VM is too small "
268 "(%d byte%s each, %d minimum)\n",
269 mem_for_vm
, PLURAL(mem_for_vm
), MIN_MEM_FOR_VM
);
273 TR_DBG("Building %d VM%s\n", max_jobs
, PLURAL(max_jobs
));
275 std::vector
<VM::VM
*> vms
;
276 vms
.resize(max_jobs
);
278 std::vector
<VM::VM
*>::iterator iter
;
279 for (iter
= vms
.begin(); iter
!= vms
.end(); iter
++) {
282 (*iter
) = new VM::Lua(mem_for_vm
);
285 TR_CRT("Cannot create VM\n");
288 TR_DBG("VM %p initialized\n", (*iter
));
291 size_t slack
= max_mem
- max_jobs
* mem_for_vm
;
292 TR_DBG("Memory slack is %d byte%s\n", slack
, PLURAL(slack
));
294 // Do the main loop here
296 std::string
t1("550e8400-e29b-41d4-a716-123456782122");
299 std::cout
<< t1
<< std::endl
;
303 t2
= std::string(uuid
);
305 std::cout
<< t2
<< std::endl
;
309 } catch (std::exception
& e
) {
310 TR_DBG("Got exception '%s'\n", e
.what());