iBoot/drivers/flash_nand/benchmark/L2V_Test.c

209 lines
4.5 KiB
C

/*
* Copyright (c) 2009 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include "L2V.h"
#include "L2V_Funcs.h"
#include "L2V_Print.h"
//#include <stdio.h>
//#include <stdlib.h>
L2V_t L2V;
#define LAST_TREE_TEST 16
#define SIMPLE_SIZE (L2V_TREE_SIZE*LAST_TREE_TEST)
// Prototypes
static void RandomTest(void);
static void SequentialTest(void);
static void Simple_Init(void);
static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn);
static void Simple_Lookup(UInt32 lba, UInt32 *vpn);
static void Seed_Local_Rand(UInt32 seed);
static UInt32 Get_Local_Rand(void);
static UInt32 _current_rand = 0;
void Usage(int argc, char** argv)
{
printf("Usage: %s s OR %s r (for sequential and random, respectively\n", argv[0], argv[0]);
exit(-1);
}
int test = 0;
#if 0
int main(int argc, char** argv)
{
L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192);
if (argc == 2) {
if ('r' == argv[1][0]) {
test = 0;
} else if ('s' == argv[1][0]) {
test = 1;
} else {
Usage(argc, argv);
}
}
if (argc > 2) {
Usage(argc, argv);
}
if (0 == test) {
RandomTest();
} else {
SequentialTest();
}
return 0;
}
#endif
#define MAXLEN 512
void L2VRandomTest() {
UInt32 lba, size, vpn;
UInt32 i;
L2V_SearchCtx_t c;
UInt32 iterations = 1000000;
L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192);
L2V_Search_Init(&c);
Seed_Local_Rand(12345);
while (iterations--) {
lba = Get_Local_Rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN);
size = (Get_Local_Rand() % (MAXLEN-1))+1;
vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1);
// 1 write
L2V_Update(lba, size, vpn);
// 5 reads
for (i = 0; i < 5; ++i)
{
c.lba = Get_Local_Rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN);
L2V_Search(&c);
}
}
}
static void SequentialTest() {
UInt32 lba, size, vpn;
UInt32 i, svpn;
L2V_SearchCtx_t c;
L2V_Search_Init(&c);
Simple_Init();
Seed_Local_Rand(12345);
lba = 0;
size = 0;
vpn = 1;
while (1) {
lba += size;
size = (Get_Local_Rand() % (MAXLEN-1))+1;
if ((lba + size) >= L2V_TREE_SIZE) {
lba = 0;
}
if ((Get_Local_Rand() & 3) == 0) {
vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1);
}
while (((vpn + size) & ((1<<(L2V_BITS_VPN-1))-1)) < vpn) {
vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1);
}
printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn);
L2V_Update(lba, size, vpn);
Simple_Update(lba, size, vpn);
L2V_PrintUsage(0);
vpn += size;
// Validate entire range
unsigned int maxlevel=0;
for (i = 0; i < SIMPLE_SIZE; i++) {
Simple_Lookup(i, &svpn);
c.lba = i;
L2V_Search(&c);
if (c.level > maxlevel) maxlevel = c.level;
if (svpn != c.vpn) {
printf("\n\n\n");
printf("====================\n");
printf("MISMATCH lba:%d\n", i);
printf("--------------------\n");
printf("Simple vpn:%d\n", svpn);
printf("Lookup vpn:%d\n", c.vpn);
}
l2v_assert_eq(svpn, c.vpn);
}
printf("maxlevel: %d\n", maxlevel);
l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH);
}
}
UInt32 Simple_vpn[SIMPLE_SIZE];
static void Simple_Init()
{
UInt32 i;
for (i = 0; i < SIMPLE_SIZE; i++) {
Simple_vpn[i] = L2V_VPN_MISS;
}
}
static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn)
{
while (size) {
Simple_vpn[lba] = vpn;
// Iterate
lba++;
if (vpn < L2V_VPN_SPECIAL) {
vpn++;
}
size--;
}
}
static void Simple_Lookup(UInt32 lba, UInt32 *vpn)
{
*vpn = Simple_vpn[lba];
}
static void Seed_Local_Rand(UInt32 seed)
{
_current_rand = seed;
}
static UInt32 Get_Local_Rand(void)
{
int i;
for (i = 0; i < 17; ++i)
{
_current_rand = (_current_rand >> 1) ^ (UInt32)((0 - (_current_rand & 1u)) & 0xd0000001u);
}
return _current_rand;
}