sync.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /* Generic implementation of synchronization primitives. */
20 
22 
23 #include <assert.h>
24 
25 #include <grpc/support/atm.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/sync.h>
28 
29 /* Number of mutexes to allocate for events, to avoid lock contention.
30  Should be a prime. */
31 enum { event_sync_partitions = 31 };
32 
33 /* Events are partitioned by address to avoid lock contention. */
34 static struct sync_array_s {
38 
39 /* This routine is executed once on first use, via event_once */
41 static void event_initialize(void) {
42  int i;
43  for (i = 0; i != event_sync_partitions; i++) {
46  }
47 }
48 
49 /* Hash ev into an element of sync_array[]. */
50 static struct sync_array_s* hash(gpr_event* ev) {
51  return &sync_array[reinterpret_cast<uintptr_t>(ev) % event_sync_partitions];
52 }
53 
56  ev->state = 0;
57 }
58 
59 void gpr_event_set(gpr_event* ev, void* value) {
60  struct sync_array_s* s = hash(ev);
61  gpr_mu_lock(&s->mu);
62  GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0);
64  gpr_cv_broadcast(&s->cv);
65  gpr_mu_unlock(&s->mu);
66  GPR_ASSERT(value != nullptr);
67 }
68 
70  return reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
71 }
72 
73 void* gpr_event_wait(gpr_event* ev, gpr_timespec abs_deadline) {
74  void* result = reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
75  if (result == nullptr) {
76  struct sync_array_s* s = hash(ev);
77  gpr_mu_lock(&s->mu);
78  do {
79  result = reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
80  } while (result == nullptr && !gpr_cv_wait(&s->cv, &s->mu, abs_deadline));
81  gpr_mu_unlock(&s->mu);
82  }
83  return result;
84 }
85 
86 void gpr_ref_init(gpr_refcount* r, int n) { gpr_atm_rel_store(&r->count, n); }
87 
89 
91 #ifndef NDEBUG
92  gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1);
93  assert(prior > 0);
94 #else
95  gpr_ref(r);
96 #endif
97 }
98 
99 void gpr_refn(gpr_refcount* r, int n) {
100  gpr_atm_no_barrier_fetch_add(&r->count, n);
101 }
102 
104  gpr_atm prior = gpr_atm_full_fetch_add(&r->count, -1);
105  GPR_ASSERT(prior > 0);
106  return prior == 1;
107 }
108 
110  return gpr_atm_acq_load(&r->count) == 1;
111 }
112 
114  gpr_atm_rel_store(&c->value, n);
115 }
116 
119 }
120 
122  /* don't need acquire-load, but we have no no-barrier load yet */
123  return gpr_atm_acq_load(&c->value);
124 }
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
gpr_atm_full_fetch_add
#define gpr_atm_full_fetch_add(p, delta)
Definition: impl/codegen/atm_gcc_atomic.h:62
log.h
gpr_event_set
void gpr_event_set(gpr_event *ev, void *value)
Definition: sync.cc:59
inc
static void inc(void *v)
Definition: spinlock_test.cc:125
gpr_ref_is_unique
int gpr_ref_is_unique(gpr_refcount *r)
Definition: sync.cc:109
gpr_once
pthread_once_t gpr_once
Definition: impl/codegen/sync_posix.h:50
gpr_cv
pthread_cond_t gpr_cv
Definition: impl/codegen/sync_posix.h:48
gpr_ref
void gpr_ref(gpr_refcount *r)
Definition: sync.cc:88
hash
static struct sync_array_s * hash(gpr_event *ev)
Definition: sync.cc:50
GPR_ONCE_INIT
#define GPR_ONCE_INIT
Definition: impl/codegen/sync_posix.h:52
gpr_event::state
gpr_atm state
Definition: impl/codegen/sync_generic.h:32
gpr_refcount
Definition: impl/codegen/sync_generic.h:39
gpr_stats_counter
Definition: impl/codegen/sync_generic.h:44
gpr_once_init
GPRAPI void gpr_once_init(gpr_once *once, void(*init_function)(void))
gpr_refn
void gpr_refn(gpr_refcount *r, int n)
Definition: sync.cc:99
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
gpr_ref_non_zero
void gpr_ref_non_zero(gpr_refcount *r)
Definition: sync.cc:90
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
sync_array
static struct sync_array_s sync_array[event_sync_partitions]
gpr_event_get
void * gpr_event_get(gpr_event *ev)
Definition: sync.cc:69
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
gpr_event_wait
void * gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline)
Definition: sync.cc:73
gpr_atm_acq_load
#define gpr_atm_acq_load(p)
Definition: impl/codegen/atm_gcc_atomic.h:52
gpr_event_init
void gpr_event_init(gpr_event *ev)
Definition: sync.cc:54
event_initialize
static void event_initialize(void)
Definition: sync.cc:41
gpr_cv_wait
GPRAPI int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline)
gpr_atm_rel_store
#define gpr_atm_rel_store(p, value)
Definition: impl/codegen/atm_gcc_atomic.h:54
gpr_atm_no_barrier_fetch_add
#define gpr_atm_no_barrier_fetch_add(p, delta)
Definition: impl/codegen/atm_gcc_atomic.h:59
gpr_ref_init
void gpr_ref_init(gpr_refcount *r, int n)
Definition: sync.cc:86
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
sync_array_s::mu
gpr_mu mu
Definition: sync.cc:35
value
const char * value
Definition: hpack_parser_table.cc:165
event_once
static gpr_once event_once
Definition: sync.cc:40
gpr_atm
intptr_t gpr_atm
Definition: impl/codegen/atm_gcc_atomic.h:32
gpr_event
Definition: impl/codegen/sync_generic.h:31
sync_array_s::cv
gpr_cv cv
Definition: sync.cc:36
cv
unsigned cv
Definition: cxa_demangle.cpp:4908
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
gpr_stats_read
intptr_t gpr_stats_read(const gpr_stats_counter *c)
Definition: sync.cc:121
gpr_stats_inc
void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc)
Definition: sync.cc:117
fix_build_deps.r
r
Definition: fix_build_deps.py:491
event_sync_partitions
@ event_sync_partitions
Definition: sync.cc:31
gpr_unref
int gpr_unref(gpr_refcount *r)
Definition: sync.cc:103
gpr_cv_broadcast
GPRAPI void gpr_cv_broadcast(gpr_cv *cv)
gpr_stats_init
void gpr_stats_init(gpr_stats_counter *c, intptr_t n)
Definition: sync.cc:113
atm.h
gpr_timespec
Definition: gpr_types.h:50
sync_array_s
Definition: sync.cc:34
sync.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
gpr_cv_init
GPRAPI void gpr_cv_init(gpr_cv *cv)
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:28