2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h" /* statistics */
18 static struct axscache *afs_axsfreelist = NULL;
20 #define NAXSs (1000 / sizeof(struct axscache))
21 static struct xfreelist {
22 struct xfreelist *next;
23 struct axscache data[NAXSs];
25 static int afs_xaxscnt = 0;
26 afs_rwlock_t afs_xaxs;
28 /* takes an address of an access cache & uid, returns ptr */
29 /* PRECONDITION: first field has been checked and doesn't match!
30 * INVARIANT: isparent(i,j) ^ isparent(j,i) (ie, they switch around)
33 afs_SlowFindAxs(struct axscache **cachep, afs_int32 id)
35 register struct axscache *i, *j;
41 axs_Front(cachep, j, i); /* maintain LRU queue */
45 if ((j = i->next)) { /* ASSIGNMENT HERE! */
47 axs_Front(cachep, i, j);
51 return ((struct axscache *)NULL);
54 return ((struct axscache *)NULL);
61 struct axscache *i, *j;
62 struct xfreelist *h, *xsp;
65 ObtainWriteLock(&afs_xaxs, 174);
66 if ((i = afs_axsfreelist)) {
67 afs_axsfreelist = i->next;
68 ReleaseWriteLock(&afs_xaxs);
71 h = afs_osi_Alloc(sizeof(struct xfreelist));
75 xfreemallocs->next = xsp;
77 for (k = 0; k < NAXSs - 1; k++, i++) {
80 i->next = ++j; /* need j because order of evaluation not defined */
85 afs_axsfreelist = (h->data)->next;
87 ReleaseWriteLock(&afs_xaxs);
92 #define axs_Free(axsp) { \
93 ObtainWriteLock(&afs_xaxs,175); \
94 axsp->next = afs_axsfreelist; \
95 afs_axsfreelist = axsp; \
96 ReleaseWriteLock(&afs_xaxs); \
100 /* I optimize for speed on lookup, and don't give a RIP about delete.
103 afs_RemoveAxs(struct axscache **headp, struct axscache *axsp)
105 struct axscache *i, *j;
107 if (*headp && axsp) { /* is bullet-proofing really neccessary? */
108 if (*headp == axsp) { /* most common case, I think */
123 if ((i = j->next)) { /* ASSIGNMENT HERE! */
130 /* end of "if neither pointer is NULL" */
131 return; /* !#@ FAILED to find it! */
136 * Takes an entire list of access cache structs and prepends them, lock, stock,
137 * and barrel, to the front of the freelist.
140 afs_FreeAllAxs(struct axscache **headp)
142 struct axscache *i, *j;
147 while (i) { /* chase down the list 'til we reach the end */
150 ObtainWriteLock(&afs_xaxs, 176);
151 i->next = afs_axsfreelist; /* tack on the freelist to the end */
152 afs_axsfreelist = *headp;
153 ReleaseWriteLock(&afs_xaxs);
160 if (j) { /* we ran off the end of the list... */
161 ObtainWriteLock(&afs_xaxs, 177);
162 j->next = afs_axsfreelist; /* tack on the freelist to the end */
163 afs_axsfreelist = *headp;
164 ReleaseWriteLock(&afs_xaxs);
171 /* doesn't appear to be used at all */
173 shutdown_xscache(void)
175 struct xfreelist *xp, *nxp;
177 AFS_RWLOCK_INIT(&afs_xaxs, "afs_xaxs");
181 afs_osi_Free(xp, sizeof(struct xfreelist));
184 afs_axsfreelist = NULL;