check for text mounted /tmp and print a warning

This commit is contained in:
Alexander Gottwald 2004-06-24 20:21:59 +00:00
parent 4b3209ede1
commit 6874ff3ec6
9 changed files with 1864 additions and 0 deletions

147
GL/mesa/X/xf86glx_util.c Normal file
View file

@ -0,0 +1,147 @@
/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glx_util.c,v 1.5 2000/03/02 16:07:39 martin Exp $ */
/**************************************************************************
Copyright 1998-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, sub license, 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 NON-INFRINGEMENT.
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:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
*/
#include <gcstruct.h>
#include "pixmapstr.h"
#include "xf86glx_util.h"
#include <X11/Xmd.h>
#include "GL/xf86glx.h"
#ifdef ROUNDUP
#undef ROUNDUP
#endif
#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data)
{
XMesaImage *image;
image = (XMesaImage *)xalloc(sizeof(XMesaImage));
if (image) {
image->width = width;
image->height = height;
image->data = data;
/* Always pad to 32 bits */
image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32);
image->bits_per_pixel = bitsPerPixel;
}
return image;
}
void XMesaDestroyImage(XMesaImage *image)
{
if (image->data)
free(image->data);
xfree(image);
}
unsigned long XMesaGetPixel(XMesaImage *image, int x, int y)
{
CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
CARD8 *i8;
CARD16 *i16;
CARD32 *i32;
switch (image->bits_per_pixel) {
case 8:
i8 = (CARD8 *)row;
return i8[x];
break;
case 15:
case 16:
i16 = (CARD16 *)row;
return i16[x];
break;
case 24: /* WARNING: architecture specific code */
i8 = (CARD8 *)row;
return (((CARD32)i8[x*3]) |
(((CARD32)i8[x*3+1])<<8) |
(((CARD32)i8[x*3+2])<<16));
break;
case 32:
i32 = (CARD32 *)row;
return i32[x];
break;
}
return 0;
}
#ifndef XMESA_USE_PUTPIXEL_MACRO
void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel)
{
CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
CARD8 *i8;
CARD16 *i16;
CARD32 *i32;
switch (image->bits_per_pixel) {
case 8:
i8 = (CARD8 *)row;
i8[x] = (CARD8)pixel;
break;
case 15:
case 16:
i16 = (CARD16 *)row;
i16[x] = (CARD16)pixel;
break;
case 24: /* WARNING: architecture specific code */
i8 = (CARD8 *)__row;
i8[x*3] = (CARD8)(p);
i8[x*3+1] = (CARD8)(p>>8);
i8[x*3+2] = (CARD8)(p>>16);
case 32:
i32 = (CARD32 *)row;
i32[x] = (CARD32)pixel;
break;
}
}
#endif
void XMesaPutImageHelper(ScreenPtr display,
DrawablePtr d, GCPtr gc,
XMesaImage *image,
int src_x, int src_y,
int dest_x, int dest_y,
unsigned int width, unsigned int height)
{
/* NOT_DONE: Verify that the following works for all depths */
char *src = (image->data +
src_y * image->bytes_per_line +
((src_x * image->bits_per_pixel) >> 3));
ValidateGC(d, gc);
(*gc->ops->PutImage)(d, gc, d->depth, dest_x, dest_y, width, height,
0, ZPixmap, src);
}

102
GL/mesa/X/xf86glx_util.h Normal file
View file

@ -0,0 +1,102 @@
/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glx_util.h,v 1.5 2000/08/10 17:40:29 dawes Exp $ */
/**************************************************************************
Copyright 1998-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, sub license, 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 NON-INFRINGEMENT.
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:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
*/
#ifndef _XF86GLX_UTIL_H_
#define _XF86GLX_UTIL_H_
#ifdef __CYGWIN__
#undef WIN32
#undef _WIN32
#endif
#include <screenint.h>
#include <pixmap.h>
#include <gc.h>
#include "GL/xmesa.h"
#define XMESA_USE_PUTPIXEL_MACRO
struct _XMesaImageRec {
int width, height;
char *data;
int bytes_per_line; /* Padded to 32 bits */
int bits_per_pixel;
};
extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height,
char *data);
extern void XMesaDestroyImage(XMesaImage *image);
extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y);
#ifdef XMESA_USE_PUTPIXEL_MACRO
#define XMesaPutPixel(__i,__x,__y,__p) \
{ \
CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \
CARD8 *__i8; \
CARD16 *__i16; \
CARD32 *__i32; \
switch (__i->bits_per_pixel) { \
case 8: \
__i8 = (CARD8 *)__row; \
__i8[__x] = (CARD8)__p; \
break; \
case 15: \
case 16: \
__i16 = (CARD16 *)__row; \
__i16[__x] = (CARD16)__p; \
break; \
case 24: /* WARNING: architecture specific code */ \
__i8 = (CARD8 *)__row; \
__i8[__x*3] = (CARD8)(__p); \
__i8[__x*3+1] = (CARD8)(__p>>8); \
__i8[__x*3+2] = (CARD8)(__p>>16); \
break; \
case 32: \
__i32 = (CARD32 *)__row; \
__i32[__x] = (CARD32)__p; \
break; \
} \
}
#else
extern void XMesaPutPixel(XMesaImage *image, int x, int y,
unsigned long pixel);
#endif
extern void XMesaPutImageHelper(ScreenPtr display,
DrawablePtr d, GCPtr gc,
XMesaImage *image,
int src_x, int src_y,
int dest_x, int dest_y,
unsigned int width, unsigned int height);
#endif /* _XF86GLX_UTIL_H_ */

115
GL/mesa/X/xf86glxint.h Normal file
View file

@ -0,0 +1,115 @@
/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glxint.h,v 1.4 2002/02/22 21:45:08 dawes Exp $ */
/**************************************************************************
Copyright 1998-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, sub license, 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 NON-INFRINGEMENT.
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:
* Kevin E. Martin <kevin@precisioninsight.com>
*
*/
#ifndef _XF86GLXINT_H_
#define _XF86GLXINT_H_
#include <miscstruct.h>
#include <GL/gl.h>
#include <GL/xmesa.h>
typedef struct __MESA_screenRec __MESA_screen;
struct __MESA_screenRec {
int num_vis;
__GLcontextModes *modes;
XMesaVisual *xm_vis;
void **private;
};
typedef struct __MESA_bufferRec *__MESA_buffer;
struct __MESA_bufferRec {
XMesaBuffer xm_buf;
GLboolean (*fbresize)(__GLdrawableBuffer *buf,
GLint x, GLint y, GLuint width, GLuint height,
__GLdrawablePrivate *glPriv, GLuint bufferMask);
GLboolean (*fbswap)(__GLXdrawablePrivate *glxPriv);
};
extern void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
void **privates);
extern Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp, int *rootDepthp,
VisualID *defaultVisp, unsigned long sizes,
int bitsPerRGB);
extern Bool __MESA_screenProbe(int screen);
extern void __MESA_resetExtension(void);
extern void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv);
extern GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buf,
GLint x, GLint y,
GLuint width, GLuint height,
__GLdrawablePrivate *glPriv,
GLuint bufferMask);
extern GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv);
extern void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv);
extern __GLinterface *__MESA_createContext(__GLimports *imports,
__GLcontextModes *modes,
__GLinterface *shareGC);
extern GLboolean __MESA_destroyContext(__GLcontext *gc);
extern GLboolean __MESA_loseCurrent(__GLcontext *gc);
extern GLboolean __MESA_makeCurrent(__GLcontext *gc);
extern GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare);
extern GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
GLuint mask);
extern GLboolean __MESA_forceCurrent(__GLcontext *gc);
extern GLboolean __MESA_notifyResize(__GLcontext *gc);
extern void __MESA_notifyDestroy(__GLcontext *gc);
extern void __MESA_notifySwapBuffers(__GLcontext *gc);
extern struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc);
extern void __MESA_beginDispatchOverride(__GLcontext *gc);
extern void __MESA_endDispatchOverride(__GLcontext *gc);
extern GLint __glCallLists_size(GLsizei n, GLenum type);
extern GLint __glEvalComputeK(GLenum target);
extern GLuint __glFloorLog2(GLuint val);
extern GLint __glFogfv_size(GLenum pname);
extern GLint __glFogiv_size(GLenum pname);
extern GLint __glLightModelfv_size(GLenum pname);
extern GLint __glLightModeliv_size(GLenum pname);
extern GLint __glLightfv_size(GLenum pname);
extern GLint __glLightiv_size(GLenum pname);
extern GLint __glMaterialfv_size(GLenum pname);
extern GLint __glMaterialiv_size(GLenum pname);
extern GLint __glTexEnvfv_size(GLenum pname);
extern GLint __glTexEnviv_size(GLenum pname);
extern GLint __glTexGendv_size(GLenum pname);
extern GLint __glTexGenfv_size(GLenum pname);
extern GLint __glTexGeniv_size(GLenum pname);
extern GLint __glTexParameterfv_size(GLenum pname);
extern GLint __glTexParameteriv_size(GLenum pname);
#endif /* _XF86GLXINT_H_ */

200
Xprint/spooler.c Normal file
View file

@ -0,0 +1,200 @@
/* $Xorg: spooler.c,v 1.1 2003/09/14 1:19:56 gisburn Exp $ */
/*
Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
Copyright (c) 2004 Sun Microsystems, Inc.
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 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 THE
COPYRIGHT HOLDERS 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.
Except as contained in this notice, the names of the copyright holders shall
not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from said
copyright holders.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#ifdef __hpux
#include <sys/sysmacros.h>
#endif
#include "spooler.h"
/*
* The string LIST_QUEUES_* is fed to a shell to generate an ordered
* list of available printers on the system. These string definitions
* are taken from the file PrintSubSys.C within the code for the
* dtprintinfo program.
*/
#define LIST_QUEUES_AIX4 \
"lsallq | grep -v '^bsh$' | sort | uniq"
#define LIST_QUEUES_HPUX \
"LANG=C lpstat -v | " \
"awk '" \
" $2 == \"for\" " \
" { " \
" x = match($3, /:/); " \
" print substr($3, 1, x-1)" \
" }' | sort | uniq"
#define LIST_QUEUES_OSF \
"LANG=C lpstat -v | " \
"nawk '" \
" $2 == \"for\" " \
" { print $4 }' " \
" | sort | uniq"
#define LIST_QUEUES_UXP \
"LANG=C lpstat -v |" \
"nawk '" \
" $4 == \"for\" " \
" { " \
" x = match($5, /:/); " \
" print substr($5, 1, x-1)" \
" }' | sort | uniq"
/* Support both normal and LPRng output of "lpc status" */
#define LIST_QUEUES_BSD \
"PATH=\"${PATH}:/usr/bin:/usr/sbin:/bin:/sbin\"\n" \
"export PATH\n" \
\
"which_tool()\n" \
"{\n" \
" echo \"${PATH}\" | tr \":\" \"\n\" | while read i ; do ls -1ad \"${i}/${1}\" 2>/dev/null ; done\n" \
"}\n" \
\
"(\n" \
"WHICH_LPC=\"`which_tool lpc`\"\n" \
\
"if [ \"`which_tool nawk`\" != \"\" ] ; then\n" \
" NAWK=\"nawk\"\n" \
"else\n" \
" NAWK=\"awk\"\n" \
"fi\n" \
\
"[ \"${WHICH_LPC}\" != \"\" ] && (LANG=C lpc status | ${NAWK} '/^[^ ]*:$/ && !/@/ && !/ / { print $1 }' | sed -e /:/s///)\n" \
"[ \"${WHICH_LPC}\" != \"\" ] && (LANG=C lpc -a status | ${NAWK} '/^[^ ]*@[^ ]/ && !/:$/ { split( $1, name, \"@\" ); print name[1]; }')\n" \
") | egrep -v -i \" |^all$\" | sort | uniq"
#define LIST_QUEUES_SYSV \
"PATH=\"${PATH}:/usr/bin:/usr/sbin:/bin:/sbin\"\n" \
"export PATH\n" \
\
"which_tool()\n" \
"{\n" \
" echo \"${PATH}\" | tr \":\" \"\n\" | while read i ; do ls -1ad \"${i}/${1}\" 2>/dev/null ; done\n" \
"}\n" \
\
"(\n" \
"WHICH_LPSTAT=\"`which_tool lpstat`\"\n" \
\
"if [ \"`which_tool nawk`\" != \"\" ] ; then\n" \
" NAWK=\"nawk\"\n" \
"else\n" \
" NAWK=\"awk\"\n" \
"fi\n" \
\
"[ \"${WHICH_LPSTAT}\" != \"\" ] && (LANG=C lpstat -v | ${NAWK} ' $2 == \"for\" { x = match($3, /:/); print substr($3, 1, x-1) }')\n" \
") | egrep -v -i \" |^all$\" | sort | uniq"
#define LIST_QUEUES_SOLARIS "LANG=C lpget -k description " \
"`lpstat -v " \
"| nawk '$2 == \"for\" { x = match($3, /:/); print substr($3, 1,x-1) }' " \
"| sort -u` " \
"| nawk -F: ' NF == 2 { name=$1 } " \
" NF == 1 { sub(\"^.*description\\( - undefined|=\\)\",\"\"); " \
" printf \"%sxp-printerattr.descriptor=%s\\n\", name, $1 } '"
#define LIST_QUEUES_OTHER \
"LANG=C lpstat -v | " \
"nawk '" \
" $2 == \"for\" " \
" { " \
" x = match($3, /:/); " \
" print substr($3, 1, x-1)" \
" }' | sort | uniq"
#define DEFAULT_SPOOL_COMMAND_HPUX "/usr/bin/lp -d %printer-name% -o raw -n %copy-count% -t %job-name% %options%"
#define DEFAULT_SPOOL_COMMAND_BSD "/usr/bin/lpr -P %printer-name% -#%copy-count% -T %job-name% %options%"
#define DEFAULT_SPOOL_COMMAND_SYSV "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
#define DEFAULT_SPOOL_COMMAND_SOLARIS "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
#define DEFAULT_SPOOL_COMMAND_OTHER "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
/* List of spooler types and the commands used to enumerate
* print queues and submit print jobs */
XpSpoolerType xpstm[] =
{
/* OS-specific spoolers */
{ "aix", LIST_QUEUES_AIX4, DEFAULT_SPOOL_COMMAND_OTHER },
{ "aix4", LIST_QUEUES_AIX4, DEFAULT_SPOOL_COMMAND_OTHER },
{ "bsd", LIST_QUEUES_BSD, DEFAULT_SPOOL_COMMAND_BSD },
{ "osf", LIST_QUEUES_OSF, DEFAULT_SPOOL_COMMAND_OTHER },
{ "solaris", LIST_QUEUES_SOLARIS, DEFAULT_SPOOL_COMMAND_SOLARIS },
{ "sysv", LIST_QUEUES_SYSV, DEFAULT_SPOOL_COMMAND_SYSV },
{ "uxp", LIST_QUEUES_UXP, DEFAULT_SPOOL_COMMAND_OTHER },
/* crossplatform spoolers */
{ "cups", LIST_QUEUES_SYSV, DEFAULT_SPOOL_COMMAND_SYSV },
{ "lprng", LIST_QUEUES_BSD, DEFAULT_SPOOL_COMMAND_BSD },
/* misc */
{ "other", LIST_QUEUES_OTHER, DEFAULT_SPOOL_COMMAND_OTHER },
{ "none", NULL, NULL },
{ NULL, NULL, NULL }
};
/* Used by Init.c and attributes.c */
XpSpoolerTypePtr spooler_type = NULL;
XpSpoolerTypePtr XpSpoolerNameToXpSpoolerType(char *name)
{
XpSpoolerTypePtr curr = xpstm;
while( curr->name != NULL )
{
if( !strcasecmp(name, curr->name) )
return curr;
curr++;
}
return NULL;
}
static char *spooler_namelist = NULL;
char *XpGetSpoolerTypeNameList(void)
{
if( spooler_namelist )
return spooler_namelist;
return XPDEFAULTSPOOLERNAMELIST;
}
void XpSetSpoolerTypeNameList(char *namelist)
{
spooler_namelist = namelist;
}

View file

@ -0,0 +1,435 @@
/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
* Created: Sun Apr 18 09:35:45 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>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
*
* DESCRIPTION
*
* This file contains a straightforward implementation of a fixed-sized
* hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
* collision resolution. There are two potentially interesting things
* about this implementation:
*
* 1) The table is power-of-two sized. Prime sized tables are more
* traditional, but do not have a significant advantage over power-of-two
* sized table, especially when double hashing is not used for collision
* resolution.
*
* 2) The hash computation uses a table of random integers [Hanson97,
* pp. 39-41].
*
* FUTURE ENHANCEMENTS
*
* With a table size of 512, the current implementation is sufficient for a
* few hundred keys. Since this is well above the expected size of the
* tables for which this implementation was designed, the implementation of
* dynamic hash tables was postponed until the need arises. A common (and
* naive) approach to dynamic hash table implementation simply creates a
* new hash table when necessary, rehashes all the data into the new table,
* and destroys the old table. The approach in [Larson88] is superior in
* two ways: 1) only a portion of the table is expanded when needed,
* distributing the expansion cost over several insertions, and 2) portions
* of the table can be locked, enabling a scalable thread-safe
* implementation.
*
* REFERENCES
*
* [Hanson97] David R. Hanson. C Interfaces and Implementations:
* Techniques for Creating Reusable Software. Reading, Massachusetts:
* Addison-Wesley, 1997.
*
* [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
* Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
*
* [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
* 1988, pp. 446-457.
*
*/
#define HASH_MAIN 0
#if HASH_MAIN
# include <stdio.h>
# include <stdlib.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define HASH_MAGIC 0xdeadbeef
#define HASH_DEBUG 0
#define HASH_SIZE 512 /* Good for about 100 entries */
/* If you change this value, you probably
have to change the HashHash hashing
function! */
#if HASH_MAIN
#define HASH_ALLOC malloc
#define HASH_FREE free
#define HASH_RANDOM_DECL
#define HASH_RANDOM_INIT(seed) srandom(seed)
#define HASH_RANDOM random()
#else
#define HASH_ALLOC drmMalloc
#define HASH_FREE drmFree
#define HASH_RANDOM_DECL void *state
#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
#define HASH_RANDOM drmRandom(state)
#endif
typedef struct HashBucket {
unsigned long key;
void *value;
struct HashBucket *next;
} HashBucket, *HashBucketPtr;
typedef struct HashTable {
unsigned long magic;
unsigned long entries;
unsigned long hits; /* At top of linked list */
unsigned long partials; /* Not at top of linked list */
unsigned long misses; /* Not in table */
HashBucketPtr buckets[HASH_SIZE];
int p0;
HashBucketPtr p1;
} HashTable, *HashTablePtr;
#if HASH_MAIN
extern void *N(HashCreate)(void);
extern int N(HashDestroy)(void *t);
extern int N(HashLookup)(void *t, unsigned long key, unsigned long *value);
extern int N(HashInsert)(void *t, unsigned long key, unsigned long value);
extern int N(HashDelete)(void *t, unsigned long key);
#endif
static unsigned long HashHash(unsigned long key)
{
unsigned long hash = 0;
unsigned long tmp = key;
static int init = 0;
static unsigned long scatter[256];
int i;
if (!init) {
HASH_RANDOM_DECL;
HASH_RANDOM_INIT(37);
for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
++init;
}
while (tmp) {
hash = (hash << 1) + scatter[tmp & 0xff];
tmp >>= 8;
}
hash %= HASH_SIZE;
#if HASH_DEBUG
printf( "Hash(%d) = %d\n", key, hash);
#endif
return hash;
}
void *N(HashCreate)(void)
{
HashTablePtr table;
int i;
table = HASH_ALLOC(sizeof(*table));
if (!table) return NULL;
table->magic = HASH_MAGIC;
table->entries = 0;
table->hits = 0;
table->partials = 0;
table->misses = 0;
for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
return table;
}
int N(HashDestroy)(void *t)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
HashBucketPtr next;
int i;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
for (i = 0; i < HASH_SIZE; i++) {
for (bucket = table->buckets[i]; bucket;) {
next = bucket->next;
HASH_FREE(bucket);
bucket = next;
}
}
HASH_FREE(table);
return 0;
}
/* Find the bucket and organize the list so that this bucket is at the
top. */
static HashBucketPtr HashFind(HashTablePtr table,
unsigned long key, unsigned long *h)
{
unsigned long hash = HashHash(key);
HashBucketPtr prev = NULL;
HashBucketPtr bucket;
if (h) *h = hash;
for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
if (bucket->key == key) {
if (prev) {
/* Organize */
prev->next = bucket->next;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
++table->partials;
} else {
++table->hits;
}
return bucket;
}
prev = bucket;
}
++table->misses;
return NULL;
}
int N(HashLookup)(void *t, unsigned long key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
bucket = HashFind(table, key, NULL);
if (!bucket) return 1; /* Not found */
*value = bucket->value;
return 0; /* Found */
}
int N(HashInsert)(void *t, unsigned long key, void *value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
unsigned long hash;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (HashFind(table, key, &hash)) return 1; /* Already in table */
bucket = HASH_ALLOC(sizeof(*bucket));
if (!bucket) return -1; /* Error */
bucket->key = key;
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
#if HASH_DEBUG
printf("Inserted %d at %d/%p\n", key, hash, bucket);
#endif
return 0; /* Added to table */
}
int N(HashDelete)(void *t, unsigned long key)
{
HashTablePtr table = (HashTablePtr)t;
unsigned long hash;
HashBucketPtr bucket;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
bucket = HashFind(table, key, &hash);
if (!bucket) return 1; /* Not found */
table->buckets[hash] = bucket->next;
HASH_FREE(bucket);
return 0;
}
int N(HashNext)(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
for (; table->p0 < HASH_SIZE;
++table->p0, table->p1 = table->buckets[table->p0]) {
if (table->p1) {
*key = table->p1->key;
*value = table->p1->value;
table->p1 = table->p1->next;
return 1;
}
}
return 0;
}
int N(HashFirst)(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
table->p0 = 0;
table->p1 = table->buckets[0];
return N(HashNext)(table, key, value);
}
#if HASH_MAIN
#define DIST_LIMIT 10
static int dist[DIST_LIMIT];
static void clear_dist(void) {
int i;
for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
}
static int count_entries(HashBucketPtr bucket)
{
int count = 0;
for (; bucket; bucket = bucket->next) ++count;
return count;
}
static void update_dist(int count)
{
if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
else ++dist[count];
}
static void compute_dist(HashTablePtr table)
{
int i;
HashBucketPtr bucket;
printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
table->entries, table->hits, table->partials, table->misses);
clear_dist();
for (i = 0; i < HASH_SIZE; i++) {
bucket = table->buckets[i];
update_dist(count_entries(bucket));
}
for (i = 0; i < DIST_LIMIT; i++) {
if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
else printf("other %10d\n", dist[i]);
}
}
static void check_table(HashTablePtr table,
unsigned long key, unsigned long value)
{
unsigned long retval = 0;
int retcode = N(HashLookup)(table, key, &retval);
switch (retcode) {
case -1:
printf("Bad magic = 0x%08lx:"
" key = %lu, expected = %lu, returned = %lu\n",
table->magic, key, value, retval);
break;
case 1:
printf("Not found: key = %lu, expected = %lu returned = %lu\n",
key, value, retval);
break;
case 0:
if (value != retval)
printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
key, value, retval);
break;
default:
printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
retcode, key, value, retval);
break;
}
}
int main(void)
{
HashTablePtr table;
int i;
printf("\n***** 256 consecutive integers ****\n");
table = N(HashCreate)();
for (i = 0; i < 256; i++) N(HashInsert)(table, i, i);
for (i = 0; i < 256; i++) check_table(table, i, i);
for (i = 256; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 consecutive integers ****\n");
table = N(HashCreate)();
for (i = 0; i < 1024; i++) N(HashInsert)(table, i, i);
for (i = 0; i < 1024; i++) check_table(table, i, i);
for (i = 1024; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
table = N(HashCreate)();
for (i = 0; i < 1024; i++) N(HashInsert)(table, i*4096, i);
for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 random integers ****\n");
table = N(HashCreate)();
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) N(HashInsert)(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 5000 random integers ****\n");
table = N(HashCreate)();
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) N(HashInsert)(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
compute_dist(table);
N(HashDestroy)(table);
return 0;
}
#endif

View file

@ -0,0 +1,219 @@
/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
* Created: Mon Apr 19 08: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>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 2000/06/17 00:03:34 martin Exp $
*
* DESCRIPTION
*
* This file contains a simple, straightforward implementation of the Park
* & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
* multiplicative linear congruential generator (MLCG) with a period of
* 2^31-1.
*
* This implementation is intended to provide a reliable, portable PRNG
* that is suitable for testing a hash table implementation and for
* implementing skip lists.
*
* FUTURE ENHANCEMENTS
*
* If initial seeds are not selected randomly, two instances of the PRNG
* can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
* that can eliminate this problem.
*
* If PRNGs are used for simulation, the period of the current
* implementation may be too short. [LE88] discusses methods of combining
* MLCGs to produce much longer periods, and suggests some alternative
* values for A and M. [LE90 and Sch92] also provide information on
* long-period PRNGs.
*
* REFERENCES
*
* [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
* Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
*
* [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
* Generators". CACM 31(6), June 1988, pp. 742-774.
*
* [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
* October 1990, pp. 85-97.
*
* [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
* Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
*
* [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
* CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
*
* [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
* "Technical Correspondence: Remarks on Choosing and Implementing Random
* Number Generators". CACM 36(7), July 1993, pp. 105-110.
*
*/
#define RANDOM_MAIN 0
#if RANDOM_MAIN
# include <stdio.h>
# include <stdlib.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define RANDOM_MAGIC 0xfeedbeef
#define RANDOM_DEBUG 0
#if RANDOM_MAIN
#define RANDOM_ALLOC malloc
#define RANDOM_FREE free
#else
#define RANDOM_ALLOC drmMalloc
#define RANDOM_FREE drmFree
#endif
typedef struct RandomState {
unsigned long magic;
unsigned long a;
unsigned long m;
unsigned long q; /* m div a */
unsigned long r; /* m mod a */
unsigned long check;
long seed;
} RandomState;
#if RANDOM_MAIN
extern void *N(RandomCreate)(unsigned long seed);
extern int N(RandomDestroy)(void *state);
extern unsigned long N(Random)(void *state);
extern double N(RandomDouble)(void *state);
#endif
void *N(RandomCreate)(unsigned long seed)
{
RandomState *state;
state = RANDOM_ALLOC(sizeof(*state));
if (!state) return NULL;
state->magic = RANDOM_MAGIC;
#if 0
/* Park & Miller, October 1988 */
state->a = 16807;
state->m = 2147483647;
state->check = 1043618065; /* After 10000 iterations */
#else
/* Park, Miller, and Stockmeyer, July 1993 */
state->a = 48271;
state->m = 2147483647;
state->check = 399268537; /* After 10000 iterations */
#endif
state->q = state->m / state->a;
state->r = state->m % state->a;
state->seed = seed;
/* Check for illegal boundary conditions,
and choose closest legal value. */
if (state->seed <= 0) state->seed = 1;
if (state->seed >= state->m) state->seed = state->m - 1;
return state;
}
int N(RandomDestroy)(void *state)
{
RANDOM_FREE(state);
return 0;
}
unsigned long N(Random)(void *state)
{
RandomState *s = (RandomState *)state;
long hi;
long lo;
hi = s->seed / s->q;
lo = s->seed % s->q;
s->seed = s->a * lo - s->r * hi;
if (s->seed <= 0) s->seed += s->m;
return s->seed;
}
double N(RandomDouble)(void *state)
{
RandomState *s = (RandomState *)state;
return (double)N(Random)(state)/(double)s->m;
}
#if RANDOM_MAIN
static void check_period(long seed)
{
unsigned long count = 0;
unsigned long initial;
void *state;
state = N(RandomCreate)(seed);
initial = N(Random)(state);
++count;
while (initial != N(Random)(state)) {
if (!++count) break;
}
printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
seed, count, count);
N(RandomDestroy)(state);
}
int main(void)
{
RandomState *state;
int i;
unsigned long rand;
state = N(RandomCreate)(1);
for (i = 0; i < 10000; i++) {
rand = N(Random)(state);
}
printf("After 10000 iterations: %lu (%lu expected): %s\n",
rand, state->check,
rand - state->check ? "*INCORRECT*" : "CORRECT");
N(RandomDestroy)(state);
printf("Checking periods...\n");
check_period(1);
check_period(2);
check_period(31415926);
return 0;
}
#endif

View file

@ -0,0 +1,490 @@
/* xf86drmSL.c -- Skip list support
* 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>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.3 2000/06/17 00:03:34 martin Exp $
*
* 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.
*
*/
#define SL_MAIN 0
#if SL_MAIN
# include <stdio.h>
# include <stdlib.h>
# include <sys/time.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define SL_LIST_MAGIC 0xfacade00LU
#define SL_ENTRY_MAGIC 0x00fab1edLU
#define SL_FREED_MAGIC 0xdecea5edLU
#define SL_MAX_LEVEL 16
#define SL_DEBUG 0
#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_INIT(seed) if (!state) state = drmRandomCreate(seed)
#define SL_RANDOM drmRandom(state)
#endif
typedef struct SLEntry {
unsigned long magic; /* SL_ENTRY_MAGIC */
unsigned long key;
void *value;
int levels;
struct SLEntry *forward[1]; /* variable sized array */
} SLEntry, *SLEntryPtr;
typedef struct SkipList {
unsigned long magic; /* SL_LIST_MAGIC */
int level;
int count;
SLEntryPtr head;
SLEntryPtr p0; /* Position for iteration */
} SkipList, *SkipListPtr;
#if SL_MAIN
extern void *N(SLCreate)(void);
extern int N(SLDestroy)(void *l);
extern int N(SLLookup)(void *l, unsigned long key, void **value);
extern int N(SLInsert)(void *l, unsigned long key, void *value);
extern int N(SLDelete)(void *l, unsigned long key);
extern int N(SLNext)(void *l, unsigned long *key, void **value);
extern int N(SLFirst)(void *l, unsigned long *key, void **value);
extern void N(SLDump)(void *l);
extern int N(SLLookupNeighbors)(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)
{
SLEntryPtr entry;
if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
entry = SL_ALLOC(sizeof(*entry)
+ (max_level + 1) * sizeof(entry->forward[0]));
if (!entry) return NULL;
entry->magic = SL_ENTRY_MAGIC;
entry->key = key;
entry->value = value;
entry->levels = max_level + 1;
return entry;
}
static int SLRandomLevel(void)
{
int level = 1;
SL_RANDOM_DECL;
SL_RANDOM_INIT(SL_RANDOM_SEED);
while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
return level;
}
void *N(SLCreate)(void)
{
SkipListPtr list;
int i;
list = SL_ALLOC(sizeof(*list));
if (!list) return NULL;
list->magic = SL_LIST_MAGIC;
list->level = 0;
list->head = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
list->count = 0;
for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
return list;
}
int N(SLDestroy)(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
SLEntryPtr next;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
for (entry = list->head; entry; entry = next) {
if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
next = entry->forward[0];
entry->magic = SL_FREED_MAGIC;
SL_FREE(entry);
}
list->magic = SL_FREED_MAGIC;
SL_FREE(list);
return 0;
}
static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) return NULL;
for (i = list->level, entry = list->head; i >= 0; i--) {
while (entry->forward[i] && entry->forward[i]->key < key)
entry = entry->forward[i];
update[i] = entry;
}
return entry->forward[0];
}
int N(SLInsert)(void *l, unsigned long key, void *value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
SLEntryPtr update[SL_MAX_LEVEL + 1];
int level;
int i;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = SLLocate(list, key, update);
if (entry && entry->key == key) return 1; /* Already in list */
level = SLRandomLevel();
if (level > list->level) {
level = ++list->level;
update[level] = list->head;
}
entry = SLCreateEntry(level, key, value);
/* Fix up forward pointers */
for (i = 0; i <= level; i++) {
entry->forward[i] = update[i]->forward[i];
update[i]->forward[i] = entry;
}
++list->count;
return 0; /* Added to table */
}
int N(SLDelete)(void *l, unsigned long key)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = SLLocate(list, key, update);
if (!entry || entry->key != key) return 1; /* Not found */
/* Fix up forward pointers */
for (i = 0; i <= list->level; i++) {
if (update[i]->forward[i] == entry)
update[i]->forward[i] = entry->forward[i];
}
entry->magic = SL_FREED_MAGIC;
SL_FREE(entry);
while (list->level && !list->head->forward[list->level]) --list->level;
--list->count;
return 0;
}
int N(SLLookup)(void *l, unsigned long key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
entry = SLLocate(list, key, update);
if (entry && entry->key == key) {
*value = entry;
return 0;
}
*value = NULL;
return -1;
}
int N(SLLookupNeighbors)(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
int retcode = 0;
entry = SLLocate(list, key, update);
*prev_key = *next_key = key;
*prev_value = *next_value = NULL;
if (update[0]) {
*prev_key = update[0]->key;
*prev_value = update[0]->value;
++retcode;
if (update[0]->forward[0]) {
*next_key = update[0]->forward[0]->key;
*next_value = update[0]->forward[0]->value;
++retcode;
}
}
return retcode;
}
int N(SLNext)(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = list->p0;
if (entry) {
list->p0 = entry->forward[0];
*key = entry->key;
*value = entry->value;
return 1;
}
list->p0 = NULL;
return 0;
}
int N(SLFirst)(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
list->p0 = list->head->forward[0];
return N(SLNext)(list, key, value);
}
/* Dump internal data structures for debugging. */
void N(SLDump)(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) {
printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
list->magic, SL_LIST_MAGIC);
return;
}
printf("Level = %d, count = %d\n", list->level, list->count);
for (entry = list->head; entry; entry = entry->forward[0]) {
if (entry->magic != SL_ENTRY_MAGIC) {
printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
list->magic, SL_ENTRY_MAGIC);
}
printf("\nEntry %p <0x%08lx, %p> has %2d levels\n",
entry, entry->key, entry->value, entry->levels);
for (i = 0; i < entry->levels; i++) {
if (entry->forward[i]) {
printf(" %2d: %p <0x%08lx, %p>\n",
i,
entry->forward[i],
entry->forward[i]->key,
entry->forward[i]->value);
} else {
printf(" %2d: %p\n", i, entry->forward[i]);
}
}
}
}
#if SL_MAIN
static void print(SkipListPtr list)
{
unsigned long key;
void *value;
if (N(SLFirst)(list, &key, &value)) {
do {
printf("key = %5lu, value = %p\n", key, value);
} while (N(SLNext)(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 = N(SLCreate)();
for (i = 0; i < size; i++) {
keys[i] = SL_RANDOM;
N(SLInsert)(list, keys[i], NULL);
}
previous = 0;
if (N(SLFirst)(list, &key, &value)) {
do {
if (key <= previous) {
printf( "%lu !< %lu\n", previous, key);
}
previous = key;
} while (N(SLNext)(list, &key, &value));
}
gettimeofday(&start, NULL);
for (j = 0; j < iter; j++) {
for (i = 0; i < size; i++) {
if (N(SLLookup)(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);
N(SLDestroy)(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 = N(SLCreate)();
printf( "list at %p\n", list);
print(list);
printf("\n==============================\n\n");
N(SLInsert)(list, 123, NULL);
N(SLInsert)(list, 213, NULL);
N(SLInsert)(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");
N(SLDelete)(list, 50);
print(list);
printf("\n==============================\n\n");
N(SLDump)(list);
N(SLDestroy)(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

View file

@ -0,0 +1,70 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S,v 1.1 1999/07/10 07:24:49 dawes Exp $ */
/*
* Copyright 1998 by Metro Link Incorporated
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Metro Link
* Incorporated not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Metro Link Incorporated makes no representations
* about the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
* METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
* LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
.file "ppc.s"
.toc
.csect .text[PR]
.balign 4
.globl ppc_flush_icache
.globl .ppc_flush_icache
.csect ppc_flush_icache[DS]
ppc_flush_icache:
.long .ppc_flush_icache, TOC[tc0], 0
.csect .text[PR]
.ppc_flush_icache:
mflr 0
stw 31,-4(1)
stw 0,8(1)
stwu 1,-64(1)
mr 31,1
stw 3,88(31)
li 6, 0 /* __inst_dcbf (addr, 0); */
dcbf 3, 6
li 5, 32 /* __inst_dcbf (addr, LINESIZE); */
dcbf 3, 5
sync /* __inst_sync (); */
li 4,0 /* __inst_icbi (addr, 0); */
icbi 3,4
li 7,32 /* __inst_icbi (addr, LINESIZE); */
icbi 3,7
sync /* __inst_sync (); */
isync /* __inst_isync (); */
L..1:
lwz 1,0(1)
lwz 0,8(1)
mtlr 0
lwz 31,-4(1)
blr
LT..ppc_flush_icache:
.long 0
.byte 0,0,32,97,128,1,1,1
.long 0
.long LT..ppc_flush_icache-.ppc_flush_icache
.short 16
.byte "ppc_flush_icache"
.byte 31
_section_.text:
.csect .data[RW]
.long _section_.text

View file

@ -35,6 +35,7 @@ from The Open Group.
#endif
#include "winprefs.h"
#include "X11/Xlocale.h"
#include <mntent.h>
/*
@ -267,6 +268,89 @@ AbortDDX (void)
ddxGiveUp ();
}
/* hasmntopt is currently not implemented for cygwin */
const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
{
const char *s;
size_t len;
if (mnt == NULL)
return NULL;
if (opt == NULL)
return NULL;
if (mnt->mnt_opts == NULL)
return NULL;
len = strlen(opt);
s = strstr(mnt->mnt_opts, opt);
if (s == NULL)
return NULL;
if ((s == mnt->mnt_opts || *(s-1) == ',') && (s[len] == 0 || s[len] == ','))
return (char *)opt;
return NULL;
}
void
winCheckMount(void)
{
FILE *mnt;
struct mntent *ent;
enum { none = 0, sys_root, user_root, sys_tmp, user_tmp }
level = none, curlevel;
BOOL binary = TRUE;
mnt = setmntent("/etc/mtab", "r");
if (mnt == NULL)
{
ErrorF("setmntent failed");
return;
}
while ((ent = getmntent(mnt)) != NULL)
{
BOOL system = (strcmp(ent->mnt_type, "system") == 0);
BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);
if (system)
{
if (root)
curlevel = sys_root;
else if (tmp)
curlevel = sys_tmp;
else
continue;
}
else
{
if (root)
curlevel = user_root;
else if (tmp)
curlevel = user_tmp;
else
continue;
}
if (curlevel <= level)
continue;
level = curlevel;
if (winCheckMntOpt(ent, "binmode") == NULL)
binary = 0;
else
binary = 1;
}
if (endmntent(mnt) != 1)
{
ErrorF("endmntent failed");
return;
}
if (!binary)
winMsg(X_WARNING, "/tmp mounted int textmode\n");
}
void
OsVendorInit (void)
@ -296,6 +380,8 @@ OsVendorInit (void)
if (serverGeneration == 1)
winLogVersionInfo ();
winCheckMount();
/* Add a default screen if no screens were specified */
if (g_iNumScreens == 0)
{