mm_netbuf_fill(struct mm_netbuf_socket *sock, size_t cnt) { ENTER(); ASSERT(mm_netbuf_thread(sock) == mm_thread_self()); ssize_t rc; struct mm_buffer *buf = &sock->rxbuf; char *ptr = buf->tail.ptr; size_t len = buf->tail.end - ptr; while (len == 0 && mm_buffer_iterator_next_check(&buf->tail)) { mm_buffer_iterator_write_next_unsafe(&buf->tail); ptr = buf->tail.ptr; len = buf->tail.end - ptr; } if (len >= cnt) { rc = mm_net_read(&sock->sock, ptr, len); } else { int iovcnt = 0; struct iovec iov[MM_NETBUF_MAXIOV]; size_t nbytes = len; if (len) { iovcnt = 1; iov[0].iov_len = len; iov[0].iov_base = ptr; } struct mm_buffer_iterator iter = buf->tail; do { if (!mm_buffer_iterator_write_next(&iter)) { mm_buffer_extend(buf, &iter, cnt - nbytes); iter = buf->tail; } ptr = iter.ptr; len = iter.end - ptr; nbytes += len; iov[iovcnt].iov_len = len; iov[iovcnt].iov_base = ptr; if (unlikely(++iovcnt == MM_NETBUF_MAXIOV)) break; } while (unlikely(nbytes < cnt)); if (nbytes) rc = mm_net_readv(&sock->sock, iov, iovcnt, nbytes); else rc = 0; } if (rc > 0) mm_buffer_fill(buf, rc); DEBUG("rc: %ld", (long) rc); LEAVE(); return rc; }
struct mm_chunk * MALLOC mm_chunk_create_private(size_t size) { size += sizeof(struct mm_chunk); struct mm_chunk *chunk = mm_private_alloc(size); chunk->base.tag = mm_thread_self(); mm_slink_prepare(&chunk->base.slink); return chunk; }
mm_netbuf_flush(struct mm_netbuf_socket *sock) { ENTER(); ASSERT(mm_netbuf_thread(sock) == mm_thread_self()); ssize_t rc; struct mm_buffer *buf = &sock->txbuf; char *ptr = buf->head.ptr; size_t len = buf->head.end - ptr; while (len == 0 && mm_buffer_iterator_next_check(&buf->head)) { mm_buffer_iterator_read_next_unsafe(&buf->head); ptr = buf->head.ptr; len = buf->head.end - ptr; } if (!mm_buffer_iterator_next_check(&buf->head)) { rc = mm_net_write(&sock->sock, ptr, len); } else { int iovcnt = 0; struct iovec iov[MM_NETBUF_MAXIOV]; size_t nbytes = len; if (len) { iovcnt = 1; iov[0].iov_len = len; iov[0].iov_base = ptr; } struct mm_buffer_iterator iter = buf->head; while (mm_buffer_iterator_read_next(&iter)) { ptr = iter.ptr; len = iter.end - ptr; nbytes += len; iov[iovcnt].iov_len = len; iov[iovcnt].iov_base = ptr; if (unlikely(++iovcnt == MM_NETBUF_MAXIOV)) break; } if (nbytes) rc = mm_net_writev(&sock->sock, iov, iovcnt, len); else rc = 0; } if (rc > 0) mm_buffer_flush(buf, rc); DEBUG("rc: %ld", (long) rc); LEAVE(); return rc; }
/* Entry point for a task. */ static void mm_task_entry(void) { struct mm_task *task = mm_task_self(); #if ENABLE_TRACE mm_trace_context_prepare(&task->trace, "[%s][%d %s]", mm_thread_getname(mm_thread_self()), mm_task_getid(task), mm_task_getname(task)); #endif TRACE("enter task %s", mm_task_getname(task)); // Execute the task routine on an empty stack. mm_value_t result = task->start(task->start_arg); // Finish the task making sure there is no return from this point // as there is no valid stack frame above it. mm_task_exit(result); }