Ejemplo n.º 1
0
/*-----------------------------------------------------------------------------
 *
 *---------------------------------------------------------------------------*/
void destroy_proc(void)
{
	thread_t*	thread;
	process_t*	proc;

	/*asm volatile ("cli");*/
	stop();

	thread = get_current_thread();
	proc = thread->process;

	remove_thread(thread);

	/* Free process memory pages */
	kfree(thread->stack);
	thread->stack = NULL;

	free_phys_pages(proc->user_stack_paddr, proc->stack_page_count);
	free_phys_pages(proc->seg_paddr, proc->seg_page_count);
	free_phys_pages(proc->heap_paddr, proc->heap_page_count);
	free_phys_pages(proc->blocks_paddr, proc->blocks_page_count);

	kfree(thread);
	thread = NULL;

	proc->threads_count--;

	while (proc->threads_count > 0)
	{
		thread = get_thread(proc->thread_id[proc->threads_count - 1]);

		remove_thread(thread);

		thread->process->threads_count--;

		/* Free thread's memory (handler and stack) */
		kfree(thread->stack);
		thread->stack = NULL;
		kfree(thread);
		thread = NULL;
	}

	/* Here we must free memory!!! */

	/*asm volatile ("sti");*/
	start();

	task_switch();
}
Ejemplo n.º 2
0
void Skedule()
{
    UINTN i;
    thread_list *  oldThread;
    BOOLEAN CouldSkedule ;
    CouldSkedule =  __sync_bool_compare_and_swap (&Inschedule, 0, 1);
    if(CouldSkedule == 0)
        return;
    //pebp();
    oldThread = sys.current;
    if(oldThread->thread.status == STATUS_DEAD){
        remove_thread();
        //switchto();
        LongJump(& sys.current->thread.sig_context, 1);
    }
    free_dead_stack();

    sys.current = getNext(sys.current);
    if(oldThread == sys.current)
        return;
    i = SetJump(&oldThread->thread.sig_context);
    if( i  ==  0)
    {
    //EnableInterrupt ();
        gBS->RestoreTPL(TPL_APPLICATION);
        LongJump(& sys.current->thread.sig_context, 1);
    }
    __sync_bool_compare_and_swap (&Inschedule, 1, 0);
    //pebp();
    // Print(L"Haha, I am resuming\n");
    //while(1);
}
Ejemplo n.º 3
0
/* Delete a thread from the list of threads.  */
static void
delete_thread_info (struct inferior_list_entry *thread)
{
  win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);

  remove_thread ((struct thread_info *) thread);
  CloseHandle (th->h);
  free (th);
}
Ejemplo n.º 4
0
void thread_exit(void)
{
    remove_thread(THREAD_ID_CURRENT);
    /* This should never and must never be reached - if it is, the
     * state is corrupted */
    THREAD_PANICF("thread_exit->K:*R",
                  thread_id_entry(THREAD_ID_CURRENT));
    while (1);
}
void thread_exit(void)
{
    unsigned int id = thread_self();
    remove_thread(id);
    /* This should never and must never be reached - if it is, the
     * state is corrupted */
    THREAD_PANICF("thread_exit->K:*R (ID: %d)", id);
    while (1);
}
Ejemplo n.º 6
0
static
void remove_thread_if_not_in_vg_threads (struct inferior_list_entry *inf)
{
  struct thread_info *thread = get_thread (inf);
  if (!VG_(lwpid_to_vgtid)(thread_to_gdb_id(thread))) {
     dlog(1, "removing gdb ptid %s\n", 
          image_ptid(thread_to_gdb_id(thread)));
     remove_thread (thread);
  }
}
Ejemplo n.º 7
0
/* Clean exited process' pmap and calling thread */
static inline void destroy_all(struct thread *old)
{
	kprintf("Thread Exiting");
	if(old->states & PROCESS_EXITING)
	{
		pmap_destroy(old->proc->map->pmap);
		vm_map_destroy(old->proc->map);
	}
	remove_thread(old);
	destroy_thread(old);
}
Ejemplo n.º 8
0
/*
 * Wait for the IRQ.
 */
