configurations. Returns true if the system should retry again or false
otherwise. */
static inline bool
-__get_new_count (uint8_t *adapt_count)
+__get_new_count (uint8_t *adapt_count, int attempt)
{
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
}
/* Same logic as above, but for a number of temporary failures in a
a row. */
- else if (__elision_aconf.skip_lock_out_of_tbegin_retries > 0
+ else if (attempt <= 1 && __elision_aconf.skip_lock_out_of_tbegin_retries > 0
&& __elision_aconf.try_tbegin > 0)
*adapt_count = __elision_aconf.skip_lock_out_of_tbegin_retries;
return true;
__builtin_tabort (_ABORT_LOCK_BUSY); \
} \
else \
- if (!__get_new_count(&adapt_count)) \
+ if (!__get_new_count (&adapt_count,i)) \
break; \
} \
ret; \
goto use_lock;
}
- int try_begin = aconf.try_tbegin;
- while (1)
+ for (int i = aconf.try_tbegin; i > 0; i--)
{
if (__builtin_tbegin (0))
{
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
for the next couple of calls. */
- if (try_begin-- <= 0
- || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+ if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
{
if (aconf.skip_lock_internal_abort > 0)
*adapt_count = aconf.skip_lock_internal_abort;
goto use_lock;
}
- /* Same logic as above, but for for a number of temporary failures
- in a row. */
- else if (aconf.skip_lock_out_of_tbegin_retries > 0
- && aconf.try_tbegin > 0)
- *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
}
}
+ /* Fall back to locks for a bit if retries have been exhausted */
+ if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0)
+ *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+
use_lock:
return LLL_LOCK ((*lock), pshared);
}