diff options
author | Ruslan Bukin <br@FreeBSD.org> | 2017-10-24 16:28:00 +0000 |
---|---|---|
committer | Ruslan Bukin <br@FreeBSD.org> | 2017-10-24 16:28:00 +0000 |
commit | d27927f731d6877267b0db84664776d2e62fc443 (patch) | |
tree | cd3aca85950d07a00423da65d47330205feed92c /lib/libpmcstat/libpmcstat_string.c | |
parent | 701492a5f6733530ace7c6af70a753bb6c8c4120 (diff) |
Notes
Diffstat (limited to 'lib/libpmcstat/libpmcstat_string.c')
-rw-r--r-- | lib/libpmcstat/libpmcstat_string.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/lib/libpmcstat/libpmcstat_string.c b/lib/libpmcstat/libpmcstat_string.c new file mode 100644 index 000000000000..d7932c680eb4 --- /dev/null +++ b/lib/libpmcstat/libpmcstat_string.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2003-2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/cpuset.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/pmc.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <pmc.h> +#include <pmclog.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> + +#include "libpmcstat.h" + +static LIST_HEAD(,pmcstat_string) pmcstat_string_hash[PMCSTAT_NHASH]; + +/* + * Intern a copy of string 's', and return a pointer to the + * interned structure. + */ + +pmcstat_interned_string +pmcstat_string_intern(const char *s) +{ + struct pmcstat_string *ps; + const struct pmcstat_string *cps; + int hash, len; + + if ((cps = pmcstat_string_lookup(s)) != NULL) + return (cps); + + hash = pmcstat_string_compute_hash(s); + len = strlen(s); + + if ((ps = malloc(sizeof(*ps))) == NULL) + err(EX_OSERR, "ERROR: Could not intern string"); + ps->ps_len = len; + ps->ps_hash = hash; + ps->ps_string = strdup(s); + LIST_INSERT_HEAD(&pmcstat_string_hash[hash], ps, ps_next); + return ((pmcstat_interned_string) ps); +} + +const char * +pmcstat_string_unintern(pmcstat_interned_string str) +{ + const char *s; + + s = ((const struct pmcstat_string *) str)->ps_string; + return (s); +} + +/* + * Compute a 'hash' value for a string. + */ + +int +pmcstat_string_compute_hash(const char *s) +{ + unsigned hash; + + for (hash = 2166136261; *s; s++) + hash = (hash ^ *s) * 16777619; + + return (hash & PMCSTAT_HASH_MASK); +} + +pmcstat_interned_string +pmcstat_string_lookup(const char *s) +{ + struct pmcstat_string *ps; + int hash, len; + + hash = pmcstat_string_compute_hash(s); + len = strlen(s); + + LIST_FOREACH(ps, &pmcstat_string_hash[hash], ps_next) + if (ps->ps_len == len && ps->ps_hash == hash && + strcmp(ps->ps_string, s) == 0) + return (ps); + return (NULL); +} + +int +pmcstat_string_lookup_hash(pmcstat_interned_string s) +{ + const struct pmcstat_string *ps; + + ps = (const struct pmcstat_string *) s; + return (ps->ps_hash); +} + +/* + * Destroy the string table, free'ing up space. + */ + +void +pmcstat_string_shutdown(void) +{ + int i; + struct pmcstat_string *ps, *pstmp; + + for (i = 0; i < PMCSTAT_NHASH; i++) + LIST_FOREACH_SAFE(ps, &pmcstat_string_hash[i], ps_next, + pstmp) { + LIST_REMOVE(ps, ps_next); + free(ps->ps_string); + free(ps); + } +} + +/* + * Initialize the string interning facility. + */ + +void +pmcstat_string_initialize(void) +{ + int i; + + for (i = 0; i < PMCSTAT_NHASH; i++) + LIST_INIT(&pmcstat_string_hash[i]); +} |