open-src/xserver/xorg/faster-devPrivates.patch
changeset 606 068c11b419c9
equal deleted inserted replaced
605:e5259db5befc 606:068c11b419c9
       
     1 From b6ab114212c0e4c3346ceb5b207f14c526ab81e7 Mon Sep 17 00:00:00 2001
       
     2 From: Eamon Walsh <[email protected]>
       
     3 Date: Fri, 12 Sep 2008 19:11:53 -0400
       
     4 Subject: [PATCH] Array-index based devPrivates implementation.
       
     5 
       
     6 Note: DevPrivateKey is now pointer-to-int, which means
       
     7 each key now needs to point to some global storage of
       
     8 size at least sizeof(int).
       
     9 ---
       
    10  dix/privates.c     |  209 +++++++++++++++++++++++++++-------------------------
       
    11  include/privates.h |    2 
       
    12  2 files changed, 109 insertions(+), 102 deletions(-)
       
    13 
       
    14 diff --git a/dix/privates.c b/dix/privates.c
       
    15 index efb3204..ca03317 100644
       
    16 --- a/dix/privates.c
       
    17 +++ b/dix/privates.c
       
    18 @@ -40,9 +40,8 @@ #include "colormapst.h"
       
    19  #include "inputstr.h"
       
    20  
       
    21  struct _Private {
       
    22 -    DevPrivateKey      key;
       
    23 -    pointer            value;
       
    24 -    struct _Private    *next;
       
    25 +    int state;
       
    26 +    pointer value;
       
    27  };
       
    28  
       
    29  typedef struct _PrivateDesc {
       
    30 @@ -50,22 +49,36 @@ typedef struct _PrivateDesc {
       
    31      unsigned size;
       
    32      CallbackListPtr initfuncs;
       
    33      CallbackListPtr deletefuncs;
       
    34 -    struct _PrivateDesc *next;
       
    35  } PrivateDescRec;
       
    36  
       
    37 +#define PRIV_MAX 256
       
    38 +#define PRIV_STEP 16
       
    39 +
       
    40  /* list of all allocated privates */
       
    41 -static PrivateDescRec *items = NULL;
       
    42 +static PrivateDescRec items[PRIV_MAX];
       
    43 +static int nextPriv;
       
    44  
       
    45 -static _X_INLINE PrivateDescRec *
       
    46 +static PrivateDescRec *
       
    47  findItem(const DevPrivateKey key)
       
    48  {
       
    49 -    PrivateDescRec *item = items;
       
    50 -    while (item) {
       
    51 -	if (item->key == key)
       
    52 -	    return item;
       
    53 -	item = item->next;
       
    54 +    if (!*key) {
       
    55 +	if (nextPriv >= PRIV_MAX)
       
    56 +	    return NULL;
       
    57 +
       
    58 +	items[nextPriv].key = key;
       
    59 +	*key = nextPriv;
       
    60 +	nextPriv++;
       
    61      }
       
    62 -    return NULL;
       
    63 +
       
    64 +    return items + *key;
       
    65 +}
       
    66 +
       
    67 +static _X_INLINE int
       
    68 +privateExists(PrivateRec **privates, const DevPrivateKey key)
       
    69 +{
       
    70 +    return *key && *privates &&
       
    71 +	(*privates)[0].state > *key &&
       
    72 +	(*privates)[*key].state;
       
    73  }
       
    74  
       
    75  /*
       
    76 @@ -75,21 +88,10 @@ _X_EXPORT int
       
    77  dixRequestPrivate(const DevPrivateKey key, unsigned size)
       
    78  {
       
    79      PrivateDescRec *item = findItem(key);
       
    80 -    if (item) {
       
    81 -	if (size > item->size)
       
    82 -	    item->size = size;
       
    83 -    } else {
       
    84 -	item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec));
       
    85 -	if (!item)
       
    86 -	    return FALSE;
       
    87 -	memset(item, 0, sizeof(PrivateDescRec));
       
    88 -
       
    89 -	/* add privates descriptor */
       
    90 -	item->key = key;
       
    91 +    if (!item)
       
    92 +	return FALSE;
       
    93 +    if (size > item->size)
       
    94  	item->size = size;
       
    95 -	item->next = items;
       
    96 -	items = item;
       
    97 -    }
       
    98      return TRUE;
       
    99  }
       
   100  
       
   101 @@ -100,25 +102,52 @@ _X_EXPORT pointer *
       
   102  dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
       
   103  {
       
   104      PrivateDescRec *item = findItem(key);
       
   105 +    PrivateCallbackRec calldata;
       
   106      PrivateRec *ptr;
       
   107 -    unsigned size = sizeof(PrivateRec);
       
   108 -    
       
   109 -    if (item)
       
   110 -	size += item->size;
       
   111 +    pointer value;
       
   112 +    int oldsize, newsize;
       
   113 +
       
   114 +    newsize = (*key / PRIV_STEP + 1) * PRIV_STEP;
       
   115  
       
   116 -    ptr = (PrivateRec *)xcalloc(size, 1);
       
   117 -    if (!ptr)
       
   118 +    /* resize or init privates array */
       
   119 +    if (!item)
       
   120  	return NULL;
       
   121 -    ptr->key = key;
       
   122 -    ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL;
       
   123 -    ptr->next = *privates;
       
   124 -    *privates = ptr;
       
   125 -
       
   126 -    /* call any init funcs and return */
       
   127 -    if (item) {
       
   128 -	PrivateCallbackRec calldata = { key, &ptr->value };
       
   129 -	CallCallbacks(&item->initfuncs, &calldata);
       
   130 +
       
   131 +    /* initialize privates array if necessary */
       
   132 +    if (!*privates) {
       
   133 +	ptr = xcalloc(newsize, sizeof(*ptr));
       
   134 +	if (!ptr)
       
   135 +	    return NULL;
       
   136 +	*privates = ptr;
       
   137 +	(*privates)[0].state = newsize;
       
   138 +    }
       
   139 +
       
   140 +    oldsize = (*privates)[0].state;
       
   141 +
       
   142 +    /* resize privates array if necessary */
       
   143 +    if (*key >= oldsize) {
       
   144 +	ptr = xrealloc(*privates, newsize * sizeof(*ptr));
       
   145 +	if (!ptr)
       
   146 +	    return NULL;
       
   147 +	memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr));
       
   148 +	*privates = ptr;
       
   149 +	(*privates)[0].state = newsize;
       
   150 +    }
       
   151 +
       
   152 +    /* initialize slot */
       
   153 +    ptr = *privates + *key;
       
   154 +    ptr->state = 1;
       
   155 +    if (item->size) {
       
   156 +	value = xcalloc(item->size, 1);
       
   157 +	if (!value)
       
   158 +	    return NULL;
       
   159 +	ptr->value = value;
       
   160      }
       
   161 +
       
   162 +    calldata.key = key;
       
   163 +    calldata.value = &ptr->value;
       
   164 +    CallCallbacks(&item->initfuncs, &calldata);
       
   165 +
       
   166      return &ptr->value;
       
   167  }
       
   168  
       
   169 @@ -128,14 +157,10 @@ dixAllocatePrivate(PrivateRec **privates
       
   170  _X_EXPORT pointer
       
   171  dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
       
   172  {
       
   173 -    PrivateRec *rec = *privates;
       
   174      pointer *ptr;
       
   175  
       
   176 -    while (rec) {
       
   177 -	if (rec->key == key)
       
   178 -	    return rec->value;
       
   179 -	rec = rec->next;
       
   180 -    }
       
   181 +    if (privateExists(privates, key))
       
   182 +	return (*privates)[*key].value;
       
   183  
       
   184      ptr = dixAllocatePrivate(privates, key);
       
   185      return ptr ? *ptr : NULL;
       
   186 @@ -147,13 +172,8 @@ dixLookupPrivate(PrivateRec **privates, 
       
   187  _X_EXPORT pointer *
       
   188  dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
       
   189  {
       
   190 -    PrivateRec *rec = *privates;
       
   191 -
       
   192 -    while (rec) {
       
   193 -	if (rec->key == key)
       
   194 -	    return &rec->value;
       
   195 -	rec = rec->next;
       
   196 -    }
       
   197 +    if (privateExists(privates, key))
       
   198 +	return &(*privates)[*key].value;
       
   199  
       
   200      return dixAllocatePrivate(privates, key);
       
   201  }
       
   202 @@ -164,16 +184,10 @@ dixLookupPrivateAddr(PrivateRec **privat
       
   203  _X_EXPORT int
       
   204  dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
       
   205  {
       
   206 -    PrivateRec *rec;
       
   207 -
       
   208   top:
       
   209 -    rec = *privates;
       
   210 -    while (rec) {
       
   211 -	if (rec->key == key) {
       
   212 -	    rec->value = val;
       
   213 -	    return TRUE;
       
   214 -	}
       
   215 -	rec = rec->next;
       
   216 +    if (privateExists(privates, key)) {
       
   217 +	(*privates)[*key].value = val;
       
   218 +	return TRUE;
       
   219      }
       
   220  
       
   221      if (!dixAllocatePrivate(privates, key))
       
   222 @@ -187,27 +201,23 @@ dixSetPrivate(PrivateRec **privates, con
       
   223  _X_EXPORT void
       
   224  dixFreePrivates(PrivateRec *privates)
       
   225  {
       
   226 -    PrivateRec *ptr, *next;
       
   227 -    PrivateDescRec *item;
       
   228 +    int i;
       
   229      PrivateCallbackRec calldata;
       
   230  
       
   231 -    /* first pass calls the delete callbacks */
       
   232 -    for (ptr = privates; ptr; ptr = ptr->next) {
       
   233 -	item = findItem(ptr->key);
       
   234 -	if (item) {
       
   235 -	    calldata.key = ptr->key;
       
   236 -	    calldata.value = &ptr->value;
       
   237 -	    CallCallbacks(&item->deletefuncs, &calldata);
       
   238 -	}
       
   239 -    }
       
   240 -	
       
   241 -    /* second pass frees the memory */
       
   242 -    ptr = privates;
       
   243 -    while (ptr) {
       
   244 -	next = ptr->next;
       
   245 -	xfree(ptr);
       
   246 -	ptr = next;
       
   247 -    }
       
   248 +    if (privates)
       
   249 +	for (i = 1; i < privates->state; i++)
       
   250 +	    if (privates[i].state) {
       
   251 +		/* call the delete callbacks */
       
   252 +		calldata.key = items[i].key;
       
   253 +		calldata.value = &privates[i].value;
       
   254 +		CallCallbacks(&items[i].deletefuncs, &calldata);
       
   255 +
       
   256 +		/* free pre-allocated memory */
       
   257 +		if (items[i].size)
       
   258 +		    xfree(privates[i].value);
       
   259 +	    }
       
   260 +
       
   261 +    xfree(privates);
       
   262  }
       
   263  
       
   264  /*
       
   265 @@ -218,11 +228,9 @@ dixRegisterPrivateInitFunc(const DevPriv
       
   266  			   CallbackProcPtr callback, pointer data)
       
   267  {
       
   268      PrivateDescRec *item = findItem(key);
       
   269 -    if (!item) {
       
   270 -	if (!dixRequestPrivate(key, 0))
       
   271 -	    return FALSE;
       
   272 -	item = findItem(key);
       
   273 -    }
       
   274 +    if (!item)
       
   275 +	return FALSE;
       
   276 +
       
   277      return AddCallback(&item->initfuncs, callback, data);
       
   278  }
       
   279  
       
   280 @@ -231,11 +239,9 @@ dixRegisterPrivateDeleteFunc(const DevPr
       
   281  			     CallbackProcPtr callback, pointer data)
       
   282  {
       
   283      PrivateDescRec *item = findItem(key);
       
   284 -    if (!item) {
       
   285 -	if (!dixRequestPrivate(key, 0))
       
   286 -	    return FALSE;
       
   287 -	item = findItem(key);
       
   288 -    }
       
   289 +    if (!item)
       
   290 +	return FALSE;
       
   291 +
       
   292      return AddCallback(&item->deletefuncs, callback, data);
       
   293  }
       
   294  
       
   295 @@ -292,16 +298,17 @@ dixLookupPrivateOffset(RESTYPE type)
       
   296  int
       
   297  dixResetPrivates(void)
       
   298  {
       
   299 -    PrivateDescRec *next;
       
   300 -
       
   301 -    /* reset internal structures */
       
   302 -    while (items) {
       
   303 -	next = items->next;
       
   304 -	DeleteCallbackList(&items->initfuncs);
       
   305 -	DeleteCallbackList(&items->deletefuncs);
       
   306 -	xfree(items);
       
   307 -	items = next;
       
   308 +    int i;
       
   309 +
       
   310 +    /* reset private descriptors */
       
   311 +    for (i = 1; i < nextPriv; i++) {
       
   312 +	*items[i].key = 0;
       
   313 +	DeleteCallbackList(&items[i].initfuncs);
       
   314 +	DeleteCallbackList(&items[i].deletefuncs);
       
   315      }
       
   316 +    nextPriv = 1;
       
   317 +
       
   318 +    /* reset offsets */
       
   319      if (offsets)
       
   320  	xfree(offsets);
       
   321      offsetsSize = sizeof(offsetDefaults);
       
   322 diff --git a/include/privates.h b/include/privates.h
       
   323 index 98d893c..e3fa83c 100644
       
   324 --- a/include/privates.h
       
   325 +++ b/include/privates.h
       
   326 @@ -19,7 +19,7 @@ #include "resource.h"
       
   327   * STUFF FOR PRIVATES
       
   328   *****************************************************************/
       
   329  
       
   330 -typedef void *DevPrivateKey;
       
   331 +typedef int *DevPrivateKey;
       
   332  struct _Private;
       
   333  typedef struct _Private PrivateRec;
       
   334  
       
   335 -- 
       
   336 1.4.1
       
   337