4
4
/* *
5
5
* Create a new rust channel and associate it with the specified port.
6
6
*/
7
- rust_chan::rust_chan (rust_kernel *kernel, maybe_proxy< rust_port> *port,
7
+ rust_chan::rust_chan (rust_kernel *kernel, rust_port *port,
8
8
size_t unit_sz)
9
9
: ref_count(1 ),
10
10
kernel(kernel),
@@ -29,18 +29,16 @@ rust_chan::~rust_chan() {
29
29
/* *
30
30
* Link this channel with the specified port.
31
31
*/
32
- void rust_chan::associate (maybe_proxy< rust_port> *port) {
32
+ void rust_chan::associate (rust_port *port) {
33
33
this ->port = port;
34
- if (port->is_proxy () == false ) {
35
- scoped_lock with (port->referent ()->lock );
36
- KLOG (kernel, task,
37
- " associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
38
- this , port);
39
- ++this ->ref_count ;
40
- this ->task = port->referent ()->task ;
41
- this ->task ->ref ();
42
- this ->port ->referent ()->chans .push (this );
43
- }
34
+ scoped_lock with (port->lock );
35
+ KLOG (kernel, task,
36
+ " associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
37
+ this , port);
38
+ ++this ->ref_count ;
39
+ this ->task = port->task ;
40
+ this ->task ->ref ();
41
+ this ->port ->chans .push (this );
44
42
}
45
43
46
44
bool rust_chan::is_associated () {
@@ -52,19 +50,17 @@ bool rust_chan::is_associated() {
52
50
*/
53
51
void rust_chan::disassociate () {
54
52
A (kernel,
55
- port->referent ()-> lock .lock_held_by_current_thread (),
53
+ port->lock .lock_held_by_current_thread (),
56
54
" Port referent lock must be held to call rust_chan::disassociate" );
57
55
A (kernel, is_associated (),
58
56
" Channel must be associated with a port." );
59
- if (port->is_proxy () == false ) {
60
- KLOG (kernel, task,
61
- " disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
62
- this , port->referent ());
63
- --this ->ref_count ;
64
- task->deref ();
65
- this ->task = NULL ;
66
- port->referent ()->chans .swap_delete (this );
67
- }
57
+ KLOG (kernel, task,
58
+ " disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
59
+ this , port);
60
+ --this ->ref_count ;
61
+ task->deref ();
62
+ this ->task = NULL ;
63
+ port->chans .swap_delete (this );
68
64
69
65
// Delete reference to the port.
70
66
port = NULL ;
@@ -74,12 +70,7 @@ void rust_chan::disassociate() {
74
70
* Attempt to send data to the associated port.
75
71
*/
76
72
void rust_chan::send (void *sptr) {
77
- I (kernel, !port->is_proxy ());
78
-
79
- rust_port *target_port = port->referent ();
80
- // TODO: We can probably avoid this lock by using atomic operations in
81
- // circular_buffer.
82
- scoped_lock with (target_port->lock );
73
+ scoped_lock with (port->lock );
83
74
84
75
buffer.enqueue (sptr);
85
76
@@ -92,28 +83,17 @@ void rust_chan::send(void *sptr) {
92
83
A (kernel, !buffer.is_empty (),
93
84
" rust_chan::transmit with nothing to send." );
94
85
95
- if (port->is_proxy ()) {
96
- data_message::send (buffer.peek (), buffer.unit_sz , " send data" ,
97
- task->get_handle (), port->as_proxy ()->handle ());
98
- buffer.dequeue (NULL );
99
- } else {
100
- if (target_port->task ->blocked_on (target_port)) {
101
- KLOG (kernel, comm, " dequeued in rendezvous_ptr" );
102
- buffer.dequeue (target_port->task ->rendezvous_ptr );
103
- target_port->task ->rendezvous_ptr = 0 ;
104
- target_port->task ->wakeup (target_port);
105
- return ;
106
- }
86
+ if (port->task ->blocked_on (port)) {
87
+ KLOG (kernel, comm, " dequeued in rendezvous_ptr" );
88
+ buffer.dequeue (port->task ->rendezvous_ptr );
89
+ port->task ->rendezvous_ptr = 0 ;
90
+ port->task ->wakeup (port);
107
91
}
108
-
109
- return ;
110
92
}
111
93
112
94
rust_chan *rust_chan::clone (rust_task *target) {
113
- size_t unit_sz = buffer.unit_sz ;
114
- maybe_proxy<rust_port> *port = this ->port ;
115
95
return new (target->kernel , " cloned chan" )
116
- rust_chan (kernel, port, unit_sz);
96
+ rust_chan (kernel, port, buffer. unit_sz );
117
97
}
118
98
119
99
/* *
@@ -125,30 +105,21 @@ void rust_chan::destroy() {
125
105
" Channel's ref count should be zero." );
126
106
127
107
if (is_associated ()) {
128
- if (port->is_proxy ()) {
129
- // Here is a good place to delete the port proxy we allocated
130
- // in upcall_clone_chan.
131
- rust_proxy<rust_port> *proxy = port->as_proxy ();
132
- scoped_lock with (port->referent ()->lock );
133
- disassociate ();
134
- delete proxy;
135
- } else {
136
- // We're trying to delete a channel that another task may be
137
- // reading from. We have two options:
138
- //
139
- // 1. We can flush the channel by blocking in upcall_flush_chan()
140
- // and resuming only when the channel is flushed. The problem
141
- // here is that we can get ourselves in a deadlock if the
142
- // parent task tries to join us.
143
- //
144
- // 2. We can leave the channel in a "dormnat" state by not freeing
145
- // it and letting the receiver task delete it for us instead.
146
- if (buffer.is_empty () == false ) {
147
- return ;
148
- }
149
- scoped_lock with (port->referent ()->lock );
150
- disassociate ();
108
+ // We're trying to delete a channel that another task may be
109
+ // reading from. We have two options:
110
+ //
111
+ // 1. We can flush the channel by blocking in upcall_flush_chan()
112
+ // and resuming only when the channel is flushed. The problem
113
+ // here is that we can get ourselves in a deadlock if the
114
+ // parent task tries to join us.
115
+ //
116
+ // 2. We can leave the channel in a "dormnat" state by not freeing
117
+ // it and letting the receiver task delete it for us instead.
118
+ if (buffer.is_empty () == false ) {
119
+ return ;
151
120
}
121
+ scoped_lock with (port->lock );
122
+ disassociate ();
152
123
}
153
124
delete this ;
154
125
}
0 commit comments