tests/drmsl: Extract tests out of xf86drmSL.c

v2: merge tests creation and xf86drmSL cleanup
    rename tests/drmsltest -> tests/drmsl
    move the test out of libudev test block
v3: run test even on noudev builds

Signed-off-by: Jan Vesely <jan.vesely@rutgers.edu>
Acked-by: Emil Velikov <emil.l.velikov@gmail.com>
main
Jan Vesely 2015-03-20 16:58:29 -04:00
parent 3b2ee2b5bf
commit 7d8c946408
4 changed files with 184 additions and 169 deletions

1
.gitignore vendored
View File

@ -74,6 +74,7 @@ tdfx.kld
via.kld via.kld
tests/auth tests/auth
tests/dristat tests/dristat
tests/drmsl
tests/drmstat tests/drmstat
tests/getclient tests/getclient
tests/getstats tests/getstats

View File

@ -35,6 +35,9 @@ if HAVE_NOUVEAU
SUBDIRS += nouveau SUBDIRS += nouveau
endif endif
TESTS = \
drmsl
if HAVE_LIBUDEV if HAVE_LIBUDEV
check_LTLIBRARIES = libdrmtest.la check_LTLIBRARIES = libdrmtest.la
@ -52,7 +55,7 @@ XFAIL_TESTS = \
auth \ auth \
lock lock
TESTS = \ TESTS += \
openclose \ openclose \
getversion \ getversion \
getclient \ getclient \
@ -60,7 +63,6 @@ TESTS = \
setversion \ setversion \
updatedraw \ updatedraw \
name_from_fd name_from_fd
endif
check_PROGRAMS += $(TESTS) check_PROGRAMS += $(TESTS)
endif

172
tests/drmsl.c Normal file
View File

