Пример #1
0
int s_qmidms_meid_resp(void *buf,  u16 size, char *meid, int meidsize)
{
	int result;

	u8 offset = sizeof(struct qmux) + 3;

	if (!buf || size < offset || meidsize < 14)
		return -ENOMEM;

	buf = buf + offset;
	size -= offset;

	result = s_qmi_msgid(buf, size);
	if (result != 0x25)
		return -EFAULT;

	result = s_qmi_msgisvalid(buf, size);
	if (result)
		return -EFAULT;

	result = tlv_get(buf, size, 0x12, meid, 14);
	if (result != 14)
		return -EFAULT;

	return 0;
}
Пример #2
0
int qmiwds_event_resp(void *buf, u16 size, struct qmiwds_stats *stats)
{
	int result;
	u8 status[2];

	u8 offset = sizeof(struct qmux) + 3;

	if (!buf || size < offset || !stats)
		return -ENOMEM;

	buf = buf + offset;
	size -= offset;

	result = qmi_msgid(buf, size);
	if (result == 0x22) {
		result = tlv_get(buf, size, 0x01, &status[0], 2);
		if (result >= 1)
			stats->linkstate = status[0] == 0x02;
		if (result == 2)
			stats->reconfigure = status[1] == 0x01;

		if (result < 0)
			return result;
	} else {
		return -EFAULT;
	}

	return 0;
}
Пример #3
0
static void
control_destroy(struct sml_control *control)
{
	assert(tlv_get(current_control) == control);

#ifndef WITHOUT_MULTITHREAD
	/* To release the thread local heap exclusively, it must be
	 * occupied by the current thread. */
	assert(IS_ACTIVE(load_relaxed(&control->state)));
#endif /* !WITHOUT_MULTITHREAD */

	if (control->thread_local_heap) {
		sml_heap_mutator_destroy(control->thread_local_heap);
		control->thread_local_heap = NULL;
	}

	/* Pointers in the stack is safely ignored since the thread has
	 * been terminated. */
	control->frame_stack = NULL;

	control_leave(control);

	control_unregister(control);
	tlv_set(current_control, NULL);

	mutex_destroy(&control->inactive_wait_lock);
	cond_destroy(&control->inactive_wait_cond);
	free(control);
}
Пример #4
0
int s_qmictl_alloccid_resp(void *buf, u16 size, u16 *cid)
{
	int result;
	u8 offset = sizeof(struct qmux) + 2;

	if (!buf || size < offset)
		return -ENOMEM;

	buf = buf + offset;
	size -= offset;

	result = s_qmi_msgid(buf, size);
	if (result != 0x22)
		return -EFAULT;

	result = s_qmi_msgisvalid(buf, size);
	if (result != 0)
		return -EFAULT;

	result = tlv_get(buf, size, 0x01, cid, 2);
	if (result != 2)
		return -EFAULT;

	return 0;
}
Пример #5
0
void
sml_enter_internal(void *old_frame_top)
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	control->frame_stack->top = old_frame_top;
}
Пример #6
0
void *
sml_save_exn_internal(void *obj)
{
	struct sml_control *control = tlv_get(current_control);
	void *old = control->exn_object;
	control->exn_object = obj;
	return old;
}
Пример #7
0
SML_PRIMITIVE void
sml_enter()
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	assert(control->frame_stack->top == CALLER_FRAME_END_ADDRESS());
	control->frame_stack->top = NULL;
}
Пример #8
0
SML_PRIMITIVE void
sml_unsave()
{
	struct sml_control *control = tlv_get(current_control);
#ifndef WITHOUT_MULTITHREAD
	assert(IS_ACTIVE(load_relaxed(&control->state)));
#endif /* !WITHOUT_MULTITHREAD */
	assert(control->frame_stack->top == CALLER_FRAME_END_ADDRESS());
	control->frame_stack->top = NULL;
}
Пример #9
0
enum sml_sync_phase
sml_current_phase()
{
	struct sml_control *control = tlv_get(current_control);
	/* Thanks to memory coherency, control->state always indicates
	 * the current status of this mutator regardless of the fact that
	 * both the mutator and collector updates it.
	 * If control->state is SYNC1, then the thread is in SYNC1.
	 */
	return PHASE(load_relaxed(&control->state));
}
Пример #10
0
int s_qmi_msgisvalid(void *msg, u16 size)
{
	char tlv[4];

	if (tlv_get(msg, size, 2, &tlv[0], 4) == 4) {
		if (*(u16 *)&tlv[0] != 0)
			return *(u16 *)&tlv[2];
		else
			return 0;
	}
	return -ENOMSG;
}
Пример #11
0
void *
sml_leave_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	old_frame_top = control->frame_stack->top;
	if (!old_frame_top)
		control->frame_stack->top = frame_pointer;
	control_leave(control);
	return old_frame_top;
}
Пример #12
0
int s_qmiwds_event_resp(void *buf, u16 size, struct qmiwds_stats *stats)
{
	int result;
	u8 status[2];

	u8 offset = sizeof(struct qmux) + 3;

	if (!buf || size < offset || !stats)
		return -ENOMEM;

	buf = buf + offset;
	size -= offset;

	result = s_qmi_msgid(buf, size);
	if (result == 0x01) {
		tlv_get(buf, size, 0x10, &stats->txok, 4);
		tlv_get(buf, size, 0x11, &stats->rxok, 4);
		tlv_get(buf, size, 0x12, &stats->txerr, 4);
		tlv_get(buf, size, 0x13, &stats->rxerr, 4);
		tlv_get(buf, size, 0x14, &stats->txofl, 4);
		tlv_get(buf, size, 0x15, &stats->rxofl, 4);
		tlv_get(buf, size, 0x19, &stats->txbytesok, 8);
		tlv_get(buf, size, 0x1A, &stats->rxbytesok, 8);
	} else if (result == 0x22) {
		result = tlv_get(buf, size, 0x01, &status[0], 2);
		if (result >= 1)
			stats->linkstate = status[0] == 0x02;
		if (result == 2)
			stats->reconfigure = status[1] == 0x01;

		if (result < 0)
			return result;
	} else {
		return -EFAULT;
	}

	return 0;
}
Пример #13
0
SML_PRIMITIVE void
sml_end()
{
	struct sml_control *control = tlv_get(current_control);

#ifndef WITHOUT_MULTITHREAD
	assert(IS_ACTIVE(load_relaxed(&control->state)));
#endif /* !WITHOUT_MULTITHREAD */
	assert(control->frame_stack->bottom == CALLER_FRAME_END_ADDRESS());

	control->frame_stack = control->frame_stack->next;

	if (control->frame_stack) {
		control_leave(control);
	} else {
		control_destroy(control);
	}
}
Пример #14
0
void
sml_check_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	assert(load_relaxed(&control->state) == ACTIVE(ASYNC));
	if (load_relaxed(&stop_the_world_flag)) {
		old_frame_top = control->frame_stack->top;
		if (!old_frame_top)
			control->frame_stack->top = frame_pointer;
		store_release(&control->state, INACTIVE(SYNC1));
		mutex_lock(&control->inactive_wait_lock);
		cond_signal(&control->inactive_wait_cond);
		mutex_unlock(&control->inactive_wait_lock);
		control_enter(control);
		control->frame_stack->top = old_frame_top;
	}
}
Пример #15
0
	/* lock; all updates so far must be acquired */
	old = INACTIVE(ASYNC);
	if (cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC)))
		return;

	mutex_lock(&control->inactive_wait_lock);
	pthread_cleanup_push(cleanup_mutex_unlock,
			     &control->inactive_wait_lock);
	old = INACTIVE(ASYNC);
	while (!cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC))) {
		cond_wait(&control->inactive_wait_cond,
			  &control->inactive_wait_lock);
		old = INACTIVE(ASYNC);
	}
	pthread_cleanup_pop(1);
}

