Ejemplo n.º 1
0
int main(void)
{
    pthread_t thread_id_1hz;
    pthread_t thread_id_2hz;

    thread_start(&thread_id_1hz, thread_1hz);
    thread_start(&thread_id_2hz, thread_0_5hz);

    sleep(1);

    thread_stop(&thread_id_1hz);
    thread_stop(&thread_id_2hz);

    exit(0);
}
Ejemplo n.º 2
0
Archivo: poll_ts.c Proyecto: tniuli/xio
int main (int argc, char **argv)
{
	int i, j;
	char *ubuf = 0;
	int afd, sfd, tmp;
	thread_t cli_thread = {};

	BUG_ON ( (afd = xlisten ("tcp+ipc+inproc://127.0.0.1:18897") ) < 0);
	thread_start (&cli_thread, xclient_thread, 0);
	usleep (100000);
	BUG_ON (xselect (XPOLLIN, 1, &afd, 1, &tmp) <= 0);
	for (j = 0; j < 3; j++) {
		BUG_ON ( (sfd = xaccept (afd) ) < 0);
		for (i = 0; i < cnt; i++) {
			while (xselect (XPOLLIN, 1, &sfd, 1, &tmp) <= 0)
				usleep (10000);
			BUG_ON (tmp != sfd);
			BUG_ON (0 != xrecv (sfd, &ubuf) );
			BUG_ON (0 != xsend (sfd, ubuf) );
		}
		xclose (sfd);
	}
	thread_stop (&cli_thread);
	xclose (afd);
	return 0;
}
Ejemplo n.º 3
0
void process_stop(Process* proc) {
    MAGIC_ASSERT(proc);

    /* we only have state if we are running */
    if(process_isRunning(proc)) {
        info("stopping '%s' process", g_quark_to_string(proc->programID));
        program_swapInState(proc->prog, proc->state);

        thread_execute(proc->mainThread, program_getFreeFunc(proc->prog));

        debug("calling atexit for '%s' process", g_quark_to_string(proc->programID));

        while(proc->atExitFunctions && g_queue_get_length(proc->atExitFunctions) > 0) {
            ProcessExitCallbackData* exitCallback = g_queue_pop_head(proc->atExitFunctions);
            if(exitCallback->passArgument) {
                thread_executeExitCallback(proc->mainThread, exitCallback->callback, exitCallback->argument);
            } else {
                thread_execute(proc->mainThread, (PluginNotifyFunc)exitCallback->callback);
            }
            g_free(exitCallback);
        }

        program_swapOutState(proc->prog, proc->state);

        /* free our copy of plug-in resources, and other application state */
        program_freeState(proc->prog, proc->state);
        proc->state = NULL;

        thread_stop(proc->mainThread);
        thread_unref(proc->mainThread);
        proc->mainThread = NULL;
    }
}
Ejemplo n.º 4
0
int zfp_transport_stop(zfp_transport_t *transport)
{
	if (transport == NULL)
		return ZISS_ERROR;

	if (transport->is_sending != ZISS_TRUE)
		return ZISS_ERROR;

	transport->is_to_exit = ZISS_TRUE;
	if (transport->thread != NULL) {
		thread_stop(transport->thread);
		transport->thread = NULL;
	}

	if (transport->file_handle != NULL) {
		fclose((FILE*)transport->file_handle);
		transport->file_handle = NULL;
	}

	if (transport->buf != NULL) {
		free(transport->buf);
		transport->buf = NULL;
	}

	return ZISS_OK;
}
Ejemplo n.º 5
0
/*
 *	Change thread's machine-dependent state.  Called with nothing
 *	locked.  Returns same way.
 */
kern_return_t
thread_set_state(
	register thread_act_t	act,
	int						flavor,
	thread_state_t			state,
	mach_msg_type_number_t	state_count)
{
	kern_return_t		result = KERN_SUCCESS;
	thread_t			thread;

	if (act == THR_ACT_NULL || act == current_act())
		return (KERN_INVALID_ARGUMENT);

	thread = act_lock_thread(act);

	if (!act->active) {
		act_unlock_thread(act);
		return (KERN_TERMINATED);
	}

	thread_hold(act);

	for (;;) {
		thread_t			thread1;

		if (	thread == THREAD_NULL		||
				thread->top_act != act		)
			break;
		act_unlock_thread(act);

		if (!thread_stop(thread)) {
			result = KERN_ABORTED;
			(void)act_lock_thread(act);
			thread = THREAD_NULL;
			break;
		}

		thread1 = act_lock_thread(act);
		if (thread1 == thread)
			break;

		thread_unstop(thread);
		thread = thread1;
	}

	if (result == KERN_SUCCESS)
		result = machine_thread_set_state(act, flavor, state, state_count);

	if (	thread != THREAD_NULL		&&
			thread->top_act == act		)
	    thread_unstop(thread);

	thread_release(act);
	act_unlock_thread(act);

	return (result);
}
void thread_free(thread_t *thread) {
  if (!thread)
    return;

  thread_stop(thread);
  pthread_join(thread->pthread, NULL);
  fixed_queue_free(thread->work_queue, free);
  reactor_free(thread->reactor);
  free(thread);
}
Ejemplo n.º 7
0
void GDNetHost::unbind() {
	if (_host != NULL) {
		thread_stop();
		enet_host_flush(_host);
		enet_host_destroy(_host);
		_host = NULL;
		_message_queue.clear();
		_event_queue.clear();
	}
}
Ejemplo n.º 8
0
kern_return_t
thread_dup(
	register thread_act_t	target)
{
	kern_return_t		result = KERN_SUCCESS;
	thread_act_t		self = current_act();
	thread_t			thread;

	if (target == THR_ACT_NULL || target == self)
		return (KERN_INVALID_ARGUMENT);

	thread = act_lock_thread(target);

	if (!target->active) {
		act_unlock_thread(target);
		return (KERN_TERMINATED);
	}

	thread_hold(target);

	for (;;) {
		thread_t			thread1;

		if (	thread == THREAD_NULL		||
				thread->top_act != target	)
			break;
		act_unlock_thread(target);

		if (!thread_stop(thread)) {
			result = KERN_ABORTED;
			(void)act_lock_thread(target);
			thread = THREAD_NULL;
			break;
		}

		thread1 = act_lock_thread(target);
		if (thread1 == thread)
			break;

		thread_unstop(thread);
		thread = thread1;
	}

	if (result == KERN_SUCCESS)
		result = machine_thread_dup(self, target);

	if (	thread != THREAD_NULL		&&
			thread->top_act == target	)
	    thread_unstop(thread);

	thread_release(target);
	act_unlock_thread(target);

	return (result);
}
Ejemplo n.º 9
0
void thread_free(thread_t *thread) {
  if (!thread)
    return;

  thread_stop(thread);
  thread_join(thread);

  fixed_queue_free(thread->work_queue, osi_free);
  reactor_free(thread->reactor);
  osi_free(thread);
}
Ejemplo n.º 10
0
Archivo: zlog.c Proyecto: rocflyhi/glow
int fini_zlog()
{
    gs_zlog.is_to_exit = TRUE;
    sema_v(gs_zlog.sema);
    thread_stop(gs_zlog.thread);
    sema_delete(gs_zlog.sema);
    mutex_delete(gs_zlog.mutex);
    if (gs_zlog.file_prefix != NULL)
        free(gs_zlog.file_prefix);
    if (gs_zlog.file != NULL)
        fclose(gs_zlog.file);
    return S_OK;
}
Ejemplo n.º 11
0
/*
 * thread_stop_freeze
 *	Block the thread in the kernel and freeze the processor set.
 * return value:
 *	TRUE - the thread has blocked interruptibly, is stopped, and
 *		the processor set assignment is frozen
 *	FALSE - the thread is no longer in the processor set, so it
 *		isn't stopped, and the processor set assignment
 *		is released.
 */
