VirtualBox

source: kBuild/trunk/src/kmk/w32/imagecache.c@ 2635

Last change on this file since 2635 was 2635, checked in by bird, 12 years ago

kmk: experimental executable image cache for windows.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1/* $Id: imagecache.c 2635 2012-09-09 00:57:47Z bird $ */
2/** @file
3 * kBuild specific executable image cache for Windows.
4 */
5
6/*
7 * Copyright (c) 2012 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
23 *
24 */
25
26/* No GNU coding style here! */
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "make.h"
32
33#include <Windows.h>
34
35
36/*******************************************************************************
37* Structures and Typedefs *
38*******************************************************************************/
39typedef struct EXECCACHEENTRY
40{
41 /** The name hash value. */
42 unsigned uHash;
43 /** The name length. */
44 unsigned cchName;
45 /** Pointer to the next name with the same hash. */
46 struct EXECCACHEENTRY *pNext;
47 /** When it was last referenced. */
48 unsigned uLastRef;
49 /** The module handle. */
50 HMODULE hmod1;
51 /** The module handle. */
52 HMODULE hmod2;
53 /** The executable path. */
54 char szName[1];
55} EXECCACHEENTRY;
56typedef EXECCACHEENTRY *PEXECCACHEENTRY;
57
58/*******************************************************************************
59* Global Variables *
60*******************************************************************************/
61/** The number of cached images. */
62static unsigned g_cCached;
63/** Used noting when entries was last used.
64 * Increased on each kmk_cache_exec_image call. */
65static unsigned g_uNow;
66
67/** The size of the hash table. */
68#define EXECCACHE_HASHTAB_SIZE 128
69/** The hash table. */
70static PEXECCACHEENTRY g_apHashTab[EXECCACHE_HASHTAB_SIZE];
71
72
73/* sdbm:
74 This algorithm was created for sdbm (a public-domain reimplementation of
75 ndbm) database library. it was found to do well in scrambling bits,
76 causing better distribution of the keys and fewer splits. it also happens
77 to be a good general hashing function with good distribution. the actual
78 function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
79 is the faster version used in gawk. [there is even a faster, duff-device
80 version] the magic constant 65599 was picked out of thin air while
81 experimenting with different constants, and turns out to be a prime.
82 this is one of the algorithms used in berkeley db (see sleepycat) and
83 elsewhere. */
84
85static unsigned execcache_calc_hash(const char *psz, unsigned *pcch)
86{
87 unsigned char *puch = (unsigned char *)psz;
88 unsigned hash = 0;
89 int ch;
90
91 while ((ch = *puch++))
92 hash = ch + (hash << 6) + (hash << 16) - hash;
93
94 *pcch = (unsigned)(puch - psz - 1);
95 return hash;
96}
97
98
99extern void kmk_cache_exec_image(const char *pszExec)
100{
101 /*
102 * Lookup the name.
103 */
104 unsigned cchName;
105 const unsigned uHash = execcache_calc_hash(pszExec, &cchName);
106 PEXECCACHEENTRY *ppCur = &g_apHashTab[uHash % EXECCACHE_HASHTAB_SIZE];
107 PEXECCACHEENTRY pCur = *ppCur;
108 while (pCur)
109 {
110 if ( pCur->uHash == uHash
111 && pCur->cchName == cchName
112 && !memcmp(pCur->szName, pszExec, cchName))
113 {
114 pCur->uLastRef = ++g_uNow;
115 return;
116 }
117 ppCur = &pCur->pNext;
118 pCur = pCur->pNext;
119 }
120
121 /*
122 * Not found, create a new entry.
123 */
124 pCur = xmalloc(sizeof(*pCur) + cchName);
125 pCur->uHash = uHash;
126 pCur->cchName = cchName;
127 pCur->pNext = NULL;
128 pCur->uLastRef = ++g_uNow;
129 memcpy(pCur->szName, pszExec, cchName + 1);
130 pCur->hmod1 = LoadLibraryEx(pszExec, NULL, LOAD_LIBRARY_AS_DATAFILE);
131 pCur->hmod2 = LoadLibraryEx(pszExec, NULL, DONT_RESOLVE_DLL_REFERENCES);
132
133 *ppCur = pCur;
134 g_cCached++;
135}
136
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette