Merge pull request #413 from dklempner/kick_fd_mutex

Move pollset_kick wfd creation/destruction out of freelist lock
changes/72/217572/1
Craig Tiller 10 years ago
commit e83fe4c903
  1. 41
      src/core/iomgr/pollset_kick.c

@ -48,49 +48,49 @@
/* This implementation is based on a freelist of wakeup fds, with extra logic to /* This implementation is based on a freelist of wakeup fds, with extra logic to
* handle kicks while there is no attached fd. */ * handle kicks while there is no attached fd. */
/* TODO(klempner): Autosize this, and consider providing a way to disable the
* cap entirely on systems with large fd limits */
#define GRPC_MAX_CACHED_WFDS 50 #define GRPC_MAX_CACHED_WFDS 50
#define GRPC_WFD_LOW_WATERMARK 25
static grpc_kick_fd_info *fd_freelist = NULL; static grpc_kick_fd_info *fd_freelist = NULL;
static int fd_freelist_count = 0; static int fd_freelist_count = 0;
static gpr_mu fd_freelist_mu; static gpr_mu fd_freelist_mu;
static grpc_kick_fd_info *allocate_wfd(void) { static grpc_kick_fd_info *allocate_wfd(void) {
grpc_kick_fd_info *info; grpc_kick_fd_info *info = NULL;
gpr_mu_lock(&fd_freelist_mu); gpr_mu_lock(&fd_freelist_mu);
if (fd_freelist != NULL) { if (fd_freelist != NULL) {
info = fd_freelist; info = fd_freelist;
fd_freelist = fd_freelist->next; fd_freelist = fd_freelist->next;
--fd_freelist_count; --fd_freelist_count;
} else { }
gpr_mu_unlock(&fd_freelist_mu);
if (info == NULL) {
info = gpr_malloc(sizeof(*info)); info = gpr_malloc(sizeof(*info));
grpc_wakeup_fd_create(&info->wakeup_fd); grpc_wakeup_fd_create(&info->wakeup_fd);
info->next = NULL; info->next = NULL;
} }
gpr_mu_unlock(&fd_freelist_mu);
return info; return info;
} }
static void destroy_wfd(void) { static void destroy_wfd(grpc_kick_fd_info* wfd) {
/* assumes fd_freelist_mu is held */ grpc_wakeup_fd_destroy(&wfd->wakeup_fd);
grpc_kick_fd_info *current = fd_freelist; gpr_free(wfd);
fd_freelist = fd_freelist->next;
fd_freelist_count--;
grpc_wakeup_fd_destroy(&current->wakeup_fd);
gpr_free(current);
} }
static void free_wfd(grpc_kick_fd_info *fd_info) { static void free_wfd(grpc_kick_fd_info *fd_info) {
gpr_mu_lock(&fd_freelist_mu); gpr_mu_lock(&fd_freelist_mu);
fd_info->next = fd_freelist; if (fd_freelist_count < GRPC_MAX_CACHED_WFDS) {
fd_freelist = fd_info; fd_info->next = fd_freelist;
fd_freelist_count++; fd_freelist = fd_info;
if (fd_freelist_count > GRPC_MAX_CACHED_WFDS) { fd_freelist_count++;
while (fd_freelist_count > GRPC_WFD_LOW_WATERMARK) { fd_info = NULL;
destroy_wfd();
}
} }
gpr_mu_unlock(&fd_freelist_mu); gpr_mu_unlock(&fd_freelist_mu);
if (fd_info) {
destroy_wfd(fd_info);
}
} }
void grpc_pollset_kick_init(grpc_pollset_kick_state *kick_state) { void grpc_pollset_kick_init(grpc_pollset_kick_state *kick_state) {
@ -148,6 +148,11 @@ void grpc_pollset_kick_global_init(void) {
} }
void grpc_pollset_kick_global_destroy(void) { void grpc_pollset_kick_global_destroy(void) {
while (fd_freelist != NULL) {
grpc_kick_fd_info *current = fd_freelist;
fd_freelist = fd_freelist->next;
destroy_wfd(current);
}
grpc_wakeup_fd_global_destroy(); grpc_wakeup_fd_global_destroy();
gpr_mu_destroy(&fd_freelist_mu); gpr_mu_destroy(&fd_freelist_mu);
} }

Loading…
Cancel
Save