Beispiel #1
0
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 );
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
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 );
}
Beispiel #5
0
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;
}
Beispiel #6
0
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) );
    }
}
Beispiel #7
0
void release_socket_request(struct sockreq *req, int rc) {
  cancel_socket_request(req);
  req->rc = rc;
  mark_thread_ready(req->thread, 1, 2);
}