int syscall_IRQ_wait()
{
	thread_t thread = current;

	if(!superuser())
		return -EPERM;

	thread->states = IRQ_WAIT;
	remove_thread(thread);
	schedule();

	return 0;
}
Ejemplo n.º 9
0
void cleanup_handler( void* arg )
{
    struct _thread_cleanup_data* _data = ( struct _thread_cleanup_data* )arg;

    int* sock = (int* )_data->data;
    close(*sock);
    free( sock );

    syslog( LOG_INFO, "Worker %zu close socket and cleanup data.",
           _data->thread_id );
    syslog( LOG_INFO, "Worker %zu stopped.\n", _data->thread_id );

    remove_thread( _data->thread_id );
}
static void
nto_find_new_threads (struct nto_inferior *nto_inferior)
{
  pthread_t tid;

  TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);

  if (nto_inferior->ctl_fd == -1)
    return;

  for (tid = 1;; ++tid)
    {
      procfs_status status;
      ptid_t ptid;
      int err;

      status.tid = tid;
      err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
		    sizeof (status), 0);

      if (err != EOK || status.tid == 0)
	break;

      /* All threads in between are gone.  */
      while (tid != status.tid || status.state == STATE_DEAD)
	{
	  struct thread_info *ti;

	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  ti = find_thread_ptid (ptid);
	  if (ti != NULL)
	    {
	      TRACE ("Removing thread %d\n", tid);
	      remove_thread (ti);
	    }
	  if (tid == status.tid)
	    break;
	  ++tid;
	}

      if (status.state != STATE_DEAD)
	{
	  TRACE ("Adding thread %d\n", tid);
	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  if (!find_thread_ptid (ptid))
	    add_thread (ptid, NULL);
	}
    }
}
Ejemplo n.º 11
0
/* Lock the sync object */
int syscall_sync_lock(void *ptr, int sync_id)
{
	struct sync *sn;
	thread_t thr = current;
//	kprintf("SYNC locked");
	sn = find_sync(thr->proc->pid, sync_id);
	if(!sn)
		return -EINVAL;

	thr->states = SYNC_BLOCKED;
	remove_thread(thr);
	list_enqueue(&sn->wq, thr, runq, thread_t);
	schedule();

	return 0;
}
Ejemplo n.º 12
0
int
_papi_hwi_shutdown_thread( ThreadInfo_t * thread )
{
	int retval = PAPI_OK;
	unsigned long tid;
	int i, failure = 0;

	if ( _papi_hwi_thread_id_fn )
		tid = ( *_papi_hwi_thread_id_fn ) (  );
	else
		tid = ( unsigned long ) getpid(  );

        THRDBG("Want to shutdown thread %ld, alloc %ld, our_tid: %ld\n",
	       thread->tid,
	       thread->allocator_tid,
	       tid);

	if ((thread->tid==tid) || ( thread->allocator_tid == tid )) {

                _papi_hwi_thread_free_eventsets(tid);

		remove_thread( thread );
		THRDBG( "Shutting down thread %ld at %p\n", thread->tid, thread );
		for ( i = 0; i < papi_num_components; i++ ) {
			retval = _papi_hwd[i]->shutdown( thread->context[i] );
			if ( retval != PAPI_OK )
				failure = retval;
		}
		free_thread( &thread );
		return ( failure );
	}

	THRDBG( "Skipping shutdown thread %ld at %p, thread %ld not allocator!\n",
			thread->tid, thread, tid );
	return PAPI_EBUG;
}
Ejemplo n.º 13
0
static int
fbsd_wait_for_event (struct thread_info *child)
{
  CORE_ADDR stop_pc;
  struct process_info *event_child;
  int wstat;

  /* Check for a process with a pending status.  */
  /* It is possible that the user changed the pending task's registers since
     it stopped.  We correctly handle the change of PC if we hit a breakpoint
     (in check_removed_breakpoint); signals should be reported anyway.  */
  if (child == NULL)
    {
      event_child = (struct process_info *)
	find_inferior (&all_processes, status_pending_p, NULL);
      if (debug_threads && event_child)
	fprintf (stderr, "Got a pending child %d\n", event_child->lwpid);
    }
  else
    {
      event_child = get_thread_process (child);
      if (event_child->status_pending_p
	  && check_removed_breakpoint (event_child))
	event_child = NULL;
    }

  if (event_child != NULL)
    {
      if (event_child->status_pending_p)
	{
	  if (debug_threads)
	    fprintf (stderr, "Got an event from pending child %d (%04x)\n",
		     event_child->lwpid, event_child->status_pending);
	  wstat = event_child->status_pending;
	  event_child->status_pending_p = 0;
	  event_child->status_pending = 0;
	  current_inferior = get_process_thread (event_child);
	  return wstat;
	}
    }

  /* We only enter this loop if no process has a pending wait status.  Thus
     any action taken in response to a wait status inside this loop is
     responding as soon as we detect the status, not after any pending
     events.  */
  while (1)
    {
      if (child == NULL)
	event_child = NULL;
      else
	event_child = get_thread_process (child);

      fbsd_wait_for_process (&event_child, &wstat);

      if (event_child == NULL)
	error ("event from unknown child");

      current_inferior = (struct thread_info *)
	find_inferior_id (&all_threads, event_child->tid);

      if (using_threads)
	{
	  /* Check for thread exit.  */
	  if (! WIFSTOPPED (wstat))
	    {
	      if (debug_threads)
		fprintf (stderr, "Thread %d (LWP %d) exiting\n",
			 event_child->tid, event_child->head.id);

	      /* If the last thread is exiting, just return.  */
	      if (all_threads.head == all_threads.tail)
		return wstat;

	      dead_thread_notify (event_child->tid);

	      remove_inferior (&all_processes, &event_child->head);
	      free (event_child);
	      remove_thread (current_inferior);
	      current_inferior = (struct thread_info *) all_threads.head;

	      /* If we were waiting for this particular child to do something...
		 well, it did something.  */
	      if (child != NULL)
		return wstat;

	      /* Wait for a more interesting event.  */
	      continue;
	    }

	  if (WIFSTOPPED (wstat)
	      && WSTOPSIG (wstat) == SIGSTOP
	      && event_child->stop_expected)
	    {
	      if (debug_threads)
		fprintf (stderr, "Expected stop.\n");
	      event_child->stop_expected = 0;
	      fbsd_resume_one_process (&event_child->head,
					event_child->stepping, 0);
	      continue;
	    }

	  /* FIXME drow/2002-06-09: Get signal numbers from the inferior's
	     thread library?  */
	  if (WIFSTOPPED (wstat))
	    {
	      if (debug_threads)
		fprintf (stderr, "Ignored signal %d for %d (LWP %d).\n",
			 WSTOPSIG (wstat), event_child->tid,
			 event_child->head.id);
	      fbsd_resume_one_process (&event_child->head,
					event_child->stepping,
					WSTOPSIG (wstat));
	      continue;
	    }
	}

      /* If this event was not handled above, and is not a SIGTRAP, report
	 it.  */
      if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGTRAP)
	return wstat;

      /* If this target does not support breakpoints, we simply report the
	 SIGTRAP; it's of no concern to us.  */
      if (the_low_target.get_pc == NULL)
	return wstat;

      stop_pc = get_stop_pc ();

      /* bp_reinsert will only be set if we were single-stepping.
	 Notice that we will resume the process after hitting
	 a gdbserver breakpoint; single-stepping to/over one
	 is not supported (yet).  */
      if (event_child->bp_reinsert != 0)
	{
	  if (debug_threads)
	    fprintf (stderr, "Reinserted breakpoint.\n");
	  reinsert_breakpoint (event_child->bp_reinsert);
	  event_child->bp_reinsert = 0;

	  /* Clear the single-stepping flag and SIGTRAP as we resume.  */
	  fbsd_resume_one_process (&event_child->head, 0, 0);
	  continue;
	}

      if (debug_threads)
	fprintf (stderr, "Hit a (non-reinsert) breakpoint.\n");

      if (check_breakpoints (stop_pc) != 0)
	{
	  /* We hit one of our own breakpoints.  We mark it as a pending
	     breakpoint, so that check_removed_breakpoint () will do the PC
	     adjustment for us at the appropriate time.  */
	  event_child->pending_is_breakpoint = 1;
	  event_child->pending_stop_pc = stop_pc;

	  /* Now we need to put the breakpoint back.  We continue in the event
	     loop instead of simply replacing the breakpoint right away,
	     in order to not lose signals sent to the thread that hit the
	     breakpoint.  Unfortunately this increases the window where another
	     thread could sneak past the removed breakpoint.  For the current
	     use of server-side breakpoints (thread creation) this is
	     acceptable; but it needs to be considered before this breakpoint
	     mechanism can be used in more general ways.  For some breakpoints
	     it may be necessary to stop all other threads, but that should
	     be avoided where possible.

	     If breakpoint_reinsert_addr is NULL, that means that we can
	     use PT_STEP on this platform.  Uninsert the breakpoint,
	     mark it for reinsertion, and single-step.

	     Otherwise, call the target function to figure out where we need
	     our temporary breakpoint, create it, and continue executing this
	     process.  */
	  if (the_low_target.breakpoint_reinsert_addr == NULL)
	    {
	      event_child->bp_reinsert = stop_pc;
	      uninsert_breakpoint (stop_pc);
	      fbsd_resume_one_process (&event_child->head, 1, 0);
	    }
	  else
	    {
	      reinsert_breakpoint_by_bp
		(stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
	      fbsd_resume_one_process (&event_child->head, 0, 0);
	    }

	  continue;
	}

      /* If we were single-stepping, we definitely want to report the
	 SIGTRAP.  The single-step operation has completed, so also
         clear the stepping flag; in general this does not matter,
	 because the SIGTRAP will be reported to the client, which
	 will give us a new action for this thread, but clear it for
	 consistency anyway.  It's safe to clear the stepping flag
         because the only consumer of get_stop_pc () after this point
	 is check_removed_breakpoint, and pending_is_breakpoint is not
	 set.  It might be wiser to use a step_completed flag instead.  */
      if (event_child->stepping)
	{
	  event_child->stepping = 0;
	  return wstat;
	}

      /* A SIGTRAP that we can't explain.  It may have been a breakpoint.
	 Check if it is a breakpoint, and if so mark the process information
	 accordingly.  This will handle both the necessary fiddling with the
	 PC on decr_pc_after_break targets and suppressing extra threads
	 hitting a breakpoint if two hit it at once and then GDB removes it
	 after the first is reported.  Arguably it would be better to report
	 multiple threads hitting breakpoints simultaneously, but the current
	 remote protocol does not allow this.  */
      if ((*the_low_target.breakpoint_at) (stop_pc))
	{
	  event_child->pending_is_breakpoint = 1;
	  event_child->pending_stop_pc = stop_pc;
	}

      return wstat;
    }

  /* NOTREACHED */
  return 0;
}
Ejemplo n.º 14
0
static ptid_t
lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
{
  int pid;
  int ret;
  int wstat;
  ptid_t new_ptid;

  if (ptid_equal (ptid, minus_one_ptid))
    pid = lynx_ptid_get_pid (thread_to_gdb_id (current_thread));
  else
    pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));

