aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2013-01-30 23:37:35 +0000
committerIan Lepore <ian@FreeBSD.org>2013-01-30 23:37:35 +0000
commit5dfc0f6c530cd93d79bd9d18b8f61b6ce8d5e6f1 (patch)
tree0cca54f5d40a8dfc09ed490e1cf7839fa648e5b0 /sbin
parentce06f5f68195c2b2f45a706dfdd773e41a70c713 (diff)
downloadsrc-5dfc0f6c530cd93d79bd9d18b8f61b6ce8d5e6f1.tar.gz
src-5dfc0f6c530cd93d79bd9d18b8f61b6ce8d5e6f1.zip
Improve devd startup time, by tweaking some string handling routines that are
heavily used when parsing config files. Mostly these changes avoid making temporary copies of the strings, and avoid doing byte at a time append operations, on the most-used code path. On a 1.2 GHz ARM processor this reduces the time to parse the config files from 13 to 6 seconds. Reviewed by: imp Approved by: cognet (mentor)
Notes
Notes: svn path=/head/; revision=246134
Diffstat (limited to 'sbin')
-rw-r--r--sbin/devd/devd.cc52
-rw-r--r--sbin/devd/devd.hh5
2 files changed, 32 insertions, 25 deletions
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index c91430f32125..46f3623a3a6b 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -137,7 +137,7 @@ config cfg;
event_proc::event_proc() : _prio(-1)
{
- // nothing
+ _epsvec.reserve(4);
}
event_proc::~event_proc()
@@ -241,25 +241,18 @@ my_system(const char *command)
bool
action::do_action(config &c)
{
- string s = c.expand_string(_cmd);
+ string s = c.expand_string(_cmd.c_str());
if (Dflag)
fprintf(stderr, "Executing '%s'\n", s.c_str());
my_system(s.c_str());
return (true);
}
-match::match(config &c, const char *var, const char *re)
- : _var(var), _re("^")
+match::match(config &c, const char *var, const char *re) :
+ _inv(re[0] == '!'),
+ _var(var),
+ _re(c.expand_string(_inv ? re + 1 : re, "^", "$"))
{
- if (!c.expand_string(string(re)).empty() &&
- c.expand_string(string(re)).at(0) == '!') {
- _re.append(c.expand_string(string(re)).substr(1));
- _inv = 1;
- } else {
- _re.append(c.expand_string(string(re)));
- _inv = 0;
- }
- _re.append("$");
regcomp(&_regex, _re.c_str(), REG_EXTENDED | REG_NOSUB | REG_ICASE);
}
@@ -624,24 +617,37 @@ config::expand_one(const char *&src, string &dst)
do {
buffer.append(src++, 1);
} while (is_id_char(*src));
- buffer.append("", 1);
dst.append(get_variable(buffer.c_str()));
}
const string
-config::expand_string(const string &s)
+config::expand_string(const char *src, const char *prepend, const char *append)
{
- const char *src;
+ const char *var_at;
string dst;
- src = s.c_str();
- while (*src) {
- if (*src == '$')
- expand_one(src, dst);
- else
- dst.append(src++, 1);
+ /*
+ * 128 bytes is enough for 2427 of 2438 expansions that happen
+ * while parsing config files, as tested on 2013-01-30.
+ */
+ dst.reserve(128);
+
+ if (prepend != NULL)
+ dst = prepend;
+
+ for (;;) {
+ var_at = strchr(src, '$');
+ if (var_at == NULL) {
+ dst.append(src);
+ break;
+ }
+ dst.append(src, var_at - src);
+ src = var_at;
+ expand_one(src, dst);
}
- dst.append("", 1);
+
+ if (append != NULL)
+ dst.append(append);
return (dst);
}
diff --git a/sbin/devd/devd.hh b/sbin/devd/devd.hh
index 36132160c475..a48d07b4930c 100644
--- a/sbin/devd/devd.hh
+++ b/sbin/devd/devd.hh
@@ -90,9 +90,9 @@ public:
virtual bool do_match(config &);
virtual bool do_action(config &) { return true; }
private:
+ bool _inv;
std::string _var;
std::string _re;
- bool _inv;
regex_t _regex;
};
@@ -162,7 +162,8 @@ public:
void pop_var_table();
void set_variable(const char *var, const char *val);
const std::string &get_variable(const std::string &var);
- const std::string expand_string(const std::string &var);
+ const std::string expand_string(const char * var,
+ const char * prepend = NULL, const char * append = NULL);
char *set_vars(char *);
void find_and_execute(char);
protected: