コード例 #1
0
ファイル: ao_wasapi.c プロジェクト: ThreeGe/mpv
static void uninit(struct ao *ao)
{
    MP_DBG(ao, "Uninit wasapi\n");
    struct wasapi_state *state = ao->priv;
    wasapi_release_proxies(state);
    if (state->hWake)
        set_thread_state(ao, WASAPI_THREAD_SHUTDOWN);

    // wait up to 10 seconds
    if (state->hAudioThread &&
        WaitForSingleObject(state->hAudioThread, 10000) == WAIT_TIMEOUT)
    {
        MP_ERR(ao, "Audio loop thread refuses to abort\n");
        return;
    }

    SAFE_RELEASE(state->hInitDone,   CloseHandle(state->hInitDone));
    SAFE_RELEASE(state->hWake,       CloseHandle(state->hWake));
    SAFE_RELEASE(state->hAudioThread,CloseHandle(state->hAudioThread));

    wasapi_change_uninit(ao);

    talloc_free(state->deviceID);

    CoUninitialize();
    MP_DBG(ao, "Uninit wasapi done\n");
}
コード例 #2
0
ファイル: sem.c プロジェクト: AdamRLukaitis/spoon
int signal_local_semaphore( struct thread* tr, int sem_id )
{
	struct sem_link *sl;
	struct thread *target;
	struct process *proc;

	proc = tr->process;
	
	acquire_spinlock( & (proc->sems_lock) );
		
		if ( proc->sems[ sem_id ].sem_id != sem_id ) 
		{
			release_spinlock( & (proc->sems_lock) );
			return -1;
		}
		
		proc->sems[ sem_id ].count -= 1;
			
			// wake up any waiting threads
			sl = proc->sems[ sem_id ].waiting_list;	
			if ( sl != NULL )
			{
				target = find_thread_with_id( tr->process, sl->tid );
				if ( target != NULL )
						set_thread_state( target, THREAD_RUNNING );

				proc->sems[ sem_id ].waiting_list = sl->next;
				free( sl );
			}

	release_spinlock( & ( proc->sems_lock ) );
	return 0;
}
コード例 #3
0
/**
 * online_first_dead_cpu
 * @brief Find the first cpu with attributes online and physical_id both
 *        set to 0 and online it.
 *
 * @param nthreads
 * @returns 0 on success, !0 otherwise
 */
int
online_first_dead_cpu(int nthreads, struct dr_info *dr_info)
{
	struct thread *thread;
	int rc = 1;

	for (thread = dr_info->all_threads; thread; thread = thread->next) {
		if (OFFLINE == get_thread_state(thread)
		    && ((thread->phys_id == 0xffffffff)
			|| (thread->phys_id == 0))) {
			    
			/* just assume that there will be nthreads to online. */
			while (nthreads--) {
				set_thread_state(thread, ONLINE);
				thread = thread->next;
			}

			rc = 0;
			break;
		}
	}

	if (rc)
		say(ERROR, "Could not find any threads to online\n");

	return rc;
}
コード例 #4
0
/**
 * online cpu
 *
 * @param cpu
 * @param dr_info
 * @returns 0 on success, !0 otherwise
 */
int
online_cpu(struct dr_node *cpu, struct dr_info *dr_info) 
{
	int rc = 0;
	struct thread *thread = NULL;
	int found = 0;

	say(DEBUG, "Onlining cpu %s (%d threads)\n", cpu->name,
	    cpu->cpu_nthreads);

	/* Hack to work around kernel brain damage (LTC 7692) */
	for (thread = dr_info->all_threads; thread; thread = thread->next) {
		if (thread->cpu == cpu) {
			found = 1;
			break;
		}
	}
	
	if (!found) {
		/* There are no threads which match this cpu because
		 * the physical_id attribute is not updated until the
		 * cpu is onlined -- this case is for cpus which are
		 * not present at boot but are added afterwards.
		 */
		return online_first_dead_cpu(cpu->cpu_nthreads, dr_info);
	}

	for (thread = cpu->cpu_threads; thread; thread = thread->sibling) {
		if (get_thread_state(thread) != ONLINE)
			rc |= set_thread_state(thread, ONLINE);
	}

	return rc;
}
コード例 #5
0
ファイル: scheduler.c プロジェクト: UIKit0/racoon
int pause( struct thread *tr, uint64_t milliseconds )
{
	int pos, i, id;
	struct scheduler_info *si;
	uint64_t now;
	uint64_t target;


	assert( tr != NULL );			// Real thread.
	assert( milliseconds > 0 );		// Real time

	
	assert( tr->cpu == CPUID );		// Current CPU

	id = tr->cpu;
	si = &( cpu[ id ].sched );
	
	sched_lock( id, 0 );

		now = cpu[ id ].st_systemTime.usage;
		target = milliseconds + now;
	
	// PAUSE INSERTION ......................
		
		if ( si->pause_count == si->pause_size ) 
		{
			sched_unlock( id );
			return -1;
		}

		// Add it by finding the position in the queue.
		
		for ( pos = 0; pos < si->pause_count; pos++ )
		{
			if ( si->pause_queue[ pos ].request > target ) break; 
		}
		
		// Move everything up one.
		for ( i = si->pause_count; i > pos; i-- )
		{
			si->pause_queue[ i ] = si->pause_queue[ i - 1 ];
		}

		// Insert the pause
		
		si->pause_queue[ pos ].tr 	    = tr;
		si->pause_queue[ pos ].state 	= tr->state;
		si->pause_queue[ pos ].request 	= target;
		si->pause_queue[ pos ].start 	= now;
		si->pause_count += 1;

		set_thread_state( tr, THREAD_DORMANT );
		tr->duration = milliseconds; 

	sched_unlock( id );
	return 0;
}
コード例 #6
0
ファイル: thread_helpers.hpp プロジェクト: avyavkumar/hpx
 ///////////////////////////////////////////////////////////////////////////
 /// \brief  Set the thread state of the \a thread referenced by the
 ///         thread_id \a id.
 ///
 /// Set a timer to set the state of the given \a thread to the given
 /// new value after it expired (after the given duration)
 ///
 /// \param id         [in] The thread id of the thread the state should
 ///                   be modified for.
 /// \param after_duration
 /// \param state      [in] The new state to be set for the thread
 ///                   referenced by the \a id parameter.
 /// \param state_ex   [in] The new extended state to be set for the
 ///                   thread referenced by the \a id parameter.
 /// \param priority
 /// \param ec         [in,out] this represents the error status on exit,
 ///                   if this is pre-initialized to \a hpx#throws
 ///                   the function will throw on error instead.
 ///
 /// \returns
 ///
 /// \note             As long as \a ec is not pre-initialized to
 ///                   \a hpx#throws this function doesn't
 ///                   throw but returns the result code using the
 ///                   parameter \a ec. Otherwise it throws an instance
 ///                   of hpx#exception.
 inline thread_id_type set_thread_state(thread_id_type const& id,
     util::steady_duration const& rel_time,
     thread_state_enum state = pending,
     thread_state_ex_enum stateex = wait_timeout,
     thread_priority priority = thread_priority_normal,
     error_code& ec = throws)
 {
     return set_thread_state(id, rel_time.from_now(), state, stateex,
         priority, ec);
 }
コード例 #7
0
ファイル: random.c プロジェクト: NocturnDragon/foundation_lib
void random_thread_deallocate( void )
{
	if( !get_thread_state() )
		return;

	mutex_lock( _random_mutex );
	array_push( _random_available_state, get_thread_state() );
	mutex_unlock( _random_mutex );

	set_thread_state( 0 );
}
コード例 #8
0
/**
 * cpu_diable_smt
 * @brief Disable all but one of a cpu's threads
 *
 * @param cpu cpu to disable smt on
 * @returns 0 on success, !0 otherwise
 */
int
cpu_disable_smt(struct dr_node *cpu)
{
	int rc = 0;
	struct thread *t;
	int survivor_found = 0;

	/* Ensure that the first thread of the processor is the thread that is left online
	 * when disabling SMT.
	 */
	t = cpu->cpu_threads;
	if (get_thread_state(t) == OFFLINE)
		rc |= set_thread_state(t, ONLINE);

	for (t = cpu->cpu_threads; t != NULL; t = t->sibling) {
		if (ONLINE == get_thread_state(t)) {
			if (survivor_found)
				rc |= set_thread_state(t, OFFLINE);
			survivor_found = 1;
		}
	}

	return rc;
}
コード例 #9
0
/**
 * offline_cpu
 * @brief Mark the specified cpu as offline
 *
 * @param cpu
 * @param dr_info
 * @returns 0 on success, !0 otherwise
 */
int
offline_cpu(struct dr_node *cpu)
{
	int rc = 0;
	struct thread *thread;

	say(DEBUG, "Offlining cpu %s (%d threads)\n", cpu->name,
	    cpu->cpu_nthreads);

	for (thread = cpu->cpu_threads; thread; thread = thread->sibling) {
		if (get_thread_state(thread) != OFFLINE)
			rc |= set_thread_state(thread, OFFLINE);
	}

	return rc;
}
コード例 #10
0
ファイル: waits.c プロジェクト: AdamRLukaitis/spoon
int clean_general( struct process *owner, struct wait_info *wait, int rc )
{
  struct process *proc;
  struct thread *tr;
  int count = 0;
  int clean = 0;
  
  struct wait_info *tmp = wait;
  struct wait_info *old = NULL;
    
    while ( tmp != NULL )
    {
      tmp->success = 0;
      tmp->rc = rc;

	  clean = 0;

	  // Make sure that it's not already locked.
	  if ( owner->pid == tmp->pid ) proc = owner;
	  else proc = checkout_process( tmp->pid, WRITER );
	  
		  if ( proc != NULL )
		  {
			tr = find_thread_with_id( proc, tmp->tid );
			if ( tr != NULL )
			{
				set_thread_state( tr, THREAD_RUNNING );
			}
			else clean = 1;	// Nothing waiting on this wait. Need to clean it.
				  
			if ( proc != owner ) commit_process( proc );

		  }
		  else clean = 1; // Nothing waiting on this wait. Need to clean it.
	  

	  old = tmp;
      tmp = tmp->next;
		
		  // Clean the wait if the waiter was not found.
	  	if ( clean == 1 ) free( old );
    }

  return count;
}
コード例 #11
0
ファイル: sem.c プロジェクト: AdamRLukaitis/spoon
int destroy_global_semaphore( int pid, int sem_id )
{
	struct sem_link *sl		= NULL;
	struct sem_link *tmp	= NULL;
	struct process *proc	= NULL;
	struct thread *tr		= NULL;

	if ( sem_id < 0 ) return -1;
	if ( sem_id >= GLOBAL_SEM_COUNT ) return -1;
	
	acquire_spinlock( & global_sems_lock );

		if ( ( global_sems[ sem_id ].sem_id != sem_id ) ||
			 ( global_sems[ sem_id ].pid 	!= pid ) )
		{
			// Invalid or not allowed.
			release_spinlock( & global_sems_lock );
			return -1;
		}
	
		// Tell the waiting guys to go away.
		sl = global_sems[ sem_id ].waiting_list;
		while ( sl != NULL )
		{
			tmp = sl;
			
			proc = checkout_process( sl->pid, WRITER );
			if ( proc != NULL ) 
			{
				tr = find_thread_with_id( proc, sl->tid );
				if ( tr != NULL ) 
						set_thread_state( tr, THREAD_RUNNING );
				commit_process( proc );
			}
			sl = sl->next;
			free( tmp );
		}

	 	global_sems[ sem_id ].waiting_list = NULL;
		global_sems[ sem_id ].sem_id 	= -1;	// DELETED!

	release_spinlock( & global_sems_lock );
	return 0;
}
コード例 #12
0
    void thread_pool_attached_executor<Scheduler>::add_at(
        boost::chrono::steady_clock::time_point const& abs_time,
        closure_type && f, char const* description,
        threads::thread_stacksize stacksize, error_code& ec)
    {
        if (stacksize == threads::thread_stacksize_default)
            stacksize = stacksize_;

        // create new thread
        thread_id_type id = register_thread_nullary(
            std::move(f), description, suspended, false,
            priority_, get_next_thread_num(), stacksize, ec);
        if (ec) return;

        HPX_ASSERT(invalid_thread_id != id);    // would throw otherwise

        // now schedule new thread for execution
        set_thread_state(id, abs_time);
    }
コード例 #13
0
ファイル: random.c プロジェクト: NocturnDragon/foundation_lib
void _random_shutdown( void )
{
	int i, size;

	if( _random_mutex )
		mutex_lock( _random_mutex );

	for( i = 0, size = array_size( _random_state ); i < size; ++i )
		memory_deallocate( _random_state[i] );
	array_deallocate( _random_available_state );
	array_deallocate( _random_state );

	set_thread_state( 0 );

	if( _random_mutex )
	{
		mutex_unlock( _random_mutex );
		mutex_deallocate( _random_mutex );
	}
}
コード例 #14
0
ファイル: sem.c プロジェクト: AdamRLukaitis/spoon
int destroy_local_semaphore( struct process *proc, int sem_id )
{
	struct sem_link *sl		= NULL;
	struct sem_link *tmp	= NULL;
	struct thread *tr		= NULL;

	if ( sem_id < 0 ) return -1;
	if ( sem_id >= LOCAL_SEM_COUNT ) return -1;
	
	acquire_spinlock( & (proc->sems_lock) );
		
		if ( proc->sems[ sem_id ].sem_id != sem_id ) 
		{
			release_spinlock( & (proc->sems_lock) );
			return -1;
		}
		

		// Tell the waiting guys to go away.
		sl = proc->sems[ sem_id ].waiting_list;
		while ( sl != NULL )
		{
			tmp = sl;

			tr = find_thread_with_id( proc, sl->tid );
			if ( tr != NULL )
					set_thread_state( tr, THREAD_RUNNING );

			sl = sl->next;
			free( tmp );
		}

		proc->sems[ sem_id ].waiting_list = NULL;
		proc->sems[ sem_id ].sem_id 	= -1; // DELETED!

	release_spinlock( & (proc->sems_lock) );
	return 0;
}
コード例 #15
0
ファイル: random.c プロジェクト: NocturnDragon/foundation_lib
static unsigned int* _random_thread_allocate( void )
{
	unsigned int* buffer;

	mutex_lock( _random_mutex );

	//Grab a free state buffer or allocate if none available
	if( !array_size( _random_available_state ) )
	{
		buffer = _random_allocate_buffer();
		array_push( _random_available_state, buffer );
	}
	else
	{
		buffer = _random_available_state[ array_size( _random_available_state ) - 1 ];
		array_pop( _random_available_state );
	}

	mutex_unlock( _random_mutex );
	
	set_thread_state( buffer );

	return buffer;
}
コード例 #16
0
ファイル: sem.c プロジェクト: AdamRLukaitis/spoon
int signal_global_semaphore( struct thread* tr, int sem_id )
{
	struct sem_link *sl;
	struct process *proc;
	struct thread *target;

	acquire_spinlock( & global_sems_lock );
		
		if ( global_sems[ sem_id ].sem_id != sem_id ) 
		{
			release_spinlock( & global_sems_lock );
			return -1;
		}
		
		global_sems[ sem_id ].count -= 1;
			
			// wake up any waiting threads
			sl = global_sems[ sem_id ].waiting_list;	
			if ( sl != NULL )
			{
				proc = checkout_process( sl->pid, WRITER );
				if ( proc != NULL )
				{
					target = find_thread_with_id( proc, sl->tid );
					if ( target != NULL )
						set_thread_state( target, THREAD_RUNNING );

					commit_process( proc );
				}
				global_sems[ sem_id ].waiting_list = sl->next;
				free( sl );
			}

	release_spinlock( & ( global_sems_lock ) );
	return 0;
}
コード例 #17
0
ファイル: waits.c プロジェクト: AdamRLukaitis/spoon
int begin_wait_process( int pid, int *rc )
{
  int success = -1;
  struct wait_info *nw 	= NULL;
  struct process *proc;

  proc = checkout_process( pid, WRITER );
  if ( proc == NULL ) return -1;


	nw = (struct wait_info*)malloc( sizeof(struct wait_info) ); 
	
	  nw->next = NULL;
	  nw->prev = NULL;
	  
		  nw->pid 		= current_pid();
		  nw->tid	 	= current_tid();
		  nw->success 	= -1;	// Assume failure from the very beginning.
		  nw->rc 		= -1;

	// Now we insert it into the wait list.
	  if ( proc->waits != NULL ) proc->waits->prev = nw;
	  nw->next = proc->waits;
	  proc->waits = nw;

	// -----------------------------
	commit_process( proc );

	// ------  Now we go to sleep -------------
		proc = checkout_process( current_pid(), WRITER );
		ASSERT( proc != NULL );

		current_thread()->active_wait = nw;		// Save our active wait.
	
		   	disable_interrupts();
			   atomic_dec( &(proc->kernel_threads) );
			   set_thread_state( current_thread(), THREAD_WAITING );  
			   commit_process( proc );
			enable_interrupts();

			sched_yield();	
			
			atomic_inc( &(proc->kernel_threads) );	// Secure this thread.
		
	// Get our process back.
  	proc = checkout_process( current_pid(), WRITER );
	ASSERT( proc != NULL );

		current_thread()->active_wait = NULL;
	
	commit_process( proc );

			
	// We're back. Return the correct info.
	 *rc = nw->rc;
	 success = nw->success;

	 // nw should have been unlinked by the scheduler.
	 // waiter should have active_wait cleared by the
	 // scheduler as well.
	 // we just need to delete it.

	free( nw );

	/// \todo active_waits for threads.

  return success;
}
コード例 #18
0
ファイル: waits.c プロジェクト: AdamRLukaitis/spoon
int begin_wait_thread( int pid, int tid, int *rc )
{
  int success = -1;
  int size;
  struct wait_info *nw 	= NULL;
  struct process *proc;
  struct thread *tr;

  ASSERT( pid == current_pid() );
  
  proc = checkout_process( pid, WRITER );
  ASSERT( proc != NULL );

  	tr = find_thread_with_id( proc, tid );
	if ( tr == NULL )
	{
		commit_process( proc );
		return -1;
	}


	// --------------------------------
	
	size = sizeof(struct wait_info);
	nw = (struct wait_info*)malloc( size ); 
	
	  nw->next = NULL;
	  nw->prev = NULL;
	  
		  nw->pid 		= current_pid();
		  nw->tid	 	= current_tid();
		  nw->success 	= -1;	// Assume failure from the very beginning.
		  nw->rc 		= -1;

	current_thread()->active_wait = nw;	// Set our active wait information.
		  
	// Now we insert it into the wait list.
	  if ( tr->waits != NULL ) tr->waits->prev = nw;
	  nw->next = tr->waits;
	  tr->waits = nw;

	// -----------------------------
	commit_process( proc );

	// ------  Now we go to sleep -------------
		proc = checkout_process( current_pid(), WRITER );
		if ( proc == NULL )
		{
			/// \todo freak out and handle stuff properly
			return -1;
		}
	
		   	disable_interrupts();
			   atomic_dec( &(proc->kernel_threads) );
			   set_thread_state( current_thread(), THREAD_WAITING );  
			   commit_process( proc );
			enable_interrupts();
			
			sched_yield();		// Release!	
			
						// Secure ourselves.
			atomic_inc( &(proc->kernel_threads) );

	// Get our process back.
  	proc = checkout_process( current_pid(), WRITER );
	if ( proc == NULL ) return -1;
			
		current_thread()->active_wait = NULL;

	commit_process( proc );
	
		// We're back. Return the correct info.
		 *rc = nw->rc;
		 success = nw->success;
	
		 // nw should have been unlinked by the scheduler.
		 // waiter should have active_wait cleared by the
		 // scheduler as well.
		 // we just need to delete it.
	
		free( nw );

  return success;

}
コード例 #19
0
ファイル: ao_wasapi.c プロジェクト: BILIHUBSU/mpv
static void audio_reset(struct ao *ao)
{
    set_thread_state(ao, WASAPI_THREAD_RESET);
}
コード例 #20
0
ファイル: sem.c プロジェクト: AdamRLukaitis/spoon
int wait_local_semaphore( struct thread* tr, int sem_id )
{
	struct process *proc	= NULL;
	struct sem_link *sl		= NULL;
	struct sem_link *tmp	= NULL;

	if ( sem_id < 0 ) return -1;
	if ( sem_id >= LOCAL_SEM_COUNT ) return -1;
	
	proc = tr->process;

	acquire_spinlock( & (proc->sems_lock) );
			
		// Valid semaphore?
		if ( proc->sems[ sem_id ].sem_id != sem_id ) 
		{
			release_spinlock( & (proc->sems_lock) );
			return -1;
		}

		// Insert this thread into the waiting list and wait, if required.
		if ( proc->sems[ sem_id ].count == proc->sems[ sem_id ].capacity )
		{
			sl = (struct sem_link*)malloc(  sizeof( struct sem_link ) );
			sl->tid 	= tr->tid;
			sl->pid 	= proc->pid;
			sl->next 	= NULL;
	
			if ( proc->sems[ sem_id ].waiting_list == NULL ) 
					proc->sems[ sem_id ].waiting_list = sl;
			else
			{
			  tmp = proc->sems[ sem_id ].waiting_list;
			  while ( tmp->next != NULL ) tmp = tmp->next;
			  tmp->next = sl;
			}
	
			// Now wait...

			disable_interrupts();
				set_thread_state( tr, THREAD_SEMAPHORE );
				release_spinlock( & (proc->sems_lock) );
			enable_interrupts();

				sched_yield();	// wait proper.. won't come back for a while.

			acquire_spinlock( & (proc->sems_lock) );

			if ( proc->sems[ sem_id ].sem_id != sem_id )
			{
				release_spinlock( & (proc->sems_lock) );
				return -1;		// Must have died... damn.
			}
		}

	proc->sems[ sem_id ].count += 1;

	release_spinlock( & (proc->sems_lock) );

	return 0;
}
コード例 #21
0
ファイル: ao_wasapi.c プロジェクト: BILIHUBSU/mpv
static void audio_resume(struct ao *ao)
{
    set_thread_state(ao, WASAPI_THREAD_RESUME);
}
コード例 #22
0
ファイル: thread.c プロジェクト: budden/sbcl-ita
static void
undo_init_new_thread(struct thread *th, init_thread_data *scribble)
{
    int lock_ret;

    /* Kludge: Changed the order of some steps between the safepoint/
     * non-safepoint versions of this code.  Can we unify this more?
     */
#ifdef LISP_FEATURE_SB_SAFEPOINT
    block_blockable_signals(0);
    gc_alloc_update_page_tables(BOXED_PAGE_FLAG, &th->alloc_region);
#if defined(LISP_FEATURE_SB_SAFEPOINT_STRICTLY) && !defined(LISP_FEATURE_WIN32)
    gc_alloc_update_page_tables(BOXED_PAGE_FLAG, &th->sprof_alloc_region);
#endif
    pop_gcing_safety(&scribble->safety);
    lock_ret = pthread_mutex_lock(&all_threads_lock);
    gc_assert(lock_ret == 0);
    unlink_thread(th);
    lock_ret = pthread_mutex_unlock(&all_threads_lock);
    gc_assert(lock_ret == 0);
#else
    /* Block GC */
    block_blockable_signals(0);
    set_thread_state(th, STATE_DEAD);

    /* SIG_STOP_FOR_GC is blocked and GC might be waiting for this
     * thread, but since we are already dead it won't wait long. */
    lock_ret = pthread_mutex_lock(&all_threads_lock);
    gc_assert(lock_ret == 0);

    gc_alloc_update_page_tables(BOXED_PAGE_FLAG, &th->alloc_region);
#if defined(LISP_FEATURE_SB_SAFEPOINT_STRICTLY) && !defined(LISP_FEATURE_WIN32)
    gc_alloc_update_page_tables(BOXED_PAGE_FLAG, &th->sprof_alloc_region);
#endif
    unlink_thread(th);
    pthread_mutex_unlock(&all_threads_lock);
    gc_assert(lock_ret == 0);
#endif

    arch_os_thread_cleanup(th);

#ifndef LISP_FEATURE_SB_SAFEPOINT
    os_sem_destroy(th->state_sem);
    os_sem_destroy(th->state_not_running_sem);
    os_sem_destroy(th->state_not_stopped_sem);
#endif


#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
    mach_lisp_thread_destroy(th);
#endif

#if defined(LISP_FEATURE_WIN32)
    int i;
    for (i = 0; i<
             (int) (sizeof(th->private_events.events)/
                    sizeof(th->private_events.events[0])); ++i) {
      CloseHandle(th->private_events.events[i]);
    }
    TlsSetValue(OUR_TLS_INDEX,NULL);
#endif

    /* Undo the association of the current pthread to its `struct thread',
     * such that we can call arch_os_get_current_thread() later in this
     * thread and cleanly get back NULL. */
#ifdef LISP_FEATURE_GCC_TLS
    current_thread = NULL;
#else
    pthread_setspecific(specials, NULL);
#endif
}
コード例 #23
0
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			   sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	int err = 0;
	int signal;

	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
	if (regs->depc > 64)
		panic ("Double exception sys_sigreturn\n");

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto give_sigsegv;

	signal = current_thread_info()->exec_domain
		&& current_thread_info()->exec_domain->signal_invmap
		&& sig < 32
		? current_thread_info()->exec_domain->signal_invmap[sig]
		: sig;

	err |= copy_siginfo_to_user(&frame->info, info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |= __put_user((void *)current->sas_ss_sp,
			  &frame->uc.uc_stack.ss_sp);
	err |= __put_user(sas_ss_flags(regs->areg[1]),
			  &frame->uc.uc_stack.ss_flags);
	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
			        regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	/* Create sys_rt_sigreturn syscall in stack frame */
	err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);

	if (err)
		goto give_sigsegv;

	/* Create signal handler execution context.
	 * Return context not modified until this point.
	 */
	set_thread_state(regs, frame, frame->retcode,
		ka->sa.sa_handler, signal, &frame->info, &frame->uc);

	/* Set access mode to USER_DS.  Nomenclature is outdated, but
	 * functionality is used in uaccess.h
	 */
	set_fs(USER_DS);

#if DEBUG_SIG
	printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
		current->comm, current->pid, signal, frame, regs->pc);
#endif

	return;

give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, current);
}
コード例 #24
0
static void setup_frame(int sig, struct k_sigaction *ka,
			sigset_t *set, struct pt_regs *regs)
{
	struct sigframe *frame;
	int err = 0;
	int signal;

	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
	if (regs->depc > 64)
	{
		printk("!!!!!!! DEPC !!!!!!!\n");
		return;
	}


	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto give_sigsegv;

	signal = current_thread_info()->exec_domain
		&& current_thread_info()->exec_domain->signal_invmap
		&& sig < 32
		? current_thread_info()->exec_domain->signal_invmap[sig]
		: sig;

	err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);

	if (_NSIG_WORDS > 1) {
		err |= __copy_to_user(frame->extramask, &set->sig[1],
				      sizeof(frame->extramask));
	}

	/* Create sys_sigreturn syscall in stack frame */
	err |= gen_return_code(frame->retcode, USE_SIGRETURN);

	if (err)
		goto give_sigsegv;

	/* Create signal handler execution context.
	 * Return context not modified until this point.
	 */
	set_thread_state(regs, frame, frame->retcode,
		ka->sa.sa_handler, signal, &frame->sc, NULL);

	/* Set access mode to USER_DS.  Nomenclature is outdated, but
	 * functionality is used in uaccess.h
	 */
	set_fs(USER_DS);


#if DEBUG_SIG
	printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
		current->comm, current->pid, signal, frame, regs->pc);
#endif

	return;

give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, current);
}
コード例 #25
0
ファイル: ao_wasapi.c プロジェクト: ThreeGe/mpv
static int control_exclusive(struct ao *ao, enum aocontrol cmd, void *arg)
{
    struct wasapi_state *state = ao->priv;

    switch (cmd) {
    case AOCONTROL_GET_VOLUME:
    case AOCONTROL_SET_VOLUME:
        if (!state->pEndpointVolumeProxy ||
            !(state->vol_hw_support & ENDPOINT_HARDWARE_SUPPORT_VOLUME)) {
            return CONTROL_FALSE;
        }

        float volume;
        switch (cmd) {
        case AOCONTROL_GET_VOLUME:
            IAudioEndpointVolume_GetMasterVolumeLevelScalar(
                state->pEndpointVolumeProxy,
                &volume);
            *(ao_control_vol_t *)arg = (ao_control_vol_t){
                .left  = 100.0f * volume,
                .right = 100.0f * volume,
            };
            return CONTROL_OK;
        case AOCONTROL_SET_VOLUME:
            volume = ((ao_control_vol_t *)arg)->left / 100.f;
            IAudioEndpointVolume_SetMasterVolumeLevelScalar(
                state->pEndpointVolumeProxy,
                volume, NULL);
            return CONTROL_OK;
        }
    case AOCONTROL_GET_MUTE:
    case AOCONTROL_SET_MUTE:
        if (!state->pEndpointVolumeProxy ||
            !(state->vol_hw_support & ENDPOINT_HARDWARE_SUPPORT_MUTE)) {
            return CONTROL_FALSE;
        }

        BOOL mute;
        switch (cmd) {
        case AOCONTROL_GET_MUTE:
            IAudioEndpointVolume_GetMute(state->pEndpointVolumeProxy,
                                         &mute);
            *(bool *)arg = mute;
            return CONTROL_OK;
        case AOCONTROL_SET_MUTE:
            mute = *(bool *)arg;
            IAudioEndpointVolume_SetMute(state->pEndpointVolumeProxy,
                                         mute, NULL);
            return CONTROL_OK;
        }
    case AOCONTROL_HAS_PER_APP_VOLUME:
        return CONTROL_FALSE;
    default:
        return CONTROL_UNKNOWN;
    }
}

static int control_shared(struct ao *ao, enum aocontrol cmd, void *arg)
{
    struct wasapi_state *state = ao->priv;
    if (!state->pAudioVolumeProxy)
        return CONTROL_UNKNOWN;

    float volume;
    BOOL mute;
    switch(cmd) {
    case AOCONTROL_GET_VOLUME:
        ISimpleAudioVolume_GetMasterVolume(state->pAudioVolumeProxy,
                                           &volume);
        *(ao_control_vol_t *)arg = (ao_control_vol_t){
            .left  = 100.0f * volume,
            .right = 100.0f * volume,
        };
        return CONTROL_OK;
    case AOCONTROL_SET_VOLUME:
        volume = ((ao_control_vol_t *)arg)->left / 100.f;
        ISimpleAudioVolume_SetMasterVolume(state->pAudioVolumeProxy,
                                           volume, NULL);
        return CONTROL_OK;
    case AOCONTROL_GET_MUTE:
        ISimpleAudioVolume_GetMute(state->pAudioVolumeProxy, &mute);
        *(bool *)arg = mute;
        return CONTROL_OK;
    case AOCONTROL_SET_MUTE:
        mute = *(bool *)arg;
        ISimpleAudioVolume_SetMute(state->pAudioVolumeProxy, mute, NULL);
        return CONTROL_OK;
    case AOCONTROL_HAS_PER_APP_VOLUME:
        return CONTROL_TRUE;
    default:
        return CONTROL_UNKNOWN;
    }
}

static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
    struct wasapi_state *state = ao->priv;

    // common to exclusive and shared
    switch (cmd) {
    case AOCONTROL_UPDATE_STREAM_TITLE:
        if (!state->pSessionControlProxy)
            return CONTROL_FALSE;

        wchar_t *title = mp_from_utf8(NULL, (char*)arg);
        wchar_t *tmp = NULL;
        // There is a weird race condition in the IAudioSessionControl itself --
        // it seems that *sometimes* the SetDisplayName does not take effect and
        // it still shows the old title. Use this loop to insist until it works.
        do {
            IAudioSessionControl_SetDisplayName(state->pSessionControlProxy,
                                                title, NULL);

            SAFE_RELEASE(tmp, CoTaskMemFree(tmp));
            IAudioSessionControl_GetDisplayName(state->pSessionControlProxy,
                                                &tmp);
        } while (lstrcmpW(title, tmp));
        SAFE_RELEASE(tmp, CoTaskMemFree(tmp));
        talloc_free(title);
        return CONTROL_OK;
    }

    return state->opt_exclusive ?
        control_exclusive(ao, cmd, arg) : control_shared(ao, cmd, arg);
}

static void audio_reset(struct ao *ao)
{
    set_thread_state(ao, WASAPI_THREAD_RESET);
}

