summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2015-11-17 17:49:09 +0000
committertedu <tedu@openbsd.org>2015-11-17 17:49:09 +0000
commit560ac86f7405bfbe0f2d8cc6e4591d91aa661c4d (patch)
treed12184600b5148de8072459d00289d4d983e6a3d /lib/libc
parentnote that -chs and -l are mutually exclusive; (diff)
downloadwireguard-openbsd-560ac86f7405bfbe0f2d8cc6e4591d91aa661c4d.tar.xz
wireguard-openbsd-560ac86f7405bfbe0f2d8cc6e4591d91aa661c4d.zip
change passwd caches to be 4-way "associative". still primitive, but a
little better than winner take all caching.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/pwcache.c86
1 files changed, 62 insertions, 24 deletions
diff --git a/lib/libc/gen/pwcache.c b/lib/libc/gen/pwcache.c
index 373b0843c04..e65112447ba 100644
--- a/lib/libc/gen/pwcache.c
+++ b/lib/libc/gen/pwcache.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pwcache.c,v 1.10 2015/10/26 15:04:51 tedu Exp $ */
+/* $OpenBSD: pwcache.c,v 1.11 2015/11/17 17:49:09 tedu Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,32 +35,52 @@
#include <stdio.h>
#include <string.h>
-#define NCACHE 64 /* power of 2 */
+#define NCACHE 16 /* power of 2 */
+#define NLINES 4 /* associativity */
#define MASK (NCACHE - 1) /* bits to store with */
+#define IDX(x, i) ((x & MASK) + i * NCACHE)
char *
user_from_uid(uid_t uid, int nouser)
{
static struct ncache {
uid_t uid;
+ short noname;
char name[_PW_NAME_LEN + 1];
- } c_uid[NCACHE];
+ } c_uid[NLINES * NCACHE];
static char nbuf[15]; /* 32 bits == 10 digits */
struct passwd *pw;
struct ncache *cp;
+ unsigned int i;
- cp = c_uid + (uid & MASK);
- if (cp->uid != uid || !*cp->name) {
- if ((pw = getpwuid(uid)) == NULL) {
- if (nouser)
- return (NULL);
- (void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
- return (nbuf);
+ for (i = 0; i < NLINES; i++) {
+ cp = &c_uid[IDX(uid, i)];
+ if (!*cp->name) {
+fillit:
+ cp->uid = uid;
+ if ((pw = getpwuid(uid)) == NULL) {
+ snprintf(cp->name, sizeof(cp->name), "%u", uid);
+ cp->noname = 1;
+ } else {
+ strlcpy(cp->name, pw->pw_name, sizeof(cp->name));
+ }
}
- cp->uid = uid;
- strlcpy(cp->name, pw->pw_name, sizeof(cp->name));
+ if (cp->uid == uid) {
+ if (nouser && cp->noname)
+ return NULL;
+ return cp->name;
+ }
+ }
+ /* move everybody down a slot */
+ for (i = 0; i < NLINES - 1; i++) {
+ struct ncache *next;
+
+ cp = &c_uid[IDX(uid, i)];
+ next = &c_uid[IDX(uid, i + 1)];
+ memcpy(next, cp, sizeof(*cp));
}
- return (cp->name);
+ cp = &c_uid[IDX(uid, 0)];
+ goto fillit;
}
char *
@@ -68,22 +88,40 @@ group_from_gid(gid_t gid, int nogroup)
{
static struct ncache {
gid_t gid;
+ short noname;
char name[_PW_NAME_LEN + 1];
- } c_gid[NCACHE];
+ } c_gid[NLINES * NCACHE];
static char nbuf[15]; /* 32 bits == 10 digits */
struct group *gr;
struct ncache *cp;
+ unsigned int i;
- cp = c_gid + (gid & MASK);
- if (cp->gid != gid || !*cp->name) {
- if ((gr = getgrgid(gid)) == NULL) {
- if (nogroup)
- return (NULL);
- (void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
- return (nbuf);
+ for (i = 0; i < NLINES; i++) {
+ cp = &c_gid[IDX(gid, i)];
+ if (!*cp->name) {
+fillit:
+ cp->gid = gid;
+ if ((gr = getgrgid(gid)) == NULL) {
+ snprintf(cp->name, sizeof(cp->name), "%u", gid);
+ cp->noname = 1;
+ } else {
+ strlcpy(cp->name, gr->gr_name, sizeof(cp->name));
+ }
}
- cp->gid = gid;
- strlcpy(cp->name, gr->gr_name, sizeof(cp->name));
+ if (cp->gid == gid) {
+ if (nogroup && cp->noname)
+ return NULL;
+ return cp->name;
+ }
+ }
+ /* move everybody down a slot */
+ for (i = 0; i < NLINES - 1; i++) {
+ struct ncache *next;
+
+ cp = &c_gid[IDX(gid, i)];
+ next = &c_gid[IDX(gid, i + 1)];
+ memcpy(next, cp, sizeof(*cp));
}
- return (cp->name);
+ cp = &c_gid[IDX(gid, 0)];
+ goto fillit;
}