@ -0,0 +1,172 @@
/* drmsl.c -- Skip list test
* Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
*
* DESCRIPTION
*
* This file contains a straightforward skip list implementation.n
*
* FUTURE ENHANCEMENTS
*
* REFERENCES
*
* [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
* Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "xf86drm.h"
static void print(void* list)
{
unsigned long key;
void *value;
if (drmSLFirst(list, &key, &value)) {
do {
printf("key = %5lu, value = %p\n", key, value);
} while (drmSLNext(list, &key, &value));
}
}
static double do_time(int size, int iter)
{
void *list;
int i, j;
unsigned long keys[1000000];
unsigned long previous;
unsigned long key;
void *value;
struct timeval start, stop;
double usec;
void *ranstate;
list = drmSLCreate();
ranstate = drmRandomCreate(12345);
for (i = 0; i < size; i++) {
keys[i] = drmRandom(ranstate);
drmSLInsert(list, keys[i], NULL);
}
previous = 0;
if (drmSLFirst(list, &key, &value)) {
do {
if (key <= previous) {
printf( "%lu !< %lu\n", previous, key);
}
previous = key;
} while (drmSLNext(list, &key, &value));
}
gettimeofday(&start, NULL);
for (j = 0; j < iter; j++) {
for (i = 0; i < size; i++) {
if (drmSLLookup(list, keys[i], &value))
printf("Error %lu %d\n", keys[i], i);
}
}
gettimeofday(&stop, NULL);
usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
- start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
printf("%0.2f microseconds for list length %d\n", usec, size);
drmRandomDouble(ranstate);
drmSLDestroy(list);
return usec;
}
static void print_neighbors(void *list, unsigned long key)
{
unsigned long prev_key = 0;
unsigned long next_key = 0;
void *prev_value;
void *next_value;
int retval;
retval = drmSLLookupNeighbors(list, key,
&prev_key, &prev_value,
&next_key, &next_value);
printf("Neighbors of %5lu: %d %5lu %5lu\n",
key, retval, prev_key, next_key);
}
int main(void)
{
void* list;
double usec, usec2, usec3, usec4;
list = drmSLCreate();
printf( "list at %p\n", list);
print(list);
printf("\n==============================\n\n");
drmSLInsert(list, 123, NULL);
drmSLInsert(list, 213, NULL);
drmSLInsert(list, 50, NULL);
print(list);
printf("\n==============================\n\n");
print_neighbors(list, 0);
print_neighbors(list, 50);
print_neighbors(list, 51);
print_neighbors(list, 123);
print_neighbors(list, 200);
print_neighbors(list, 213);
print_neighbors(list, 256);
printf("\n==============================\n\n");
drmSLDelete(list, 50);
print(list);
printf("\n==============================\n\n");
drmSLDump(list);
drmSLDestroy(list);
printf("\n==============================\n\n");
usec = do_time(100, 10000);
usec2 = do_time(1000, 500);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
1000.0/100.0, usec2 / usec);
usec3 = do_time(10000, 50);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
10000.0/100.0, usec3 / usec);
usec4 = do_time(100000, 4);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
100000.0/100.0, usec4 / usec);
return 0;
}

View File

@ -41,13 +41,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define SL_MAIN 0
#if !SL_MAIN
#include "xf86drm.h" #include "xf86drm.h"
#else
# include <sys/time.h>
#endif
#define SL_LIST_MAGIC 0xfacade00LU #define SL_LIST_MAGIC 0xfacade00LU
#define SL_ENTRY_MAGIC 0x00fab1edLU #define SL_ENTRY_MAGIC 0x00fab1edLU
@ -56,21 +50,10 @@
#define SL_DEBUG 0 #define SL_DEBUG 0
#define SL_RANDOM_SEED 0xc01055a1LU #define SL_RANDOM_SEED 0xc01055a1LU
#if SL_MAIN
#define SL_ALLOC malloc
#define SL_FREE free
#define SL_RANDOM_DECL static int state = 0;
#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
#define SL_RANDOM random()
#else
#define SL_ALLOC drmMalloc
#define SL_FREE drmFree
#define SL_RANDOM_DECL static void *state = NULL #define SL_RANDOM_DECL static void *state = NULL
#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed) #define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
#define SL_RANDOM drmRandom(state) #define SL_RANDOM drmRandom(state)
#endif
typedef struct SLEntry { typedef struct SLEntry {
unsigned long magic; /* SL_ENTRY_MAGIC */ unsigned long magic; /* SL_ENTRY_MAGIC */
unsigned long key; unsigned long key;
@ -87,27 +70,13 @@ typedef struct SkipList {
SLEntryPtr p0; /* Position for iteration */ SLEntryPtr p0; /* Position for iteration */
} SkipList, *SkipListPtr; } SkipList, *SkipListPtr;
#if SL_MAIN
extern void *drmSLCreate(void);
extern int drmSLDestroy(void *l);
extern int drmSLLookup(void *l, unsigned long key, void **value);
extern int drmSLInsert(void *l, unsigned long key, void *value);
extern int drmSLDelete(void *l, unsigned long key);
extern int drmSLNext(void *l, unsigned long *key, void **value);
extern int drmSLFirst(void *l, unsigned long *key, void **value);
extern void drmSLDump(void *l);
extern int drmSLLookupNeighbors(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value);
#endif
static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value) static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
{ {
SLEntryPtr entry; SLEntryPtr entry;
if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL; if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
entry = SL_ALLOC(sizeof(*entry) entry = drmMalloc(sizeof(*entry)
+ (max_level + 1) * sizeof(entry->forward[0])); + (max_level + 1) * sizeof(entry->forward[0]));
if (!entry) return NULL; if (!entry) return NULL;
entry->magic = SL_ENTRY_MAGIC; entry->magic = SL_ENTRY_MAGIC;
@ -134,7 +103,7 @@ void *drmSLCreate(void)
SkipListPtr list; SkipListPtr list;
int i; int i;
list = SL_ALLOC(sizeof(*list)); list = drmMalloc(sizeof(*list));
if (!list) return NULL; if (!list) return NULL;
list->magic = SL_LIST_MAGIC; list->magic = SL_LIST_MAGIC;
list->level = 0; list->level = 0;
@ -158,11 +127,11 @@ int drmSLDestroy(void *l)
if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */ if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
next = entry->forward[0]; next = entry->forward[0];
entry->magic = SL_FREED_MAGIC; entry->magic = SL_FREED_MAGIC;
SL_FREE(entry); drmFree(entry);
} }
list->magic = SL_FREED_MAGIC; list->magic = SL_FREED_MAGIC;
SL_FREE(list); drmFree(list);
return 0; return 0;
} }
@ -236,7 +205,7 @@ int drmSLDelete(void *l, unsigned long key)
} }
entry->magic = SL_FREED_MAGIC; entry->magic = SL_FREED_MAGIC;
SL_FREE(entry); drmFree(entry);
while (list->level && !list->head->forward[list->level]) --list->level; while (list->level && !list->head->forward[list->level]) --list->level;
--list->count; --list->count;
@ -348,132 +317,3 @@ void drmSLDump(void *l)
} }
} }
} }
#if SL_MAIN
static void print(SkipListPtr list)
{
unsigned long key;
void *value;
if (drmSLFirst(list, &key, &value)) {
do {
printf("key = %5lu, value = %p\n", key, value);
} while (drmSLNext(list, &key, &value));
}
}
static double do_time(int size, int iter)
{
SkipListPtr list;
int i, j;
unsigned long keys[1000000];
unsigned long previous;
unsigned long key;
void *value;
struct timeval start, stop;
double usec;
SL_RANDOM_DECL;
SL_RANDOM_INIT(12345);
list = drmSLCreate();
for (i = 0; i < size; i++) {
keys[i] = SL_RANDOM;
drmSLInsert(list, keys[i], NULL);
}
previous = 0;
if (drmSLFirst(list, &key, &value)) {
do {
if (key <= previous) {
printf( "%lu !< %lu\n", previous, key);
}
previous = key;
} while (drmSLNext(list, &key, &value));
}
gettimeofday(&start, NULL);
for (j = 0; j < iter; j++) {
for (i = 0; i < size; i++) {
if (drmSLLookup(list, keys[i], &value))
printf("Error %lu %d\n", keys[i], i);
}
}
gettimeofday(&stop, NULL);
usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
- start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
printf("%0.2f microseconds for list length %d\n", usec, size);
drmSLDestroy(list);
return usec;
}
static void print_neighbors(void *list, unsigned long key)
{
unsigned long prev_key = 0;
unsigned long next_key = 0;
void *prev_value;
void *next_value;
int retval;
retval = drmSLLookupNeighbors(list, key,
&prev_key, &prev_value,
&next_key, &next_value);
printf("Neighbors of %5lu: %d %5lu %5lu\n",
key, retval, prev_key, next_key);
}
int main(void)
{
SkipListPtr list;
double usec, usec2, usec3, usec4;
list = drmSLCreate();
printf( "list at %p\n", list);
print(list);
printf("\n==============================\n\n");
drmSLInsert(list, 123, NULL);
drmSLInsert(list, 213, NULL);
drmSLInsert(list, 50, NULL);
print(list);
printf("\n==============================\n\n");
print_neighbors(list, 0);
print_neighbors(list, 50);
print_neighbors(list, 51);
print_neighbors(list, 123);
print_neighbors(list, 200);
print_neighbors(list, 213);
print_neighbors(list, 256);
printf("\n==============================\n\n");
drmSLDelete(list, 50);
print(list);
printf("\n==============================\n\n");
drmSLDump(list);
drmSLDestroy(list);
printf("\n==============================\n\n");
usec = do_time(100, 10000);
usec2 = do_time(1000, 500);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
1000.0/100.0, usec2 / usec);
usec3 = do_time(10000, 50);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
10000.0/100.0, usec3 / usec);
usec4 = do_time(100000, 4);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
100000.0/100.0, usec4 / usec);
return 0;
}
#endif