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"
15 #include "../afs/sysincludes.h" /* Standard vendor system headers */
16 #include "../afs/afsincludes.h" /* Afs-based standard headers */
17 #include "../afs/afs_stats.h" /* statistics */
19 static struct axscache *afs_axsfreelist = NULL;
20 static struct xfreelist { struct xfreelist *next; } *xfreemallocs = 0, *xsp = 0;
22 afs_rwlock_t afs_xaxs;
24 /* takes an address of an access cache & uid, returns ptr */
25 /* PRECONDITION: first field has been checked and doesn't match!
26 * INVARIANT: isparent(i,j) ^ isparent(j,i) (ie, they switch around)
28 struct axscache *afs_SlowFindAxs(cachep,id)
29 struct axscache **cachep;
32 register struct axscache *i,*j;
38 axs_Front(cachep,j,i); /* maintain LRU queue */
42 if (j=i->next) { /* ASSIGNMENT HERE! */
44 axs_Front(cachep,i,j);
48 return ((struct axscache *) NULL);
51 return ((struct axscache *) NULL);
55 #define NAXSs (1000 / sizeof(struct axscache))
56 struct axscache *axs_Alloc()
58 register struct axscache *i, *j, *xsp;
62 ObtainWriteLock(&afs_xaxs,174);
63 if (h = afs_axsfreelist) {
64 afs_axsfreelist = h->next;
66 h=i=j= (struct axscache *) afs_osi_Alloc(NAXSs * sizeof(struct axscache));
68 xsp = (struct axscache *)xfreemallocs;
69 xfreemallocs = (struct xfreelist *)h;
70 xfreemallocs->next = (struct xfreelist *)xsp;
71 for (k = 0; k < NAXSs-1; k++, i++) {
74 i->next = ++j; /* need j because order of evaluation not defined */
79 afs_axsfreelist = h->next;
81 ReleaseWriteLock(&afs_xaxs);
86 #define axs_Free(axsp) { \
87 ObtainWriteLock(&afs_xaxs,175); \
88 axsp->next = afs_axsfreelist; \
89 afs_axsfreelist = axsp; \
90 ReleaseWriteLock(&afs_xaxs); \
94 /* I optimize for speed on lookup, and don't give a RIP about delete.
96 void afs_RemoveAxs(headp, axsp)
97 struct axscache **headp, *axsp;
99 struct axscache *i, *j;
101 if (*headp && axsp) { /* is bullet-proofing really neccessary? */
102 if (*headp == axsp) { /* most common case, I think */
117 if (i = j->next) { /* ASSIGNMENT HERE! */
123 } /* end of "if neither pointer is NULL" */
125 return; /* !#@ FAILED to find it! */
130 * Takes an entire list of access cache structs and prepends them, lock, stock,
131 * and barrel, to the front of the freelist.
133 void afs_FreeAllAxs(headp)
134 struct axscache **headp;
136 struct axscache *i,*j;
141 while (i) { /* chase down the list 'til we reach the end */
144 ObtainWriteLock (&afs_xaxs,176);
145 i->next = afs_axsfreelist; /* tack on the freelist to the end */
146 afs_axsfreelist = *headp;
147 ReleaseWriteLock (&afs_xaxs);
154 if (j) { /* we ran off the end of the list... */
155 ObtainWriteLock (&afs_xaxs,177);
156 j->next = afs_axsfreelist; /* tack on the freelist to the end */
157 afs_axsfreelist = *headp;
158 ReleaseWriteLock (&afs_xaxs);
165 void shutdown_xscache()
167 struct xfreelist *xp, *nxp;
169 RWLOCK_INIT(&afs_xaxs, "afs_xaxs");
173 afs_osi_Free((char *)xp, NAXSs * sizeof(struct axscache));
176 afs_axsfreelist = NULL;