static void send_item_to_thread( obj mbox, obj thr, obj item ) { UNBLOCK_THREAD( thr ); store_resume_value( thr, item ); mark_thread_ready( thr ); if (dequeue_empty( mbox )) gvec_write_non_ptr( mbox, MAILBOX_HAS_DATA_Q, TRUE_OBJ ); }
static int virtiocon_output_callback(struct virtio_queue *vq) { struct thread *thread; unsigned int len; kprintf("[VCO]"); while ((thread = virtio_dequeue(vq, &len)) != NULL) { mark_thread_ready(thread, 1, 2); } return 0; }
static int virtioblk_callback(struct virtio_queue *vq) { struct virtioblk_request *req; unsigned int len; while ((req = virtio_dequeue(vq, &len)) != NULL) { req->size = len; mark_thread_ready(req->thread, 1, 2); } return 0; }
void krelease_joiners( obj t ) { obj p; for (p=gvec_ref( t, THREAD_JOINS ); !NULL_P(p); p=pair_cdr(p)) { obj jt = pair_car(p); assert( EQ( gvec_ref( jt, THREAD_BLOCKED_ON ), t )); UNBLOCK_THREAD( jt ); store_resume_value( jt, REG0 ); mark_thread_ready( jt ); } gvec_write_non_ptr( t, THREAD_JOINS, NIL_OBJ ); }
static void release_klog_waiters(void *arg) { struct klogreq *waiter; // Defer scheduling of kernel log waiter if we are in a interrupt handler if ((eflags() & EFLAG_IF) == 0) { queue_irq_dpc(&klog_dpc, release_klog_waiters, NULL); return; } waiter = klog_waiters; while (waiter) { waiter->rc = 0; mark_thread_ready(waiter->thread, 1, 2); waiter = waiter->next; } klog_waiters = NULL; }
void mark_thread_resumed( obj th ) { obj susp_count = gvec_ref( th, THREAD_SUSPEND_COUNT ); int still_in_q = 1; if (FX_LT( susp_count, ZERO )) { still_in_q = 0; susp_count = FX_SUB( ZERO, susp_count ); } else if (EQ( susp_count, ZERO )) { /* do nothing */ return; } susp_count = SUB1( susp_count ); if (EQ( susp_count, ZERO )) { obj blkd_on = gvec_ref( th, THREAD_BLOCKED_ON ); gvec_write_non_ptr( th, THREAD_SUSPEND_COUNT, ZERO ); /* unblock it */ if (EQ( blkd_on, ZERO )) { /* if it IS still in the queue, then we need do nothing */ if (!still_in_q) mark_thread_ready( th ); } else if (FIXNUM_P( blkd_on )) { /* it's an Event, so it must have been sleeping *and* the timer hasn't gone off (see comments in `class.scm') */ assert( still_in_q ); gvec_set( th, THREAD_STATE, int2fx( TSTATE_SLEEPING ) ); } else { /* it must be some other object, like a <mailbox> */ if (!still_in_q) { /* put it back in the queue */ requeue( th, blkd_on ); } } } else { /* still suspended */ if (still_in_q) gvec_write_non_ptr( th, THREAD_SUSPEND_COUNT, susp_count ); else gvec_write_non_ptr( th, THREAD_SUSPEND_COUNT, FX_SUB(ZERO,susp_count) ); } }
void release_socket_request(struct sockreq *req, int rc) { cancel_socket_request(req); req->rc = rc; mark_thread_ready(req->thread, 1, 2); }