mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-24 20:23:41 +01:00
(ia64_per_thread_cache): Initialize busy/lock member.
(get_script_cache): Return NULL if caching is disabled. If HAVE_ATOMIC_OPS_H is defined, set the busy flag and if the script cache is busy already, return NULL. (put_script_cache): Don't allow it to be called for UNW_CACHE_NONE case. If HAVE_ATOMIC_OPS_H is defined, clear the "busy" flag via AO_CLEAR. (ia64_get_cached_proc_info): If we're unable to acquire the cache, return -UNW_ENOINFO. (script_init): New function. (script_new): Replace open code with call to script_init(). (uncached_find_save_locs): New function. (ia64_find_save_locs): Move code for uncached case to uncached_find_save_locs(). If get_script_cache() is unable to lock the script-cache, fall back to uncached_find_save_locs(). (ia64_script_cache_init): Delete. (Logical change 1.124)
This commit is contained in:
parent
e939f42941
commit
629d7d3263
1 changed files with 71 additions and 48 deletions
|
@ -29,7 +29,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
|
|
||||||
#ifdef HAVE___THREAD
|
#ifdef HAVE___THREAD
|
||||||
static __thread struct ia64_script_cache ia64_per_thread_cache;
|
static __thread struct ia64_script_cache ia64_per_thread_cache =
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ATOMIC_OPS_H
|
||||||
|
.busy = AO_TS_INITIALIZER
|
||||||
|
#else
|
||||||
|
.lock = PTHREAD_MUTEX_INITIALIZER
|
||||||
|
#endif
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline unw_hash_index_t
|
static inline unw_hash_index_t
|
||||||
|
@ -73,20 +80,25 @@ 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;
|
||||||
unw_caching_policy_t caching = as->caching_policy;
|
unw_caching_policy_t caching = as->caching_policy;
|
||||||
|
|
||||||
|
if (caching == UNW_CACHE_NONE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
#ifdef HAVE___THREAD
|
#ifdef HAVE___THREAD
|
||||||
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
||||||
cache = &ia64_per_thread_cache;
|
cache = &ia64_per_thread_cache;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (likely (caching != UNW_CACHE_NONE))
|
#ifdef HAVE_ATOMIC_OPS_H
|
||||||
|
if (AO_test_and_set (&cache->busy) == AO_TS_SET)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, saved_sigmaskp);
|
||||||
|
if (likely (caching == UNW_CACHE_GLOBAL))
|
||||||
{
|
{
|
||||||
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, saved_sigmaskp);
|
debug (200, "%s: acquiring lock\n", __FUNCTION__);
|
||||||
if (likely (caching == UNW_CACHE_GLOBAL))
|
mutex_lock (&cache->lock);
|
||||||
{
|
|
||||||
debug (200, "%s: acquiring lock\n", __FUNCTION__);
|
|
||||||
mutex_lock (&cache->lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (as->cache_generation != cache->generation)
|
if (as->cache_generation != cache->generation)
|
||||||
{
|
{
|
||||||
|
@ -102,13 +114,16 @@ put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache,
|
||||||
{
|
{
|
||||||
unw_caching_policy_t caching = as->caching_policy;
|
unw_caching_policy_t caching = as->caching_policy;
|
||||||
|
|
||||||
if (likely (caching != UNW_CACHE_NONE))
|
assert (caching != UNW_CACHE_NONE);
|
||||||
{
|
|
||||||
debug (200, "%s: unmasking signals/releasing lock\n", __FUNCTION__);
|
debug (200, "%s: unmasking signals/releasing lock\n", __FUNCTION__);
|
||||||
if (likely (caching == UNW_CACHE_GLOBAL))
|
#ifdef HAVE_ATOMIC_OPS_H
|
||||||
mutex_unlock (&cache->lock);
|
AO_CLEAR (&cache->busy);
|
||||||
sigprocmask (SIG_SETMASK, saved_sigmaskp, NULL);
|
#else
|
||||||
}
|
if (likely (caching == UNW_CACHE_GLOBAL))
|
||||||
|
mutex_unlock (&cache->lock);
|
||||||
|
sigprocmask (SIG_SETMASK, saved_sigmaskp, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ia64_script *
|
static struct ia64_script *
|
||||||
|
@ -152,6 +167,8 @@ ia64_get_cached_proc_info (struct cursor *c)
|
||||||
sigset_t saved_sigmask;
|
sigset_t saved_sigmask;
|
||||||
|
|
||||||
cache = get_script_cache (c->as, &saved_sigmask);
|
cache = get_script_cache (c->as, &saved_sigmask);
|
||||||
|
if (!cache)
|
||||||
|
return -UNW_ENOINFO; /* cache is busy */
|
||||||
{
|
{
|
||||||
script = script_lookup (cache, c);
|
script = script_lookup (cache, c);
|
||||||
if (script)
|
if (script)
|
||||||
|
@ -161,6 +178,15 @@ ia64_get_cached_proc_info (struct cursor *c)
|
||||||
return script ? 0 : -UNW_ENOINFO;
|
return script ? 0 : -UNW_ENOINFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
script_init (struct ia64_script *script, unw_word_t ip)
|
||||||
|
{
|
||||||
|
script->ip = ip;
|
||||||
|
script->hint = 0;
|
||||||
|
script->count = 0;
|
||||||
|
script->abi_marker = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct ia64_script *
|
static inline struct ia64_script *
|
||||||
script_new (struct ia64_script_cache *cache, unw_word_t ip)
|
script_new (struct ia64_script_cache *cache, unw_word_t ip)
|
||||||
{
|
{
|
||||||
|
@ -206,10 +232,7 @@ script_new (struct ia64_script_cache *cache, unw_word_t ip)
|
||||||
script->coll_chain = cache->hash[index];
|
script->coll_chain = cache->hash[index];
|
||||||
cache->hash[index] = script - cache->buckets;
|
cache->hash[index] = script - cache->buckets;
|
||||||
|
|
||||||
script->ip = ip;
|
script_init (script, ip);
|
||||||
script->hint = 0;
|
|
||||||
script->count = 0;
|
|
||||||
script->abi_marker = 0;
|
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,6 +520,26 @@ run_script (struct ia64_script *script, struct cursor *c)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
uncached_find_save_locs (struct cursor *c)
|
||||||
|
{
|
||||||
|
struct ia64_script script;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
script_init (&script, c->ip);
|
||||||
|
if ((ret = build_script (c, &script)) < 0)
|
||||||
|
{
|
||||||
|
if (ret != -UNW_ESTOPUNWIND)
|
||||||
|
dprintf ("%s: failed to build unwind script for ip %lx\n",
|
||||||
|
__FUNCTION__, (long) c->ip);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return run_script (&script, c);
|
||||||
|
}
|
||||||
|
|
||||||
HIDDEN int
|
HIDDEN int
|
||||||
ia64_find_save_locs (struct cursor *c)
|
ia64_find_save_locs (struct cursor *c)
|
||||||
{
|
{
|
||||||
|
@ -505,29 +548,16 @@ ia64_find_save_locs (struct cursor *c)
|
||||||
sigset_t saved_sigmask;
|
sigset_t saved_sigmask;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (unlikely (c->as->caching_policy == UNW_CACHE_NONE))
|
if (c->as->caching_policy == UNW_CACHE_NONE)
|
||||||
{
|
return uncached_find_save_locs (c);
|
||||||
struct ia64_script tmp_script;
|
|
||||||
|
|
||||||
if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
script = &tmp_script;
|
|
||||||
script->ip = c->ip;
|
|
||||||
script->hint = 0;
|
|
||||||
script->count = 0;
|
|
||||||
if ((ret = build_script (c, script)) < 0)
|
|
||||||
{
|
|
||||||
if (ret != -UNW_ESTOPUNWIND)
|
|
||||||
dprintf ("%s: failed to build unwind script for ip %lx\n",
|
|
||||||
__FUNCTION__, (long) c->ip);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
run_script (script, c);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache = get_script_cache (c->as, &saved_sigmask);
|
cache = get_script_cache (c->as, &saved_sigmask);
|
||||||
|
if (!cache)
|
||||||
|
{
|
||||||
|
debug (125, "%s: contention on script-cached; doing uncached lookup\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
return uncached_find_save_locs (c);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
script = script_lookup (cache, c);
|
script = script_lookup (cache, c);
|
||||||
debug (125, "%s: ip %lx %s in script cache\n",
|
debug (125, "%s: ip %lx %s in script cache\n",
|
||||||
|
@ -559,16 +589,9 @@ ia64_find_save_locs (struct cursor *c)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
run_script (script, c);
|
ret = run_script (script, c);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
put_script_cache (c->as, cache, &saved_sigmask);
|
put_script_cache (c->as, cache, &saved_sigmask);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
HIDDEN void
|
|
||||||
ia64_script_cache_init (struct ia64_script_cache *cache)
|
|
||||||
{
|
|
||||||
mutex_init (&cache->lock);
|
|
||||||
flush_script_cache (cache);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue