Пример #1
0
/* Function binds a given TID  to any thread of core 0 */
int do_the_bind_thread(pthread_t tid)
{
    int lcpu, rc = 0;

    lcpu = get_logical_cpu_num(0, 0, 0, bind_th_num); /* Bind to N0P0C0T* */
    rc = bind_thread(tid, lcpu, -1);
    bind_th_num = (bind_th_num + 1) % smt;
    return rc;
}
Пример #2
0
void HostInternal::driver( const size_t thread_rank )
{
  // Bind this thread to a unique processing unit
  // with all members of a gang in the same NUMA region.

  if ( bind_thread( thread_rank ) ) {

    HostThread this_thread ;

    m_thread[ thread_rank ] = & this_thread ;

    // Initialize thread ranks and fan-in relationships:

    if ( initialize_thread( thread_rank , this_thread ) ) {

      // Inform master thread that binding and initialization succeeded.
      m_master_thread.set( HostThread::ThreadActive );

      try {
        // Work loop:

        while ( HostThread::ThreadActive == this_thread.m_state ) {

          // When the work is complete the state will be Inactive or Terminate
          m_worker->execute_on_thread( this_thread );

          // If this_thread is in the Inactive state then wait for activation.
          this_thread.wait( HostThread::ThreadInactive );
        }
      }
      catch( const std::exception & x ) {
        // mfh 29 May 2012: Doesn't calling std::terminate() seem a
        // little violent?  On the other hand, C++ doesn't define how
        // to transport exceptions between threads (until C++11).
        // Since this is a worker thread, it would be hard to tell the
        // master thread what happened.
        std::cerr << "Thread " << thread_rank << " uncaught exception : "
                  << x.what() << std::endl ;
        std::terminate();
      }
      catch( ... ) {
        // mfh 29 May 2012: See note above on std::terminate().
        std::cerr << "Thread " << thread_rank << " uncaught exception"
                  << std::endl ;
        std::terminate();
      }
    }
  }

  // Notify master thread that this thread has terminated.

  m_thread[ thread_rank ] = 0 ;

  m_master_thread.set( HostThread::ThreadTerminating );
}
Пример #3
0
bool HostInternal::spawn_threads( const unsigned gang_count ,
                                  const unsigned worker_count )
{
  // If the process is bound to a particular node
  // then only use cores belonging to that node.
  // Otherwise use all nodes and all their cores.

  m_gang_count   = gang_count ;
  m_worker_count = worker_count ;
  m_thread_count = gang_count * worker_count ;
  m_worker       = & m_worker_block ;

  // Bind the process thread as thread_rank == 0
  bool ok_spawn_threads = bind_thread( 0 );

  // Spawn threads from last-to-first so that the
  // fan-in barrier thread relationships can be established.

  for ( unsigned rank = m_thread_count ; ok_spawn_threads && 0 < --rank ; ) {

    m_master_thread.set( HostThread::ThreadInactive );

    // Spawn thread executing the 'driver' function.
    ok_spawn_threads = spawn( rank );

    if ( ok_spawn_threads ) {

      // Thread spawned, wait for thread to activate:
      m_master_thread.wait( HostThread::ThreadInactive );

      // Check if the thread initialized and bound correctly:
      ok_spawn_threads = HostThread::ThreadActive == m_master_thread.m_state ;

      if ( ok_spawn_threads ) { // Wait for spawned thread to deactivate
        HostThread * volatile * const threads = m_thread ;
        threads[ rank ]->wait( HostThread::ThreadActive );
        // m_thread[ rank ]->wait( HostThread::ThreadActive );
      }
    }
  }

  m_worker = NULL ;

  // All threads spawned, initialize the master-thread fan-in
  ok_spawn_threads =
    ok_spawn_threads && initialize_thread( 0 , m_master_thread );

  if ( ! ok_spawn_threads ) {
    finalize();
  }

  return ok_spawn_threads ;
}
Пример #4
0
PRIVATE
L4_msg_tag
Irq_sender::sys_attach(L4_msg_tag const &tag, Utcb const *utcb, Syscall_frame * /*f*/,
                Obj_space *o_space)
{
  L4_snd_item_iter snd_items(utcb, tag.words());

  Thread *thread = 0;

  if (tag.items() == 0)
    {
      // detach
      Reap_list rl;
      free(_irq_thread, rl.list());
      _irq_id = ~0UL;
      cpu_lock.clear();
      rl.del();
      cpu_lock.lock();
      return commit_result(0);
    }

  if (tag.items() && snd_items.next())
    {
      L4_fpage bind_thread(snd_items.get()->d);
      if (EXPECT_FALSE(!bind_thread.is_objpage()))
	return commit_error(utcb, L4_error::Overflow);

      thread = Kobject::dcast<Thread_object*>(o_space->lookup_local(bind_thread.obj_index()));
    }

  if (!thread)
    thread = current_thread();

  if (alloc(thread))
    {
      _irq_id = utcb->values[1];
      return commit_result(0);
    }

  return commit_result(-L4_err::EInval);
}
Пример #5
0
PUBLIC
L4_msg_tag
Ipc_gate_ctl::kinvoke(L4_obj_ref self, L4_fpage::Rights rights,
                      Syscall_frame *f, Utcb const *in, Utcb *out)
{
  L4_msg_tag tag = f->tag();

  if (EXPECT_FALSE(tag.proto() != L4_msg_tag::Label_kobject))
    return commit_result(-L4_err::EBadproto);

  if (EXPECT_FALSE(tag.words() < 1))
    return commit_result(-L4_err::EInval);

  switch (in->values[0])
    {
    case Op_bind:
      return bind_thread(self, rights, f, in, out);
    case Op_get_info:
      return get_infos(self, rights, f, in, out);
    default:
      return static_cast<Ipc_gate_obj*>(this)->kobject_invoke(self, rights, f, in, out);
    }
}