int
thread_stop_freeze( thread_t thread, processor_set_t pset )
{
	thread_act_t	thr_act;
	spl_t	s;

	/*
	 * hold it, and wait for it to stop.
	 */
	thr_act = thread_lock_act(thread);
	thread_hold(thr_act);
	act_unlock_thread(thr_act);

	thread_stop(thread);

	s = splsched();
	wake_lock(thread);
        while( thread->state & (TH_RUN|TH_UNINT) ) {
                thread->wake_active = TRUE;
                assert_wait((event_t)&thread->wake_active, FALSE);
                wake_unlock(thread);
                splx(s);
                thread_block( (void (*)(void)) 0 );
                (void) splsched();
                wake_lock(thread);
        }

	/*
	 * Now, the thread has blocked uninterruptibly; freeze the 
	 * assignment and make sure it's still part of the processor set.
	 */
	wake_unlock(thread);
	thread_freeze(thread);
	thread_lock(thread);

	/*
	 * if the processor set has changed, release the freeze and
	 * then unstop it.
	 */
	if( thread->processor_set != pset ) {
		thread_unlock(thread);
		splx(s);
		thread_unfreeze(thread);
		thread_unstop(thread);
		return FALSE;
	}
	thread_unlock(thread);
	splx(s);
	return TRUE;
}
Ejemplo n.º 12
0
void btif_sock_cleanup(void) {
  if (thread_handle == -1)
    return;

  thread_stop(thread);
  thread_join(thread);
  btsock_thread_exit(thread_handle);
  btsock_rfc_cleanup();
  btsock_sco_cleanup();
  btsock_l2cap_cleanup();
  thread_free(thread);
  thread_handle = -1;
  thread = NULL;
}
Ejemplo n.º 13
0
kern_return_t
thread_get_state(
	register thread_t		thread,
	int						flavor,
	thread_state_t			state,			/* pointer to OUT array */
	mach_msg_type_number_t	*state_count)	/*IN/OUT*/
{
	kern_return_t		result = KERN_SUCCESS;

	if (thread == THREAD_NULL)
		return (KERN_INVALID_ARGUMENT);

	thread_mtx_lock(thread);

	if (thread->active) {
		if (thread != current_thread()) {
			thread_hold(thread);

			thread_mtx_unlock(thread);

			if (thread_stop(thread, FALSE)) {
				thread_mtx_lock(thread);
				result = machine_thread_get_state(
										thread, flavor, state, state_count);
				thread_unstop(thread);
			}
			else {
				thread_mtx_lock(thread);
				result = KERN_ABORTED;
			}

			thread_release(thread);
		}
		else
			result = machine_thread_get_state(
									thread, flavor, state, state_count);
	}
	else if (thread->inspection)
	{
		result = machine_thread_get_state(
									thread, flavor, state, state_count);
	}
	else
		result = KERN_TERMINATED;

	thread_mtx_unlock(thread);

	return (result);
}
Ejemplo n.º 14
0
static void post_result_to_callback(void *context) {
  assert(context);

  callbacked_wrapper_t *wrapper = context;

  // Save the values we need for callback
  void *result = wrapper->success ? FUTURE_SUCCESS : FUTURE_FAIL;
  thread_fn callback = wrapper->callback;

  // Clean up the resources we used
  thread_stop(wrapper->lifecycle_thread);
  osi_free(wrapper);

  callback(result);
}
Ejemplo n.º 15
0
/*
 *	Change thread's machine-dependent state.  Called with nothing
 *	locked.  Returns same way.
 */
