1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-26 00:57:39 +01:00

(flush_script_cache): Drop addr_space_t argument. Initialize

hash-table, collision-chains, and hash-table in addition
	to clearing the script's IP value.  The latter wasn't nearly
	sufficient because it could cause loops on the collision
	chain...
(get_script_cache): Also lock the cache if global caching is in
	effect.  Take additional "saved_sigmaskp" argument.
	After flushing the cache, update the cache generation
	here.
(put_script_cache): New function.
(ia64_get_cached_proc_info): Adjust for get_script_cache() and
	put_script_cache() changes.
(ia64_find_save_locs): Ditto.
(ia64_script_cache_init): Call flush_script_cache() instead of
	opening-coding the equivalent code.

(Logical change 1.96)
This commit is contained in:
mostang.com!davidm 2003-09-19 06:56:12 +00:00
parent 29358553a9
commit b3c1bf3f75

View file

@ -49,18 +49,26 @@ cache_match (struct ia64_script *script, unw_word_t ip, unw_word_t pr)
} }
static inline void static inline void
flush_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache) flush_script_cache (struct ia64_script_cache *cache)
{ {
int i; int i;
for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i) cache->lru_head = IA64_UNW_CACHE_SIZE - 1;
cache->buckets[i].ip = 0; cache->lru_tail = 0;
cache->generation = as->cache_generation; for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i)
{
if (i > 0)
cache->buckets[i].lru_chain = (i - 1);
cache->buckets[i].coll_chain = -1;
cache->buckets[i].ip = 0;
}
for (i = 0; i<IA64_UNW_HASH_SIZE; ++i)
cache->hash[i] = -1;
} }
static inline struct ia64_script_cache * static inline struct ia64_script_cache *
get_script_cache (unw_addr_space_t as) get_script_cache (unw_addr_space_t as, sigset_t *saved_sigmaskp)
{ {
struct ia64_script_cache *cache = &as->global_cache; struct ia64_script_cache *cache = &as->global_cache;
@ -69,12 +77,31 @@ get_script_cache (unw_addr_space_t as)
cache = &ia64_per_thread_cache; cache = &ia64_per_thread_cache;
#endif #endif
if (as->cache_generation != cache->generation) if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
flush_script_cache (as, cache); {
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, saved_sigmaskp);
mutex_lock (&cache->lock);
}
if (as->cache_generation != cache->generation)
{
flush_script_cache (cache);
cache->generation = as->cache_generation;
}
return cache; return cache;
} }
static inline void
put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache,
sigset_t *saved_sigmaskp)
{
if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
{
mutex_unlock (&cache->lock);
sigprocmask (SIG_SETMASK, saved_sigmaskp, NULL);
}
}
static struct ia64_script * static struct ia64_script *
script_lookup (struct ia64_script_cache *cache, struct cursor *c) script_lookup (struct ia64_script_cache *cache, struct cursor *c)
{ {
@ -111,28 +138,17 @@ script_lookup (struct ia64_script_cache *cache, struct cursor *c)
HIDDEN int HIDDEN int
ia64_get_cached_proc_info (struct cursor *c) ia64_get_cached_proc_info (struct cursor *c)
{ {
int global_cache = (c->as->caching_policy == UNW_CACHE_GLOBAL);
struct ia64_script_cache *cache; struct ia64_script_cache *cache;
struct ia64_script *script; struct ia64_script *script;
sigset_t saved_sigmask; sigset_t saved_sigmask;
cache = get_script_cache (c->as); cache = get_script_cache (c->as, &saved_sigmask);
if (likely (global_cache))
{ {
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
mutex_lock (&cache->lock);
}
script = script_lookup (cache, c); script = script_lookup (cache, c);
if (script) if (script)
c->pi = script->pi; c->pi = script->pi;
if (likely (global_cache))
{
mutex_unlock (&cache->lock);
sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
} }
put_script_cache (c->as, cache, &saved_sigmask);
return script ? 0 : -UNW_ENOINFO; return script ? 0 : -UNW_ENOINFO;
} }
@ -475,7 +491,6 @@ run_script (struct ia64_script *script, struct cursor *c)
HIDDEN int HIDDEN int
ia64_find_save_locs (struct cursor *c) ia64_find_save_locs (struct cursor *c)
{ {
int global_cache = (c->as->caching_policy == UNW_CACHE_GLOBAL);
struct ia64_script_cache *cache = NULL; struct ia64_script_cache *cache = NULL;
struct ia64_script *script = NULL; struct ia64_script *script = NULL;
sigset_t saved_sigmask; sigset_t saved_sigmask;
@ -485,14 +500,8 @@ ia64_find_save_locs (struct cursor *c)
if (ret < 0) if (ret < 0)
return ret; return ret;
cache = get_script_cache (c->as); cache = get_script_cache (c->as, &saved_sigmask);
if (likely (global_cache))
{ {
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
mutex_lock (&cache->lock);
}
if (c->as->caching_policy == UNW_CACHE_NONE) if (c->as->caching_policy == UNW_CACHE_NONE)
{ {
struct ia64_script tmp_script; struct ia64_script tmp_script;
@ -506,6 +515,8 @@ ia64_find_save_locs (struct cursor *c)
else else
{ {
script = script_lookup (cache, c); script = script_lookup (cache, c);
debug (125, "%s: ip %lx %s in script cache\n",
__FUNCTION__, (long) c->ip, script ? "hit" : "missed");
if (!script) if (!script)
{ {
script = script_new (cache, c->ip); script = script_new (cache, c->ip);
@ -531,31 +542,15 @@ ia64_find_save_locs (struct cursor *c)
} }
run_script (script, c); run_script (script, c);
out:
if (likely (global_cache))
{
mutex_unlock (&cache->lock);
sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
} }
out:
put_script_cache (c->as, cache, &saved_sigmask);
return ret; return ret;
} }
HIDDEN void HIDDEN void
ia64_script_cache_init (struct ia64_script_cache *cache) ia64_script_cache_init (struct ia64_script_cache *cache)
{ {
int i;
mutex_init (&cache->lock); mutex_init (&cache->lock);
cache->lru_head = IA64_UNW_CACHE_SIZE - 1; flush_script_cache (cache);
cache->lru_tail = 0;
for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i)
{
if (i > 0)
cache->buckets[i].lru_chain = (i - 1);
cache->buckets[i].coll_chain = -1;
}
for (i = 0; i<IA64_UNW_HASH_SIZE; ++i)
cache->hash[i] = -1;
} }