retry:

  ret = lynx_waitpid (pid, &wstat);
  new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
  find_process_pid (ret)->priv->last_wait_event_ptid = new_ptid;

  /* If this is a new thread, then add it now.  The reason why we do
     this here instead of when handling new-thread events is because
     we need to add the thread associated to the "main" thread - even
     for non-threaded applications where the new-thread events are not
     generated.  */
  if (!find_thread_ptid (new_ptid))
    {
      lynx_debug ("New thread: (pid = %d, tid = %d)",
		  lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
      add_thread (new_ptid, NULL);
    }

  if (WIFSTOPPED (wstat))
    {
      status->kind = TARGET_WAITKIND_STOPPED;
      status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat));
      lynx_debug ("process stopped with signal: %d",
                  status->value.integer);
    }
  else if (WIFEXITED (wstat))
    {
      status->kind = TARGET_WAITKIND_EXITED;
      status->value.integer = WEXITSTATUS (wstat);
      lynx_debug ("process exited with code: %d", status->value.integer);
    }
  else if (WIFSIGNALED (wstat))
    {
      status->kind = TARGET_WAITKIND_SIGNALLED;
      status->value.integer = gdb_signal_from_host (WTERMSIG (wstat));
      lynx_debug ("process terminated with code: %d",
                  status->value.integer);
    }
  else
    {
      /* Not sure what happened if we get here, or whether we can
	 in fact get here.  But if we do, handle the event the best
	 we can.  */
      status->kind = TARGET_WAITKIND_STOPPED;
      status->value.integer = gdb_signal_from_host (0);
      lynx_debug ("unknown event ????");
    }

  /* SIGTRAP events are generated for situations other than single-step/
     breakpoint events (Eg. new-thread events).  Handle those other types
     of events, and resume the execution if necessary.  */
  if (status->kind == TARGET_WAITKIND_STOPPED
      && status->value.integer == GDB_SIGNAL_TRAP)
    {
      const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);

      lynx_debug ("(realsig = %d)", realsig);
      switch (realsig)
	{
	  case SIGNEWTHREAD:
	    /* We just added the new thread above.  No need to do anything
	       further.  Just resume the execution again.  */
	    lynx_continue (new_ptid);
	    goto retry;

	  case SIGTHREADEXIT:
	    remove_thread (find_thread_ptid (new_ptid));
	    lynx_continue (new_ptid);
	    goto retry;
	}
    }

  return new_ptid;
}
Ejemplo n.º 15
0
UDTPPeer::~UDTPPeer()
{
    while(remove_thread()); /*Removes all flow threads!*/
    _udtp = NULL;
}
Ejemplo n.º 16
0
void thread_exit(void)
{
    remove_thread(THREAD_ID_CURRENT);
}