#else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */
static void
control_enter(struct sml_control *control)
{
	activate(control);
}

#endif /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */

SML_PRIMITIVE void
sml_leave()
{
	struct sml_control *control = tlv_get(current_control);
	assert(control->frame_stack->top == NULL);
	control->frame_stack->top = CALLER_FRAME_END_ADDRESS();
	control_leave(control);
}

SML_PRIMITIVE void
sml_enter()
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	assert(control->frame_stack->top == CALLER_FRAME_END_ADDRESS());
	control->frame_stack->top = NULL;
}

void *
sml_leave_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	old_frame_top = control->frame_stack->top;
	if (!old_frame_top)
		control->frame_stack->top = frame_pointer;
	control_leave(control);
	return old_frame_top;
}

void
sml_enter_internal(void *old_frame_top)
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	control->frame_stack->top = old_frame_top;
}

#if defined WITHOUT_MULTITHREAD
void
sml_check_internal(void *frame_pointer ATTR_UNUSED)
{
}

#elif defined WITHOUT_CONCURRENCY
void
sml_check_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	assert(load_relaxed(&control->state) == ACTIVE(ASYNC));
	if (load_relaxed(&stop_the_world_flag)) {
		old_frame_top = control->frame_stack->top;
		if (!old_frame_top)
			control->frame_stack->top = frame_pointer;
		store_release(&control->state, INACTIVE(SYNC1));
		mutex_lock(&control->inactive_wait_lock);
		cond_signal(&control->inactive_wait_cond);
		mutex_unlock(&control->inactive_wait_lock);
		control_enter(control);
		control->frame_stack->top = old_frame_top;
	}
}

#else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */
void
sml_check_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	unsigned int state = load_relaxed(&control->state);
	void *old_frame_top;

	assert(IS_ACTIVE(state));

	if (state == ACTIVE(PRESYNC1)) {
		store_relaxed(&control->state, ACTIVE(SYNC1));
		sync1_action();
	} else if (state == ACTIVE(PRESYNC2)) {
		store_relaxed(&control->state, ACTIVE(SYNC2));
		old_frame_top = control->frame_stack->top;
		if (!old_frame_top)
			control->frame_stack->top = frame_pointer;
		sync2_action(control);
		control->frame_stack->top = old_frame_top;
	}
}
Пример #16
0
/* for debug */
int
sml_saved()
{
	struct sml_control *control = tlv_get(current_control);
	return control->frame_stack->top != NULL;
}
Пример #17
0
SML_PRIMITIVE void
sml_check()
{
	assert(tlv_get(current_control)->frame_stack->top == NULL);
	sml_check_internal(CALLER_FRAME_END_ADDRESS());
}