Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(833)

Unified Diff: runtime/bin/eventhandler_linux.cc

Issue 9186035: Use hash map for event handler file descriptor map (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r3482 Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/eventhandler_linux.cc
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 296fafba1ebdbab2b81486fe0c9df0974336c127..69551df9724a79a19d1885858fb0cac8f17f99cf 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -12,6 +12,8 @@
#include "bin/eventhandler.h"
#include "bin/fdutils.h"
+#include "bin/hashmap.h"
+#include "platform/utils.h"
int64_t GetCurrentTimeMilliseconds() {
@@ -24,8 +26,6 @@ int64_t GetCurrentTimeMilliseconds() {
}
-static const int kInitialPortMapSize = 16;
-static const int kPortMapGrowingFactor = 2;
static const int kInterruptMessageSize = sizeof(InterruptMessage);
static const int kInfinityTimeout = -1;
static const int kTimerId = -1;
@@ -49,12 +49,9 @@ intptr_t SocketData::GetPollEvents() {
}
-EventHandlerImplementation::EventHandlerImplementation() {
+EventHandlerImplementation::EventHandlerImplementation()
+ : socket_map_(&HashMap::SamePointerValue, 16) {
intptr_t result;
- socket_map_size_ = kInitialPortMapSize;
- socket_map_ = reinterpret_cast<SocketData*>(calloc(socket_map_size_,
- sizeof(SocketData)));
- ASSERT(socket_map_ != NULL);
result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_));
if (result != 0) {
FATAL("Pipe creation failed");
@@ -66,33 +63,24 @@ EventHandlerImplementation::EventHandlerImplementation() {
EventHandlerImplementation::~EventHandlerImplementation() {
- free(socket_map_);
TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
}
-// TODO(hpayer): Use hash table instead of array.
SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
ASSERT(fd >= 0);
- if (fd >= socket_map_size_) {
- intptr_t new_socket_map_size = socket_map_size_;
- do {
- new_socket_map_size = new_socket_map_size * kPortMapGrowingFactor;
- } while (fd >= new_socket_map_size);
- size_t new_socket_map_bytes = new_socket_map_size * sizeof(SocketData);
- socket_map_ = reinterpret_cast<SocketData*>(realloc(socket_map_,
- new_socket_map_bytes));
- ASSERT(socket_map_ != NULL);
- size_t socket_map_bytes = socket_map_size_ * sizeof(SocketData);
- memset(socket_map_ + socket_map_size_,
- 0,
- new_socket_map_bytes - socket_map_bytes);
- socket_map_size_ = new_socket_map_size;
+ HashMap::Entry* entry = socket_map_.Lookup(
+ GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
+ ASSERT(entry != NULL);
+ SocketData* sd = reinterpret_cast<SocketData*>(entry->value);
+ if (sd == NULL) {
+ // If there is no data in the hash map for this file descriptor
+ // then this is inserting a new SocketData for the file descriptor.
+ sd = new SocketData(fd);
+ entry->value = sd;
}
-
- SocketData* sd = socket_map_ + fd;
- sd->set_fd(fd); // For now just make sure the fd is set.
+ ASSERT(fd == sd->fd());
return sd;
}
@@ -117,8 +105,10 @@ struct pollfd* EventHandlerImplementation::GetPollFds(intptr_t* pollfds_size) {
// Calculate the number of file descriptors to poll on.
intptr_t numPollfds = 1;
- for (int i = 0; i < socket_map_size_; i++) {
- SocketData* sd = &socket_map_[i];
+ for (HashMap::Entry* entry = socket_map_.Start();
+ entry != NULL;
+ entry = socket_map_.Next(entry)) {
+ SocketData* sd = reinterpret_cast<SocketData*>(entry->value);
if (sd->port() > 0 && sd->GetPollEvents() != 0) numPollfds++;
}
@@ -127,20 +117,22 @@ struct pollfd* EventHandlerImplementation::GetPollFds(intptr_t* pollfds_size) {
pollfds[0].fd = interrupt_fds_[0];
pollfds[0].events |= POLLIN;
- // TODO(hpayer): optimize the following iteration over the hash map
- int j = 1;
- for (int i = 0; i < socket_map_size_; i++) {
- SocketData* sd = &socket_map_[i];
+ int i = 1;
+ for (HashMap::Entry* entry = socket_map_.Start();
+ entry != NULL;
+ entry = socket_map_.Next(entry)) {
+ SocketData* sd = reinterpret_cast<SocketData*>(entry->value);
intptr_t events = sd->GetPollEvents();
if (sd->port() > 0 && events != 0) {
// Fd is added to the poll set.
- pollfds[j].fd = sd->fd();
- pollfds[j].events = events;
- j++;
+ pollfds[i].fd = sd->fd();
+ pollfds[i].events = events;
+ i++;
}
}
- ASSERT(numPollfds == j);
- *pollfds_size = j;
+ ASSERT(numPollfds == i);
+ *pollfds_size = i;
+
return pollfds;
}
@@ -183,7 +175,10 @@ void EventHandlerImplementation::HandleInterruptFd() {
} else if ((msg.data & (1 << kCloseCommand)) != 0) {
ASSERT(msg.data == (1 << kCloseCommand));
// Close the socket and free system resources.
+ intptr_t fd = sd->fd();
sd->Close();
+ socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
+ delete sd;
} else {
// Setup events to wait for.
sd->SetPortAndMask(msg.dart_port, msg.data);
@@ -382,3 +377,15 @@ void EventHandlerImplementation::SendData(intptr_t id,
intptr_t data) {
WakeupHandler(id, dart_port, data);
}
+
+
+void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) {
+ // The hashmap does not support keys with value 0.
+ return reinterpret_cast<void*>(fd + 1);
+}
+
+
+uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) {
+ // The hashmap does not support keys with value 0.
+ return dart::Utils::WordHash(fd + 1);
+}
« no previous file with comments | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698