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
parent
3b2ee2b5bf
commit
7d8c946408
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
172
xf86drmSL.c
172
xf86drmSL.c
|
@ -41,13 +41,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define SL_MAIN 0
|
#include "xf86drm.h"
|
||||||
|
|
||||||
#if !SL_MAIN
|
|
||||||
# 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
|
|
||||||
|
|
Loading…
Reference in New Issue