static void audio_resume(struct ao *ao)
{
    set_thread_state(ao, WASAPI_THREAD_RESUME);
}
コード例 #26
0
ファイル: sgcomm_tx_test.c プロジェクト: sma-wideband/sdbe
void handle_sigint(int signum) {
	log_message(RL_NOTICE,"%s:SIGINT received, stopping %s thread",__FUNCTION__,get_thread_type_str(st_main.type));
	/* Cannot stop_thread on main, since it's not pthread-ed */
	//~ stop_thread(&st_main);
	set_thread_state(&st_main, CS_STOP, NULL);
}
コード例 #27
0
ファイル: sgcomm_tx_test.c プロジェクト: sma-wideband/sdbe
int main(int argc, char **argv) {
	/* Slave threads */
	sgcomm_thread *st_rd; // Reader
	sgcomm_thread *st_tx; // Transmitter
	shared_buffer *sbtx; // shared buffer for read+transmit
	
	/* Reader message parameters */
	char *fmtstr = "/mnt/disks/%u/%u/data/%s";
	char *pattern_read = "input.vdif";
	char *host = "localhost";
	uint16_t port = 61234;
	int n_mod = 4;
	int mod_list[4] = { 1, 2, 3, 4};
	int n_disk = 8;
	int disk_list_read[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
	int disk_list_write[8] = { 1, 0, 2, 3, 4, 5, 6, 7 };
	
	/* Transmitter message parameters */
	if (argc > 1)
		pattern_read = argv[1];
	if (argc > 2)
		fmtstr = argv[2];
	if (argc > 3)
		host = argv[3];
	if (argc > 4)
		port = atoi(argv[4]);
	
	log_message(RL_NOTICE,"%s:Using input file '%s' matching pattern '%s'",__FUNCTION__,pattern_read,fmtstr);
	log_message(RL_NOTICE,"%s:Transmitting to %s:%u",__FUNCTION__,host,port);
	
	/* This thread */
	sgcomm_thread *st = &st_main;
	ctrl_state state;
	
	log_message(RL_DEBUG,"%s:Creating shared buffer",__FUNCTION__);
	
	/* Initialize shared data buffer */
	sbtx = create_shared_buffer(SHARED_BUFFER_SIZE_TX);
	if (sbtx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Creating slave threads",__FUNCTION__);
	
	/* Create thread instances */
	st_rd = create_thread(TT_READER);
	if (st_rd == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create reader thread",__FUNCTION__,__LINE__);
	st_tx = create_thread(TT_TRANSMITTER);
	if (st_tx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create transmitter thread",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Initializing thread messages",__FUNCTION__);
	
	/* Initialize thread messages */
	init_reader_msg((reader_msg *)st_rd->type_msg, sbtx, pattern_read, fmtstr,
					mod_list, n_mod, disk_list_read, n_disk);
	init_transmitter_msg((transmitter_msg *)st_tx->type_msg, sbtx,
					host, port);
	
	/* Start transmitter thread */
	if (start_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot start transmitter thread",__FUNCTION__,__LINE__);
	/* Pause, then see if transmitter has error, if so, abort */
	usleep(MAIN_WAIT_PERIOD_US);
	if ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) {
		set_thread_state(st,CS_ERROR,"%s(%d):Transmitter terminated prematurely, aborting start.",__FUNCTION__,__LINE__);
	} else {
		if (start_thread(st_rd) != 0)
			set_thread_state(st,CS_ERROR,"%s(%d):Cannot start reader thread",__FUNCTION__,__LINE__);
	}
	
	//~ log_message(RL_DEBUG,"%s:Entering main thread run loop",__FUNCTION__);
	
	if ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP))
		set_thread_state(st,CS_RUN,"%s:Thread running",__FUNCTION__);
	while ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP)) {
				
		// TODO: do something
		
		usleep(MAIN_WAIT_PERIOD_US);
		
		/* If any thread has a problem, stop all of them */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_ERROR)) ||
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_ERROR)) ) {
			// TODO: Some cleanup?
			break;
		}
		
		/* If all threads are stopped, break */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP)) &&
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) ) {
			log_message(RL_NOTICE,"%s:All threads stopped of their own volition",__FUNCTION__);
			break;
		}
		
		/* If reader thread is done, stop transmitter */
		if ( (get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP) && 
			 (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP)) {
			log_message(RL_NOTICE,"%s:Reader is done, stop transmitter",__FUNCTION__);
			/* Two wait periods should be enough - reader is the only
			 * other thread that can cause transmitter to wait on a 
			 * resource, and then it will only be a single wait. */
			usleep(MAIN_WAIT_PERIOD_US);
			usleep(MAIN_WAIT_PERIOD_US);
			if (stop_thread(st_tx) != 0)
				set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
		}
		
	}
	
	log_message(RL_DEBUG,"%s:Stopping slave threads",__FUNCTION__);
	
	/* Stop slave threads on tx side */
	if ( (get_thread_state(st_rd,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_rd) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop reader thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Reader thread stopped",__FUNCTION__);
	if ( (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Transmitter thread stopped",__FUNCTION__);
	
	log_message(RL_DEBUG,"%s:Destroying shared buffer",__FUNCTION__);
	
	/* Destroy shared data buffer */
	if (destroy_shared_buffer(&sbtx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot destroy shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Destroying slave threads",__FUNCTION__);
	
	/* Destroy threads */
	destroy_thread(&st_rd);
	destroy_thread(&st_tx);
	
	log_message(RL_DEBUG,"%s:Everything is done, goodbye",__FUNCTION__);
	
	/* That's all folks! */
	// TODO: Report that we're done
	return EXIT_SUCCESS;
}