about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-11-11 11:46:07 -0800
committerBrian Anderson <banderson@mozilla.com>2011-11-11 12:11:21 -0800
commit5d1e321ecbdaf50fe4723b698081c7cda60d366a (patch)
treeb9d5bc27f8787a81a67647db4543ed3204040721
parent39084fb881a1a0fd2db6c8df04ccd5cc0a9c6716 (diff)
downloadrust-5d1e321ecbdaf50fe4723b698081c7cda60d366a.tar.gz
rust-5d1e321ecbdaf50fe4723b698081c7cda60d366a.zip
rt: Remove rust_chan
-rw-r--r--mk/rt.mk2
-rw-r--r--src/rt/rust_builtin.cpp13
-rw-r--r--src/rt/rust_chan.cpp53
-rw-r--r--src/rt/rust_chan.h35
-rw-r--r--src/rt/rust_internal.h2
-rw-r--r--src/rt/rust_port.cpp39
-rw-r--r--src/rt/rust_port.h4
-rw-r--r--src/rt/rust_task.cpp19
-rw-r--r--src/rt/rust_task.h2
9 files changed, 29 insertions, 140 deletions
diff --git a/mk/rt.mk b/mk/rt.mk
index 5aa1a390dfa..0208fe7ab55 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -45,7 +45,6 @@ RUNTIME_CS_$(1) := \
               rt/rust_scheduler.cpp \
               rt/rust_task.cpp \
               rt/rust_task_list.cpp \
-              rt/rust_chan.cpp \
               rt/rust_port.cpp \
               rt/rust_upcall.cpp \
               rt/rust_log.cpp \
@@ -78,7 +77,6 @@ RUNTIME_HDR_$(1) := rt/globals.h \
                rt/rust_gc.h \
                rt/rust_internal.h \
                rt/rust_util.h \
-               rt/rust_chan.h \
                rt/rust_env.h \
                rt/rust_obstack.h \
                rt/rust_unwind.h \
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 4086e3708fd..3b69fcf9466 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -463,8 +463,7 @@ new_port(size_t unit_sz) {
     rust_task *task = rust_scheduler::get_task();
     LOG(task, comm, "new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)",
         (uintptr_t) task, task->name, unit_sz);
-    // take a reference on behalf of the port
-    task->ref();
+    // port starts with refcount == 1
     return new (task->kernel, "rust_port") rust_port(task, unit_sz);
 }
 
@@ -472,11 +471,7 @@ extern "C" CDECL void
 del_port(rust_port *port) {
     rust_task *task = rust_scheduler::get_task();
     LOG(task, comm, "del_port(0x%" PRIxPTR ")", (uintptr_t) port);
-    I(task->sched, !port->ref_count);
-    delete port;
-
-    // FIXME: this should happen in the port.
-    task->deref();
+    port->deref();
 }
 
 extern "C" CDECL rust_port_id