static kern_return_t
thread_set_state_internal(
	register thread_t		thread,
	int						flavor,
	thread_state_t			state,
	mach_msg_type_number_t	state_count,
	boolean_t				from_user)
{
	kern_return_t		result = KERN_SUCCESS;

	if (thread == THREAD_NULL)
		return (KERN_INVALID_ARGUMENT);

	thread_mtx_lock(thread);

	if (thread->active) {
		if (thread != current_thread()) {
			thread_hold(thread);

			thread_mtx_unlock(thread);

			if (thread_stop(thread, TRUE)) {
				thread_mtx_lock(thread);
				result = machine_thread_set_state(
										thread, flavor, state, state_count);
				thread_unstop(thread);
			}
			else {
				thread_mtx_lock(thread);
				result = KERN_ABORTED;
			}

			thread_release(thread);
		}
		else
			result = machine_thread_set_state(
									thread, flavor, state, state_count);
	}
	else
		result = KERN_TERMINATED;

	if ((result == KERN_SUCCESS) && from_user)
		extmod_statistics_incr_thread_set_state(thread);

	thread_mtx_unlock(thread);

	return (result);
}
Ejemplo n.º 16
0
void check_inx_append_mthread_test(inx_t *inx) {

	bool_t *outcome;

	if (!thread_start() || !(outcome = mm_alloc(sizeof(bool_t)))) {
		log_error("Unable to setup the thread context.");
		pthread_exit(NULL);
		return;
	}

	*outcome = check_inx_append_helper(inx);

	thread_stop();
	pthread_exit(outcome);
	return;
}
Ejemplo n.º 17
0
Archivo: main.c Proyecto: Jhuster/clib
int main(int argc, char const *argv[])
{
    echo_t echo;
    echo.num = 0;

    echo.thread = thread_create();
    thread_start(echo.thread, echo_loop,&echo);

    getchar();
    getchar();

    thread_stop(echo.thread, NULL);
    thread_destroy(echo.thread);

    return 0;
}
Ejemplo n.º 18
0
void check_rand_mthread_wrap(void) {

	stringer_t *result = NULL;

	if (!thread_start()) {
		log_error("Unable to setup the thread context.");
		pthread_exit(st_dupe(NULLER("Thread startup error.")));
		return;
	}

	result = check_rand_sthread();

	thread_stop();
	pthread_exit(result);
	return;
}
Ejemplo n.º 19
0
void check_tokyo_tank_mthread_cnv(check_tank_opt_t *opts) {

	bool_t *result;

	if (!thread_start() || !(result = mm_alloc(sizeof(bool_t)))) {
		log_error("Unable to setup the thread context.");
		pthread_exit(NULL);
		return;
	}

	*result = check_tokyo_tank(opts);

	thread_stop();
	pthread_exit(result);
	return;
}
Ejemplo n.º 20
0
kern_return_t
thread_dup2(
	thread_t	source,
	thread_t	target)
{
	kern_return_t		result = KERN_SUCCESS;
	uint32_t		active = 0;

	if (source == THREAD_NULL || target == THREAD_NULL || target == source)
		return (KERN_INVALID_ARGUMENT);

	thread_mtx_lock(source);
	active = source->active;
	thread_mtx_unlock(source);

	if (!active) {
		return KERN_TERMINATED;
	}

	thread_mtx_lock(target);

	if (target->active || target->inspection) {
		thread_hold(target);

		thread_mtx_unlock(target);

		if (thread_stop(target, TRUE)) {
			thread_mtx_lock(target);
			result = machine_thread_dup(source, target);
			if (source->affinity_set != AFFINITY_SET_NULL)
				thread_affinity_dup(source, target);
			thread_unstop(target);
		}
		else {
			thread_mtx_lock(target);
			result = KERN_ABORTED;
		}

		thread_release(target);
	}
	else
		result = KERN_TERMINATED;

	thread_mtx_unlock(target);

	return (result);
}
Ejemplo n.º 21
0
int main(int _argc, char** _argv) {
    int i;
    thread_t childs[1];

    argc = _argc;
    argv = _argv;

    for (i = 0; i < NELEM(childs); i++) {
        thread_start(&childs[i], task_main, 0);
    }

    for (i = 0; i < NELEM(childs); i++) {
        thread_stop(&childs[i]);
    }

    return 0;
}
Ejemplo n.º 22
0
static future_t *shut_down() {
  LOG_INFO(LOG_TAG, "%s", __func__);

  hci_inject->close();

  if (thread) {
    if (firmware_is_configured) {
      non_repeating_timer_restart(epilog_timer);
      thread_post(thread, event_epilog, NULL);
    } else {
      thread_stop(thread);
    }

    thread_join(thread);
  }

  fixed_queue_free(command_queue, buffer_allocator->free);
  fixed_queue_free(packet_queue, buffer_allocator->free);
  list_free(commands_pending_response);

  pthread_mutex_destroy(&commands_pending_response_lock);

  packet_fragmenter->cleanup();

  non_repeating_timer_free(epilog_timer);
  non_repeating_timer_free(command_response_timer);
  non_repeating_timer_free(startup_timer);

  epilog_timer = NULL;
  command_response_timer = NULL;

  low_power_manager->cleanup();
  hal->close();

  // Turn off the chip
  int power_state = BT_VND_PWR_OFF;
  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
  vendor->close();

  thread_free(thread);
  thread = NULL;
  firmware_is_configured = false;

  return NULL;
}
Ejemplo n.º 23
0
int session_mgr_stop(session_mgr_t *mgr)
{
	if (mgr == NULL) {
		LOG_ERROR("Invalid session mgr");
		return ZISS_ERROR;
	}

	if (mgr->thread != NULL) {
		cond_signal(mgr->exit_cond);
		thread_stop(mgr->thread);
		thread_delete(mgr->thread);
		cond_delete(mgr->exit_cond);
		mgr->thread = NULL;
		mgr->exit_cond = NULL;
	}
	session_mgr_clear(mgr);

	return ZISS_OK;
}
Ejemplo n.º 24
0
int zsp_listener_stop(zsp_listener_t *listener)
{
	if (listener == NULL)
		return SSS_ERROR;

	if (listener->sock != NULL)
	{
		socket_shutdown(listener->sock);
		socket_delete(listener->sock);
		listener->sock = NULL;
	}
	if (listener->thread != NULL)
	{
		thread_stop(listener->thread);
		thread_delete(listener->thread);
		listener->thread = NULL;
	}
	listener->port = 0;

	return SSS_OK;
}
Ejemplo n.º 25
0
/*
 *	Change thread's machine-dependent userspace TSD base.
 *  Called with nothing locked.  Returns same way.
 */
