* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: rz3_lruhash.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* fully-associative cache with lru replacement
struct rz3_lruhash_elem
{
fprintf(stderr
, "warning: rz3_lruhash: rz3_lruhash_elem key not set\n");
fprintf(stderr
, "warning: rz3_lruhash: rz3_lruhash_elem key already set\n");
// "k" is equivalent to a java "final" variable - write once
int k
; // "key", which is an index into a linear array in this implementation
// size must be a power of 2
rz3_lruhash(int arg_size
) {
arr
= new rz3_lruhash_elem
[size
];
searchtbl
= new rz3_lruhash_elem
* [size
];
refs
= misses
= searchtbl_hits
= 0;
bzero(searchtbl
, size
*sizeof(rz3_lruhash_elem
*));
rz3_lruhash_elem
* elem
= arr
+i
;
elem
->prev
= (elem
== newest
) ? NULL
: arr
+(i
-1);
elem
->next
= (elem
== oldest
) ? NULL
: arr
+(i
+1);
searchtbl
[search_idx_fn(elem
->v
)] = elem
;
} // rz3_lruhash(int arg_size)
// returns a "key" whose value is [0 .. size-1]
// and whose size is CEIL(log2(arg_size)) bits
bool Update(uint64_t v
, int & k
) {
int searchidx
= search_idx_fn(v
);
if ((searchtbl
[searchidx
] != NULL
) && (searchtbl
[searchidx
]->v
== v
)) {
k
= searchtbl
[searchidx
]->GetKey();
searchtbl
[searchidx
] = &(arr
[k
]);
} // int Update(uint64_t v)
// if key is good, stores corresponding value in v and returns true. also brings (key,v) to the front of the MRU list
// returns false otherwise
bool Get(int key
, uint64_t & v
) {
if ((key
< 0) || (key
>= size
)) return false;
BringToFront(&(arr
[key
]));
int searchidx
= search_idx_fn(v
);
searchtbl
[searchidx
] = &(arr
[key
]);
} // bool Get(int key, uint64_t & v)
void BringToFront(rz3_lruhash_elem
* elem
) {
if (elem
== newest
) return;
elem
->prev
->next
= elem
->next
;
if (elem
->next
== NULL
) {
elem
->next
->prev
= elem
->prev
;
int search_idx_fn(uint64_t v
) {
return (v
& (size
-1)) ^ ((v
>> idxbits
) & (size
-1));
fprintf(fp
, "refs %lld misses %lld (%0.4f%%/ref)\n", refs
, misses
, misses
*100.0/refs
);
uint64_t hits
= refs
-misses
;
fprintf(fp
, " fasthits %lld (%0.4f%%/hit, %0.4f%%/ref)\n", searchtbl_hits
, searchtbl_hits
*100.0/hits
, searchtbl_hits
*100.0/refs
);
rz3_lruhash_elem
* newest
;
rz3_lruhash_elem
* oldest
;
rz3_lruhash_elem
** searchtbl
; // search here first. if fails, search entire list
#endif // _rz3_lruhash_h_