@@ -486,7 +481,6 @@ get_port_id(rust_port *port) {
 
 extern "C" CDECL
 void drop_port(rust_port *port) {
-    port->ref_count--;
 }
 
 extern "C" CDECL void
@@ -497,10 +491,11 @@ chan_id_send(type_desc *t, rust_task_id target_task_id,
     rust_task *target_task = task->kernel->get_task_by_id(target_task_id);
     if(target_task) {
         rust_port *port = target_task->get_port_by_id(target_port_id);
+        target_task->deref();
         if(port) {
             port->send(sptr);
+            port->deref();
         }
-        target_task->deref();
     }
 }
 
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp
deleted file mode 100644
index 9a41dacc323..00000000000
--- a/src/rt/rust_chan.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "rust_internal.h"
-#include "rust_chan.h"
-
-/**
- * Create a new rust channel and associate it with the specified port.
- */
-rust_chan::rust_chan(rust_kernel *kernel, rust_port *port,
-                     size_t unit_sz)
-    : ref_count(0),
-      kernel(kernel),
-      port(port),
-      buffer(kernel, unit_sz) {
-    KLOG(kernel, comm, "new rust_chan(task=0x%" PRIxPTR
-        ", port=0x%" PRIxPTR ") -> chan=0x%" PRIxPTR,
-        (uintptr_t) task, (uintptr_t) port, (uintptr_t) this);
-
-    A(kernel, port != NULL, "Port must not be null");
-    this->task = port->task;
-    this->task->ref();
-}
-
-rust_chan::~rust_chan() {
-    KLOG(kernel, comm, "del rust_chan(task=0x%" PRIxPTR ")",
-         (uintptr_t) this);
-
-    I(this->kernel, !is_associated());
-
-    A(kernel, is_associated() == false,
-      "Channel must be disassociated before being freed.");
-
-    task->deref();
-    task = NULL;
-}
-
-bool rust_chan::is_associated() {
-    return port != NULL;
-}
-
-rust_chan *rust_chan::clone(rust_task *target) {
-    return new (target->kernel, "cloned chan")
-        rust_chan(kernel, port, buffer.unit_sz);
-}
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
-// End:
-//
diff --git a/src/rt/rust_chan.h b/src/rt/rust_chan.h
deleted file mode 100644
index 4fb78e062c7..00000000000
--- a/src/rt/rust_chan.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef RUST_CHAN_H
-#define RUST_CHAN_H
-
-class rust_chan : public kernel_owned<rust_chan>,
-                  public rust_cond {
-    ~rust_chan();
-
-public:
-    RUST_ATOMIC_REFCOUNT();
-    rust_chan(rust_kernel *kernel, rust_port *port,
-              size_t unit_sz);
-
-    rust_kernel *kernel;
-    rust_task *task;
-    rust_port *port;
-    size_t idx;
-    circular_buffer buffer;
-
-    bool is_associated();
-
-    rust_chan *clone(rust_task *target);
-};
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
-// End:
-//
-
-#endif /* RUST_CHAN_H */
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index 4189e5a39bf..1e65d701e8f 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -55,7 +55,6 @@ struct rust_scheduler;
 struct rust_task;
 class rust_log;
 class rust_port;
-class rust_chan;
 class rust_kernel;
 class rust_crate_cache;
 
@@ -282,7 +281,6 @@ struct type_desc {
 
 #include "circular_buffer.h"
 #include "rust_task.h"
-#include "rust_chan.h"
 #include "rust_port.h"
 #include "memory.h"
 
diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp
index a68b4417110..5daf5e40033 100644
--- a/src/rt/rust_port.cpp
+++ b/src/rt/rust_port.cpp
@@ -1,61 +1,47 @@
 #include "rust_internal.h"
 #include "rust_port.h"
-#include "rust_chan.h"
 
 
 rust_port::rust_port(rust_task *task, size_t unit_sz)
     : ref_count(1), kernel(task->kernel), task(task),
-      unit_sz(unit_sz) {
+      unit_sz(unit_sz), buffer(kernel, unit_sz) {
 
     LOG(task, comm,
         "new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%"
         PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this);
 
+    task->ref();
     id = task->register_port(this);
-    remote_chan = new (task->kernel, "rust_chan")
-        rust_chan(task->kernel, this, unit_sz);
-    remote_chan->ref();
-    remote_chan->port = this;
 }
 
 rust_port::~rust_port() {
     LOG(task, comm, "~rust_port 0x%" PRIxPTR, (uintptr_t) this);
 
-    {
-        scoped_lock with(lock);
-        remote_chan->port = NULL;
-        remote_chan->deref();
-        remote_chan = NULL;
-    }
-
     task->release_port(id);
+    task->deref();
 }
 
 void rust_port::send(void *sptr) {
-    if (!remote_chan->is_associated()) {
-        W(kernel, remote_chan->is_associated(),
-          "rust_chan::transmit with no associated port.");
-        return;
-    }
-
+    // FIXME: Is this lock really necessary? Why do we send with the lock
+    // but not receive with the lock?
     scoped_lock with(lock);
 
-    remote_chan->buffer.enqueue(sptr);
+    buffer.enqueue(sptr);
 
-    A(kernel, !remote_chan->buffer.is_empty(),
+    A(kernel, !buffer.is_empty(),
       "rust_chan::transmit with nothing to send.");
 
     if (task->blocked_on(this)) {
         KLOG(kernel, comm, "dequeued in rendezvous_ptr");
-        remote_chan->buffer.dequeue(task->rendezvous_ptr);
+        buffer.dequeue(task->rendezvous_ptr);
         task->rendezvous_ptr = 0;
         task->wakeup(this);
     }
 }
 
 bool rust_port::receive(void *dptr) {
-    if (remote_chan->buffer.is_empty() == false) {
-        remote_chan->buffer.dequeue(dptr);
+    if (buffer.is_empty() == false) {
+        buffer.dequeue(dptr);
         LOG(task, comm, "<=== read data ===");
         return true;
     }
@@ -64,9 +50,8 @@ bool rust_port::receive(void *dptr) {
 
 void rust_port::log_state() {
     LOG(task, comm,
-        "\tchan: 0x%" PRIxPTR ", size: %d",
-        remote_chan,
-        remote_chan->buffer.size());
+        "port size: %d",
+        buffer.size());
 }
 
 //
diff --git a/src/rt/rust_port.h b/src/rt/rust_port.h
index 551ad2e89da..4f735c59b63 100644
--- a/src/rt/rust_port.h
+++ b/src/rt/rust_port.h
@@ -3,14 +3,14 @@
 
 class rust_port : public kernel_owned<rust_port>, public rust_cond {
 public:
-    RUST_REFCOUNTED(rust_port);
+    RUST_ATOMIC_REFCOUNT();
 
     rust_port_id id;
 
     rust_kernel *kernel;
     rust_task *task;
-    rust_chan *remote_chan;
     size_t unit_sz;
+    circular_buffer buffer;
 
     lock_and_signal lock;
 
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 854c2c74462..493f1635510 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -122,21 +122,20 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
 rust_task::~rust_task()
 {
     I(sched, !sched->lock.lock_held_by_current_thread());
+    I(sched, port_table.is_empty());
     DLOG(sched, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d",
          name, (uintptr_t)this, ref_count);
 
     if(user.notify_enabled) {
-        rust_chan *target =
-            get_chan_by_handle(&user.notify_chan);
+        rust_port *target =
+            get_port_by_chan_handle(&user.notify_chan);
         if(target) {
             task_notification msg;
             msg.id = user.id;
             msg.result = failed ? tr_failure : tr_success;
 
-            if (target->is_associated()) {
-                target->port->send(&msg);
-                target->deref();
-            }
+            target->send(&msg);
+            target->deref();
         }
     }
 
@@ -552,16 +551,18 @@ rust_port *rust_task::get_port_by_id(rust_port_id id) {
     scoped_lock with(lock);
     rust_port *port = NULL;
     port_table.get(id, &port);
+    if (port) {
+        port->ref();
+    }
     return port;
 }
 
-rust_chan *rust_task::get_chan_by_handle(chan_handle *handle) {
+rust_port *rust_task::get_port_by_chan_handle(chan_handle *handle) {
     rust_task *target_task = kernel->get_task_by_id(handle->task);
     if(target_task) {
         rust_port *port = target_task->get_port_by_id(handle->port);
         target_task->deref();
-        port->remote_chan->ref();
-        return port->remote_chan;
+        return port;
     }
     return NULL;
 }
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 783d46eaced..3bdc900250d 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -209,7 +209,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
     // not at all safe.
     intptr_t get_ref_count() const { return ref_count; }
 
-    rust_chan *get_chan_by_handle(chan_handle *handle);
+    rust_port *get_port_by_chan_handle(chan_handle *handle);
 
     // FIXME: These functions only exist to get the tasking system off the
     // ground. We should never be migrating shared boxes between tasks.