kern_return_t
thread_set_tsd_base(
	thread_t			thread,
	mach_vm_offset_t	tsd_base)
{
	kern_return_t		result = KERN_SUCCESS;

	if (thread == THREAD_NULL)
		return (KERN_INVALID_ARGUMENT);

	thread_mtx_lock(thread);

	if (thread->active) {
		if (thread != current_thread()) {
			thread_hold(thread);

			thread_mtx_unlock(thread);

			if (thread_stop(thread, TRUE)) {
				thread_mtx_lock(thread);
				result = machine_thread_set_tsd_base(thread, tsd_base);
				thread_unstop(thread);
			}
			else {
				thread_mtx_lock(thread);
				result = KERN_ABORTED;
			}

			thread_release(thread);
		}
		else
			result = machine_thread_set_tsd_base(thread, tsd_base);
	}
	else
		result = KERN_TERMINATED;

	thread_mtx_unlock(thread);

	return (result);
}
Ejemplo n.º 26
0
kern_return_t
thread_dup(
	register thread_t	target)
{
	thread_t			self = current_thread();
	kern_return_t		result = KERN_SUCCESS;

	if (target == THREAD_NULL || target == self)
		return (KERN_INVALID_ARGUMENT);

	thread_mtx_lock(target);

	if (target->active) {
		thread_hold(target);

		thread_mtx_unlock(target);

		if (thread_stop(target, TRUE)) {
			thread_mtx_lock(target);
			result = machine_thread_dup(self, target);
			if (self->affinity_set != AFFINITY_SET_NULL)
				thread_affinity_dup(self, target);
			thread_unstop(target);
		}
		else {
			thread_mtx_lock(target);
			result = KERN_ABORTED;
		}

		thread_release(target);
	}
	else
		result = KERN_TERMINATED;

	thread_mtx_unlock(target);

	return (result);
}
Ejemplo n.º 27
0
/*
 * Internal routine to terminate a thread.
 * Sometimes called with task already locked.
 */
kern_return_t
thread_terminate_internal(
	register thread_act_t	act)
{
	kern_return_t	result;
	thread_t		thread;

	thread = act_lock_thread(act);

	if (!act->active) {
		act_unlock_thread(act);
		return (KERN_TERMINATED);
	}

	act_disable(act);
	result = act_abort(act, FALSE);

	/* 
	 * Make sure this thread enters the kernel
	 * Must unlock the act, but leave the shuttle
	 * captured in this act.
	 */
	if (thread != current_thread()) {
		act_unlock(act);

		if (thread_stop(thread))
			thread_unstop(thread);
		else
			result = KERN_ABORTED;

		act_lock(act);
	}

	clear_wait(thread, act->started? THREAD_INTERRUPTED: THREAD_AWAKENED);
	act_unlock_thread(act);

	return (result);
}
Ejemplo n.º 28
0
Archivo: authsrv.c Proyecto: regit/nufw
/**
 * Ask all threads to stop (by locking their mutex), and then wait
 * until they really stop (if wait is TRUE) using g_thread_join()
 * and g_thread_pool_free().
 *
 * \param wait If wait is TRUE, the function will block until all threads
 *             stopped. Else, it will just ask all threads to stop.
 */
