|
|
@ -17,6 +17,7 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
|
|
|
|
|
|
|
#ifdef GPR_POSIX_SYNC |
|
|
|
#ifdef GPR_POSIX_SYNC |
|
|
|
|
|
|
|
|
|
|
@ -72,27 +73,58 @@ gpr_atm gpr_counter_atm_add = 0; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
void gpr_mu_init(gpr_mu* mu) { |
|
|
|
void gpr_mu_init(gpr_mu* mu) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); |
|
|
|
|
|
|
|
mu->leak_checker = (int*)gpr_malloc(sizeof(*mu->leak_checker)); |
|
|
|
|
|
|
|
GPR_ASSERT(mu->leak_checker != nullptr); |
|
|
|
|
|
|
|
/* Initial it with a magic number, make no sense, just use the memory.
|
|
|
|
|
|
|
|
* This only take effect when ASAN enabled, so, |
|
|
|
|
|
|
|
* if memory allocation failed, let it crash. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
*mu->leak_checker = 0x12F34D0; |
|
|
|
|
|
|
|
#else |
|
|
|
GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); |
|
|
|
GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); } |
|
|
|
void gpr_mu_destroy(gpr_mu* mu) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0); |
|
|
|
|
|
|
|
gpr_free(mu->leak_checker); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_mutex_destroy(mu) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_mu_lock(gpr_mu* mu) { |
|
|
|
void gpr_mu_lock(gpr_mu* mu) { |
|
|
|
#ifdef GPR_LOW_LEVEL_COUNTERS |
|
|
|
#ifdef GPR_LOW_LEVEL_COUNTERS |
|
|
|
GPR_ATM_INC_COUNTER(gpr_mu_locks); |
|
|
|
GPR_ATM_INC_COUNTER(gpr_mu_locks); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_lock", 0); |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_lock", 0); |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0); |
|
|
|
|
|
|
|
#else |
|
|
|
GPR_ASSERT(pthread_mutex_lock(mu) == 0); |
|
|
|
GPR_ASSERT(pthread_mutex_lock(mu) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_mu_unlock(gpr_mu* mu) { |
|
|
|
void gpr_mu_unlock(gpr_mu* mu) { |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_unlock", 0); |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_unlock", 0); |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0); |
|
|
|
|
|
|
|
#else |
|
|
|
GPR_ASSERT(pthread_mutex_unlock(mu) == 0); |
|
|
|
GPR_ASSERT(pthread_mutex_unlock(mu) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int gpr_mu_trylock(gpr_mu* mu) { |
|
|
|
int gpr_mu_trylock(gpr_mu* mu) { |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_trylock", 0); |
|
|
|
GPR_TIMER_SCOPE("gpr_mu_trylock", 0); |
|
|
|
int err = pthread_mutex_trylock(mu); |
|
|
|
int err = 0; |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
err = pthread_mutex_trylock(&mu->mutex); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
err = pthread_mutex_trylock(mu); |
|
|
|
|
|
|
|
#endif |
|
|
|
GPR_ASSERT(err == 0 || err == EBUSY); |
|
|
|
GPR_ASSERT(err == 0 || err == EBUSY); |
|
|
|
return err == 0; |
|
|
|
return err == 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -105,10 +137,29 @@ void gpr_cv_init(gpr_cv* cv) { |
|
|
|
#if GPR_LINUX |
|
|
|
#if GPR_LINUX |
|
|
|
GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0); |
|
|
|
GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0); |
|
|
|
#endif // GPR_LINUX
|
|
|
|
#endif // GPR_LINUX
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); |
|
|
|
|
|
|
|
cv->leak_checker = (int*)gpr_malloc(sizeof(*cv->leak_checker)); |
|
|
|
|
|
|
|
GPR_ASSERT(cv->leak_checker != nullptr); |
|
|
|
|
|
|
|
/* Initial it with a magic number, make no sense, just use the memory.
|
|
|
|
|
|
|
|
* This only take effect when ASAN enabled, so, |
|
|
|
|
|
|
|
* if memory allocation failed, let it crash. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
*cv->leak_checker = 0x12F34D0; |
|
|
|
|
|
|
|
#else |
|
|
|
GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); |
|
|
|
GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } |
|
|
|
void gpr_cv_destroy(gpr_cv* cv) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0); |
|
|
|
|
|
|
|
gpr_free(cv->leak_checker); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_destroy(cv) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// For debug of the timer manager crash only.
|
|
|
|
// For debug of the timer manager crash only.
|
|
|
|
// TODO (mxyan): remove after bug is fixed.
|
|
|
|
// TODO (mxyan): remove after bug is fixed.
|
|
|
@ -169,7 +220,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == |
|
|
|
if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == |
|
|
|
0) { |
|
|
|
0) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
err = pthread_cond_wait(&cv->cond_var, &mu->mutex); |
|
|
|
|
|
|
|
#else |
|
|
|
err = pthread_cond_wait(cv, mu); |
|
|
|
err = pthread_cond_wait(cv, mu); |
|
|
|
|
|
|
|
#endif |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
struct timespec abs_deadline_ts; |
|
|
|
struct timespec abs_deadline_ts; |
|
|
|
#if GPR_LINUX |
|
|
|
#if GPR_LINUX |
|
|
@ -181,7 +236,13 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { |
|
|
|
#endif // GPR_LINUX
|
|
|
|
#endif // GPR_LINUX
|
|
|
|
abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec); |
|
|
|
abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec); |
|
|
|
abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; |
|
|
|
abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts); |
|
|
|
|
|
|
|
#else |
|
|
|
err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); |
|
|
|
err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#ifdef GRPC_DEBUG_TIMER_MANAGER |
|
|
|
#ifdef GRPC_DEBUG_TIMER_MANAGER |
|
|
|
// For debug of the timer manager crash only.
|
|
|
|
// For debug of the timer manager crash only.
|
|
|
|
// TODO (mxyan): remove after bug is fixed.
|
|
|
|
// TODO (mxyan): remove after bug is fixed.
|
|
|
@ -226,10 +287,20 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { |
|
|
|
return err == ETIMEDOUT; |
|
|
|
return err == ETIMEDOUT; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); } |
|
|
|
void gpr_cv_signal(gpr_cv* cv) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_signal(cv) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void gpr_cv_broadcast(gpr_cv* cv) { |
|
|
|
void gpr_cv_broadcast(gpr_cv* cv) { |
|
|
|
|
|
|
|
#ifdef GRPC_ASAN_ENABLED |
|
|
|
|
|
|
|
GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0); |
|
|
|
|
|
|
|
#else |
|
|
|
GPR_ASSERT(pthread_cond_broadcast(cv) == 0); |
|
|
|
GPR_ASSERT(pthread_cond_broadcast(cv) == 0); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------*/ |
|
|
|
/*----------------------------------------*/ |
|
|
|