コード例 #1
0
/*
 * chudxnu_cpu_signal_handler() is called from the IPI handler
 * when a CHUD signal arrives from another processor.
 */
__private_extern__ void
chudxnu_cpu_signal_handler(void)
{
	chudcpu_signal_request_t	*reqp;
	chudcpu_data_t			*chudinfop;

	chudinfop = (chudcpu_data_t *) current_cpu_datap()->cpu_chud;

	mpdequeue_head(&(chudinfop->cpu_request_queue),
		       (queue_entry_t *) &reqp);
	while (reqp != NULL) {
		chudxnu_private_cpu_signal_handler(reqp->req_code);
		reqp->req_sync = 0;
		mpdequeue_head(&(chudinfop->cpu_request_queue),
			       (queue_entry_t *) &reqp);
	}
}
コード例 #2
0
ファイル: kd_event.c プロジェクト: rohsaini/mkunity
void
kbd_enqueue(
	kd_event *ev)
{
	kdq_lock(&kbd_queue);
	if (kdq_full(&kbd_queue))
		printf("kbd: queue full\n");
	else
		kdq_put(&kbd_queue, ev);

	{
	    io_req_t	ior;
	    for(;;) {
		mpdequeue_head(&kbd_read_queue, (queue_entry_t *)&ior);
		if (ior)
			iodone(ior);
		else
			break;
	    }
	}
	kdq_unlock(&kbd_queue);
}
コード例 #3
0
ファイル: profile.c プロジェクト: rohsaini/mkunity
void
profile_thread(void)
{
    spl_t	    s;
    buffer_t	    buf_entry;
    queue_entry_t   prof_queue_entry;
    prof_data_t	    pbuf;
    kern_return_t   kr;
    int		    j;

    thread_swappable(current_act(), FALSE);

    /* Initialise the queue header for the prof_queue */
    mpqueue_init(&prof_queue);

    while (TRUE) {

	/* Dequeue the first buffer. */
	s = splsched();
	mpdequeue_head(&prof_queue, &prof_queue_entry);
	splx(s);

	if ((buf_entry = (buffer_t) prof_queue_entry) == NULLPBUF) { 
	    assert_wait((event_t) profile_thread, FALSE);
	    thread_block((void (*)(void)) 0);
	    if (current_thread()->wait_result != THREAD_AWAKENED)
		break;
	} else 
#if DCI
	{
	    register int    sum_samples = 0;
	    int		    i;

	    pbuf = buf_entry->p_prof;
/*
 * sum all the points from all the cpus on the machine.
*/
	    for(i=0;i < NCPUS; i++)
		sum_samples += buf_entry->p_index[i];

	    kr = send_samples(pbuf->prof_port, (void *)buf_entry->p_zone,
			(mach_msg_type_number_t)sum_samples);
	    if (kr != KERN_SUCCESS)
	    {
		task_suspend(pbuf->task); /* suspend task */
		kr = send_notices(pbuf->prof_port, (void *)buf_entry->p_zone,
				  (mach_msg_type_number_t)sum_samples,
				  MACH_SEND_ALWAYS);
	    }
	    bzero((char *)buf_entry->p_zone, NCPUS*SIZE_PROF_BUFFER);
#else
	{
	    int		    dropped;

	    pbuf = buf_entry->p_prof;
	    kr = send_samples(pbuf->prof_port, (void *)buf_entry->p_zone,
			(mach_msg_type_number_t)buf_entry->p_index);
	    profile_sample_count += buf_entry->p_index;
	    if (kr != KERN_SUCCESS)
	      printf("send_samples(%x, %x, %d) error %x\n",
			pbuf->prof_port, buf_entry->p_zone, buf_entry->p_index, kr); 
	    dropped = buf_entry->p_dropped;
	    if (dropped > 0) {
		printf("kernel: profile dropped %d sample%s\n", dropped,
		       dropped == 1 ? "" : "s");
		buf_entry->p_dropped = 0;
	    }

#endif /* DCI */
	    /* Indicate you've finished the dirty job */
#if DCI
	    {
		int i;
		for(i=0;i<NCPUS;i++)
		    buf_entry->p_full[i] = FALSE;
	    }
#else
	    buf_entry->p_full = FALSE;
#endif /* DCI */
	    if (buf_entry->p_wakeme)
	      thread_wakeup((event_t) &buf_entry->p_wakeme);
	}

    }
    /* The profile thread has been signalled to exit.  Any threads waiting
       for the last buffer of samples to be acknowledged should be woken
       up now.  */
    profile_thread_id = THREAD_NULL;
    while (1) {
	s = splsched();
	mpdequeue_head(&prof_queue, &prof_queue_entry);
	splx(s);
	if ((buf_entry = (buffer_t) prof_queue_entry) == NULLPBUF)
	    break;
	if (buf_entry->p_wakeme)
	    thread_wakeup((event_t) &buf_entry->p_wakeme);
    }
#if 0	/* XXXXX */
    thread_halt_self();
#else
	panic("profile_thread(): halt_self");
#endif	/* XXXXX */
}

/*
 *****************************************************************************
 * send_last_sample is the drain mechanism to allow partial profiled buffers
 * to be sent to the receive_prof thread in the server.
 *****************************************************************************
*/

void
send_last_sample_buf(prof_data_t pbuf)
{
    spl_t    s;
    buffer_t buf_entry;

    if (pbuf == NULLPROFDATA)
	return;

    /* Ask for the sending of the last PC buffer.
     * Make a request to the profile_thread by inserting
     * the buffer in the send queue, and wake it up. 
     * The last buffer must be inserted at the head of the
     * send queue, so the profile_thread handles it immediatly. 
     */ 
    buf_entry = pbuf->prof_area + pbuf->prof_index;
    buf_entry->p_prof = pbuf;

    /* 
       Watch out in case profile thread exits while we are about to
       queue data for it.
     */
    s = splsched();
    if (profile_thread_id == THREAD_NULL)
	splx(s);
    else {
	buf_entry->p_wakeme = 1;
	mpenqueue_tail(&prof_queue, &buf_entry->p_list);
	thread_wakeup((event_t) profile_thread);
	assert_wait((event_t) &buf_entry->p_wakeme, TRUE);
	splx(s); 
	thread_block((void (*)(void)) 0);
    }
}
コード例 #4
0
ファイル: profile.c プロジェクト: Prajna/mach
void profile_thread() 
{
	struct message {
		mach_msg_header_t	head;
		mach_msg_type_t		type;
		int			arg[SIZE_PROF_BUFFER+1];
	} msg;

	register spl_t	s;
	buf_to_send_t	buf_entry;
	queue_entry_t	prof_queue_entry;
	prof_data_t	pbuf;
	simple_lock_t 	lock;
	msg_return_t 	mr;
	int		j;

	/* Initialise the queue header for the prof_queue */
	mpqueue_init(&prof_queue);

	/* Template initialisation of header and type structures */
	msg.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	msg.head.msgh_size = sizeof(msg); 
	msg.head.msgh_local_port = MACH_PORT_NULL;
	msg.head.msgh_kind = MACH_MSGH_KIND_NORMAL;
	msg.head.msgh_id = 666666;
	
	msg.type.msgt_name = MACH_MSG_TYPE_INTEGER_32;
	msg.type.msgt_size = 32;
	msg.type.msgt_number = SIZE_PROF_BUFFER+1;
	msg.type.msgt_inline = TRUE;
	msg.type.msgt_longform = FALSE;
	msg.type.msgt_deallocate = FALSE;
	msg.type.msgt_unused = 0;

	while (TRUE) {

	   /* Dequeue the first buffer. */
	   s = splsched();
	   mpdequeue_head(&prof_queue, &prof_queue_entry);
	   splx(s);

	   if ((buf_entry = (buf_to_send_t) prof_queue_entry) == NULLBTS)
                { 
		thread_sleep((event_t) profile_thread, lock, TRUE);
		if (current_thread()->wait_result != THREAD_AWAKENED)
			break;
                }
	   else {
		task_t		curr_task;
                thread_t	curr_th;
		register int 	*sample;
                int 		curr_buf;
		int 		imax;

                curr_th = (thread_t) buf_entry->thread;
                curr_buf = (int) buf_entry->number; 
		pbuf = curr_th->profil_buffer;

		/* Set the remote port */
		msg.head.msgh_remote_port = (mach_port_t) pbuf->prof_port;

                 
                sample = pbuf->prof_area[curr_buf].p_zone;
	        imax = pbuf->prof_area[curr_buf].p_index;
	        for(j=0 ;j<imax; j++,sample++)
		msg.arg[j] = *sample;	

	        /* Let hardclock() know you've finished the dirty job */
	        pbuf->prof_area[curr_buf].p_full = FALSE;

	        /*
		 * Store the number of samples actually sent 
	         * as the last element of the array.
		 */
	        msg.arg[SIZE_PROF_BUFFER] = imax;

	        mr = mach_msg(&(msg.head), MACH_SEND_MSG, 
			            sizeof(struct message), 0, 
				    MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, 
				    MACH_PORT_NULL);

		if (mr != MACH_MSG_SUCCESS) {
printf("profile_thread: mach_msg failed returned %x\n",(int)mr);
		}

		if (buf_entry->wakeme)
			thread_wakeup((event_t) &buf_entry->wakeme);
		kmem_free(kernel_map, (buf_to_send_t) buf_entry,
					sizeof(struct buf_to_send));

            }

        }
	/* The profile thread has been signalled to exit.  There may still
	   be sample data queued for us, which we must now throw away.
	   Once we set profile_thread_id to null, hardclock() will stop
	   queueing any additional samples, so we do not need to alter
	   the interrupt level.  */
	profile_thread_id = THREAD_NULL;
	while (1) {
		mpdequeue_head(&prof_queue, &prof_queue_entry);
		if ((buf_entry = (buf_to_send_t) prof_queue_entry) == NULLBTS)
			break;
		if (buf_entry->wakeme)
			thread_wakeup((event_t) &buf_entry->wakeme);
		kmem_free(kernel_map, (buf_to_send_t) buf_entry,
					sizeof(struct buf_to_send));
	}

	thread_halt_self();
}