void stop_threads(gboolean wait)
{
	log_message(INFO, DEBUG_AREA_MAIN, "Asking threads to stop.");

#ifdef BUILD_NUAUTH_COMMAND
	/* stop command server */
	if (nuauthconf->use_command_server) {
		thread_stop(&nuauthdatas->command_thread);
	}
#endif

	/* ask theads to stop */
	if (nuauthconf->push && nuauthconf->hello_authentication) {
		thread_stop(&nuauthdatas->localid_auth_thread);
	}

	/* wait thread end */
	if (wait) {
		log_message(INFO, DEBUG_AREA_MAIN, "Waiting for threads end ...");
	}

	/* kill push worker */
	thread_stop(&nuauthdatas->tls_pusher);
	if (wait) {
		log_message(DEBUG, DEBUG_AREA_MAIN, "Waiting for thread 'tls pusher'");
		g_thread_join(nuauthdatas->tls_pusher.thread);
	}

	/* kill entries point */
	thread_list_stop_user_ev(nuauthdatas->tls_auth_servers);
	thread_list_stop_nufw_ev(nuauthdatas->tls_nufw_servers);
	thread_stop(&nuauthdatas->pre_client_thread);
	if (wait) {
		thread_list_wait_end(nuauthdatas->tls_auth_servers);
		thread_list_wait_end(nuauthdatas->tls_nufw_servers);
		thread_wait_end(&nuauthdatas->pre_client_thread);
	}

	/* Close nufw and client connections */
	log_message(INFO, DEBUG_AREA_MAIN, "Closing nufw connections");
	close_nufw_servers();

	log_message(INFO, DEBUG_AREA_MAIN, "Closing client connections");
	close_clients();

	thread_stop(&nuauthdatas->limited_connections_handler);
	thread_stop(&nuauthdatas->search_and_fill_worker);
	if (wait) {
		thread_wait_end(&nuauthdatas->limited_connections_handler);
		thread_wait_end(&nuauthdatas->search_and_fill_worker);
	}

#ifdef BUILD_NUAUTH_COMMAND
	if (nuauthconf->use_command_server) {
		thread_wait_end(&nuauthdatas->command_thread);
	}
#endif
	if (nuauthconf->push && nuauthconf->hello_authentication && wait) {
		thread_wait_end(&nuauthdatas->localid_auth_thread);
	}

	stop_all_thread_pools(wait);
	/* done! */
	log_message(INFO, DEBUG_AREA_MAIN, "Threads stopped.");
}
Ejemplo n.º 29
0
static void epilog_timer_expired(UNUSED_ATTR void *context) {
  LOG_INFO(LOG_TAG, "%s", __func__);
  thread_stop(thread);
}
Ejemplo n.º 30
0
Archivo: ipc.c Proyecto: zrho/Carbon
void syscall_ipc_respond(cpu_int_state_t *state) {
	// Check thread role
	if (THREAD_ROLE_IPC_RECEIVER != thread_current->role)
		SYSCALL_RETURN_ERROR(1);

	// Extract arguments
	uint16_t flags = (uint16_t) state->state.rbx;
	uint32_t length = (uint32_t) state->state.rcx;

	// Check length
	if (length > thread_current->ipc_buffer_sz[IPC_BUFFER_SEND])
		SYSCALL_RETURN_ERROR(2);

	// Extract info from role ctx
	ipc_role_ctx_t *role_ctx = (ipc_role_ctx_t *) thread_current->role_ctx;
	uint32_t sender_pid = role_ctx->sender_process;
	uint32_t sender_tid = role_ctx->sender_thread;

	// Sender process still exists?
	process_t *sender_process = process_get(sender_pid);

	if (0 == sender_process) {
		thread_stop(process_current, thread_current);
		thread_switch(scheduler_next(), state);
		return;
	}

	// Sender thread still exists?
	thread_t *sender_thread = thread_get(sender_process, sender_tid);

	if (0 == sender_thread) {
		thread_stop(process_current, thread_current);
		thread_switch(scheduler_next(), state);
		return;
	}

	// Response ignored?
	if (0 != (role_ctx->flags & IPC_FLAG_IGNORE_RESPONSE)) {
		thread_stop(process_current, thread_current);
		thread_switch(sender_thread, state);
		return;
	}

	// Move buffer to sender thread (if length > 0)
	if (length > 0)
		ipc_buffer_move(
				thread_current,
				IPC_BUFFER_SEND,
				sender_thread,
				IPC_BUFFER_RECV,
				sender_process);

	// Write header to registers
	ipc_message_header(
			IPC_BUFFER_RECV,
			length,
			flags,
			process_current->pid,
			sender_thread->tid,
			&sender_thread->state);

	// Thaw thread
	thread_thaw(sender_thread, 0);

	// Stop current thread and switch to sender
	thread_stop(process_current, thread_current);
	thread_switch(sender_thread, state);
}