Example #1
0
File: vmm.c Project: RnbWd/hyperkit
void
vm_signal_pause(struct vm *vm, bool pause) {
	pthread_mutex_lock(&vm->hv_pause_mtx); // Lock as we are modifying hv_is_paused
	if (pause) {
		if (atomic_cmpset_rel_int(&vm->hv_is_paused, FALSE, TRUE) == 0) { // All vcpus should wait after next interrupt
			fprintf(stderr, "freeze signal received, but we are already frozen\n");
		}
	} else {
		if (atomic_cmpset_rel_int(&vm->hv_is_paused, TRUE, FALSE) == 0) {
			fprintf(stderr, "thaw signal received, but we are not frozen\n");
		} else {
			pthread_cond_broadcast(&vm->hv_pause_cnd); // wake paused threads
		}
	}
	pthread_mutex_unlock(&vm->hv_pause_mtx);
}
Example #2
0
int
_pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
{
	struct pthread *curthread;
	int state;

	_thr_check_init();

	for (;;) {
		state = once_control->state;
		if (state == ONCE_DONE)
			return (0);
		if (state == ONCE_NEVER_DONE) {
			if (atomic_cmpset_acq_int(&once_control->state, state, ONCE_IN_PROGRESS))
				break;
		} else if (state == ONCE_IN_PROGRESS) {
			if (atomic_cmpset_acq_int(&once_control->state, state, ONCE_WAIT))
				_thr_umtx_wait_uint(&once_control->state, ONCE_WAIT, NULL, 0);
		} else if (state == ONCE_WAIT) {
			_thr_umtx_wait_uint(&once_control->state, state, NULL, 0);
		} else
			return (EINVAL);
        }

	curthread = _get_curthread();
	THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control);
	init_routine();
	THR_CLEANUP_POP(curthread, 0);
	if (atomic_cmpset_rel_int(&once_control->state, ONCE_IN_PROGRESS, ONCE_DONE))
		return (0);
	atomic_store_rel_int(&once_control->state, ONCE_DONE);
	_thr_umtx_wake(&once_control->state, INT_MAX, 0);
	return (0);
}
Example #3
0
static void
once_cancel_handler(void *arg)
{
	pthread_once_t *once_control = arg;

	if (atomic_cmpset_rel_int(&once_control->state, ONCE_IN_PROGRESS, ONCE_NEVER_DONE))
		return;
	atomic_store_rel_int(&once_control->state, ONCE_NEVER_DONE);
	_thr_umtx_wake(&once_control->state, INT_MAX, 0);
}
/*
 * Append a character to a message buffer.  This function can be
 * considered fully reentrant so long as the number of concurrent
 * callers is less than the number of characters in the buffer.
 * However, the message buffer is only guaranteed to be consistent
 * for reading when there are no callers in this function.
 */
void
msgbuf_addchar(struct msgbuf *mbp, int c)
{
	u_int new_seq, pos, seq;

	do {
		seq = mbp->msg_wseq;
		new_seq = MSGBUF_SEQNORM(mbp, seq + 1);
	} while (atomic_cmpset_rel_int(&mbp->msg_wseq, seq, new_seq) == 0);
	pos = MSGBUF_SEQ_TO_POS(mbp, seq);
	atomic_add_int(&mbp->msg_cksum, (u_int)(u_char)c -
	    (u_int)(u_char)mbp->msg_ptr[pos]);
	mbp->msg_ptr[pos] = c;
}
Example #5
0
void
ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
    u_long arg1, u_long arg2, u_long arg3, u_long arg4, u_long arg5,
    u_long arg6)
{
	struct ktr_entry *entry;
#ifdef KTR_ALQ
	struct ale *ale = NULL;
#endif
	int newindex, saveindex;
#if defined(KTR_VERBOSE) || defined(KTR_ALQ)
	struct thread *td;
#endif
	int cpu;

	if (panicstr)
		return;
	if ((ktr_mask & mask) == 0)
		return;
	cpu = KTR_CPU;
	if (((1 << cpu) & ktr_cpumask) == 0)
		return;
#if defined(KTR_VERBOSE) || defined(KTR_ALQ)
	td = curthread;
	if (td->td_pflags & TDP_INKTR)
		return;
	td->td_pflags |= TDP_INKTR;
#endif
#ifdef KTR_ALQ
	if (ktr_alq_enabled) {
		if (td->td_critnest == 0 &&
		    (td->td_flags & TDF_IDLETD) == 0 &&
		    td != ald_thread) {
			if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max)
				goto done;
			if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) {
				ktr_alq_failed++;
				goto done;
			}
			ktr_alq_cnt++;
			entry = (struct ktr_entry *)ale->ae_data;
		} else {
			goto done;
		}
	} else
#endif
	{
		do {
			saveindex = ktr_idx;
			newindex = (saveindex + 1) & (KTR_ENTRIES - 1);
		} while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0);
		entry = &ktr_buf[saveindex];
	}
	entry->ktr_timestamp = KTR_TIME;
	entry->ktr_cpu = cpu;
	entry->ktr_thread = curthread;
	if (file != NULL)
		while (strncmp(file, "../", 3) == 0)
			file += 3;
	entry->ktr_file = file;
	entry->ktr_line = line;
#ifdef KTR_VERBOSE
	if (ktr_verbose) {
#ifdef SMP
		printf("cpu%d ", cpu);
#endif
		if (ktr_verbose > 1) {
			printf("%s.%d\t", entry->ktr_file,
			    entry->ktr_line);
		}
		printf(format, arg1, arg2, arg3, arg4, arg5, arg6);
		printf("\n");
	}
#endif
	entry->ktr_desc = format;
	entry->ktr_parms[0] = arg1;
	entry->ktr_parms[1] = arg2;
	entry->ktr_parms[2] = arg3;
	entry->ktr_parms[3] = arg4;
	entry->ktr_parms[4] = arg5;
	entry->ktr_parms[5] = arg6;
#ifdef KTR_ALQ
	if (ktr_alq_enabled && ale)
		alq_post(ktr_alq, ale);
done:
#endif
#if defined(KTR_VERBOSE) || defined(KTR_ALQ)
	td->td_pflags &= ~TDP_INKTR;
#endif
}