Пример #1
0
static void thread_unblock_mutex(ThreadId tid, struct mutex *mx, const Char *action)
{
   struct thread *th = thread_get(tid);

   if (th == NULL) {
      /* should an unknown thread doing something make it spring to life? */
      thread_report(tid, THE_NotExist, "giving up on mutex");
      return;
   }

   switch(th->state) {
   case TS_MutexBlocked:	/* OK */
      break;

   case TS_Alive:
   case TS_Running:
      thread_report(tid, THE_NotBlocked, action);
      break;

   case TS_CVBlocked:
   case TS_JoinBlocked:
      thread_report(tid, THE_Blocked, action);
      break;

   case TS_Dead:
   case TS_Zombie:
      thread_report(tid, THE_NotAlive, action);
      break;
   }

   do_thread_run(th);
}
Пример #2
0
static void thread_block_mutex(ThreadId tid, struct mutex *mx)
{
   struct thread *th = thread_get(tid);

   if (th == NULL) {
      /* should an unknown thread doing something make it spring to life? */
      thread_report(tid, THE_NotExist, "blocking on mutex");
      return;
   }
   switch(th->state) {
   case TS_Dead:
   case TS_Zombie:
      thread_report(th->tid, THE_NotAlive, "blocking on mutex");
      break;

   case TS_MutexBlocked:
   case TS_CVBlocked:
   case TS_JoinBlocked:
      thread_report(th->tid, THE_Blocked, "blocking on mutex");
      break;

   case TS_Alive:
   case TS_Running:		/* OK */
      break;
   }

   do_thread_block_mutex(th, mx);
}
Пример #3
0
/* Finish unlocking a Mutex.  The mutex can validly be in one of three
   states:
   - Unlocking
   - Locked, owned by someone else (someone else got it in the meantime)
   - Free (someone else completed a lock-unlock cycle)
 */
void VG_(tm_mutex_unlock)(ThreadId tid, Addr mutexp)
{
   struct mutex *mx;
   struct thread *th;

   mx = mutex_check_initialized(tid, mutexp, "unlocking mutex");

   th = thread_get(tid);

   if (th == NULL)
      thread_report(tid, THE_NotExist, "unlocking mutex");
   else {
      switch(th->state) {
      case TS_Alive:
      case TS_Running:		/* OK */
	 break;

      case TS_Dead:
      case TS_Zombie:
	 thread_report(tid, THE_NotAlive, "unlocking mutex");
	 break;

      case TS_JoinBlocked:
      case TS_CVBlocked:
      case TS_MutexBlocked:
	 thread_report(tid, THE_Blocked, "unlocking mutex");
	 do_thread_run(th);
	 break;
      }
   }

   switch(mx->state) {
   case MX_Locked:
      /* Someone else might have taken ownership in the meantime */
      if (mx->owner == tid)
	 mutex_report(tid, mutexp, MXE_Locked, "unlocking");
      break;

   case MX_Free:
      /* OK - nothing to do */
      break;

   case MX_Unlocking:
      /* OK - we need to complete the unlock */
      VG_TRACK( post_mutex_unlock, tid, (void *)mutexp );
      mutex_setstate(tid, mx, MX_Free);
      break;

   case MX_Init:
   case MX_Dead:
      vg_assert(0);
   }
}
Пример #4
0
/* Try unlocking a lock.  This will move it into a state where it can
   either be unlocked, or change ownership to another thread.  If
   unlock fails, it will remain locked. */
void VG_(tm_mutex_tryunlock)(ThreadId tid, Addr mutexp)
{
   struct thread *th;
   struct mutex *mx;

   mx = mutex_check_initialized(tid, mutexp, "try-unlocking");

   th = thread_get(tid);

   if (th == NULL)
      thread_report(tid, THE_NotExist, "try-unlocking mutex");
   else {
      switch(th->state) {
      case TS_Alive:
      case TS_Running:		/* OK */
	 break;

      case TS_Dead:
      case TS_Zombie:
	 thread_report(tid, THE_NotAlive, "try-unlocking mutex");
	 break;

      case TS_JoinBlocked:
      case TS_CVBlocked:
      case TS_MutexBlocked:
	 thread_report(tid, THE_Blocked, "try-unlocking mutex");
	 do_thread_run(th);
	 break;
      }
   }

   switch(mx->state) {
   case MX_Locked:
      if (mx->owner != tid)
	 mutex_report(tid, mutexp, MXE_NotOwner, "try-unlocking");
      break;

   case MX_Free:
      mutex_report(tid, mutexp, MXE_NotLocked, "try-unlocking");
      break;

   case MX_Unlocking:
      mutex_report(tid, mutexp, MXE_NotLocked, "try-unlocking");
      break;

   case MX_Init:
   case MX_Dead:
      vg_assert(0);
   }

   mutex_setstate(tid, mx, MX_Unlocking);
}
Пример #5
0
void VG_(tm_thread_detach)(ThreadId tid)
{
   struct thread *th = thread_get(tid);

   if (th == NULL)
      thread_report(tid, THE_NotExist, "detaching");
   else {
      if (th->detached)
	 thread_report(tid, THE_Detached, "detaching");
      else {
	 /* XXX look for waiters */
	 th->detached = True;
      }
   }
}
Пример #6
0
/* A thread is terminating itself
    - fails if tid has already terminated
    - if detached, tid becomes invalid for all further operations
    - if not detached, the thread remains in a Zombie state until
      someone joins on it
 */
void VG_(tm_thread_exit)(ThreadId tid)
{
   struct thread *th = thread_get(tid);

   if (th == NULL)
      thread_report(tid, THE_NotExist, "exiting");
   else {
      struct thread *joiner;

      switch(th->state) {
      case TS_Dead:
      case TS_Zombie:	/* already exited once */
	 thread_report(tid, THE_NotAlive, "exiting");
	 break;

      case TS_MutexBlocked:
      case TS_CVBlocked:
      case TS_JoinBlocked:
	    thread_report(tid, THE_Blocked, "exiting");
	    break;

      case TS_Alive:
      case TS_Running:
	 /* OK */
	 break;
      }

      /* ugly - walk all threads to find people joining with us */
      /* In pthreads its an error to have multiple joiners, but that
	 seems a bit specific to implement here; there should a way
	 for the thread library binding to handle this. */
      VG_(OSet_ResetIter)(threadSet);
      while ((joiner = VG_(OSet_Next)(threadSet)) != NULL) {
	 if (joiner->state == TS_JoinBlocked && joiner->th_blocked == th) {
	    /* found someone - wake them up */
	    do_thread_run(joiner);

	    /* we're dead */
	    do_thread_dead(th);
	 }
      }

      if (th->state != TS_Dead)
	 do_thread_block_zombie(th);
   }
}
Пример #7
0
/* Thread creation */
void VG_(tm_thread_create)(ThreadId creator, ThreadId tid, Bool detached)
{
   struct thread *th = thread_get(tid);

   if (debug_thread)
      VG_(printf)("thread %d creates %d %s\n", creator, tid, detached ? "detached" : "");
   if (th != NULL) {
      if (th->state != TS_Dead)
	 thread_report(tid, THE_Rebirth, "creating");
   } else {
      th = VG_(OSet_AllocNode)(threadSet, sizeof(struct thread));
      th->tid = tid;
      VG_(OSet_Insert)(threadSet, th);
   }

   th->creator = creator;
   th->detached = detached;
   th->mx_blocked = NULL;
   th->cv_blocked = NULL;
   th->th_blocked = NULL;

   thread_setstate(th, TS_Alive);
   do_thread_run(th);
}
void threadProcess(
	std::string iFileDir, 
	std::string oFileDir, 
	FIFO<int>& module_list, 
	int threadID)
{
	while(1)
	{
		// get next module for process or exit if done.
		int module_number;
		try {
			module_number = module_list.pop();
			std:: stringstream report;
			report << "Stating module " << module_number;
			thread_report(report.str(),threadID);
		}catch(std::string i) {
			thread_report("Terminating",threadID);
			return;
		}

		std::array<FIFO<std::string>,12> asicData; //stores the data from the asic asicData[asicID][SPP]
		FIFO<std::string> side1, side2;

		for(int i(0); i < 12; i++)
		{
			std::stringstream filename;
			filename << iFileDir << "/timesync" << module_number*12 + i << ".txt";
			std::ifstream iFile(filename.str());
			std::string tempIn;

			while(iFile >> tempIn)
			{
				if (atoi(tempIn.c_str()) == 0) continue;
				asicData[i].store(tempIn);
			}
		}

		bool complete = false;
		bool next_bcid = true;
		int bcid = 0;
		while(!complete)
		{
			for (int i(0); i < 12; i++)
				if(!asicData[i].is_empty()){
					if(get_bcid(asicData[i].peek()) == bcid){
						if (i < 3 || i >= 9)
							side1.store(asicData[i].pop());
						else
							side2.store(asicData[i].pop());
						next_bcid = false;
					}
				}

			complete = true;
			for (auto& asic : asicData) if (!asic.is_empty()) complete = false;
			if (next_bcid) if (++bcid >= 512) bcid = 0;
			next_bcid = true;
		}

		std::stringstream outFileName1;
		outFileName1 << oFileDir << "/module_" << module_number << "_";
		std::stringstream outFileName2;
		outFileName2 << outFileName1.str(); //shits and giggles
		outFileName1 << 1 << ".txt";
		outFileName2 << 2 << ".txt";

		std::ofstream oFile1(outFileName1.str());
		std::ofstream oFile2(outFileName2.str());

		thread_report("Writing to file",threadID);
		while(!side1.is_empty())
			oFile1 << side1.pop() << '\n';

		while(!side2.is_empty())
			oFile2 << side2.pop() << '\n';
	}
}
Пример #9
0
/* One thread blocks until another has terminated
    - fails if joinee is detached
    - fails if joinee doesn't exist
    - once the join completes, joinee is dead
 */
void VG_(tm_thread_join)(ThreadId joinerid, ThreadId joineeid)
{
   struct thread *joiner = thread_get(joinerid);
   struct thread *joinee = thread_get(joineeid);

   /* First, check the joinee thread's state */
   if (joinee == NULL)
      thread_report(joineeid, THE_NotExist, "joining as joinee");
   else {
      switch(joinee->state) {
      case TS_Alive:		/* really shouldn't see them in this state... */
      case TS_Running:
      case TS_Zombie:
      case TS_MutexBlocked:
      case TS_CVBlocked:
      case TS_JoinBlocked:
	 /* OK */
	 break;

      case TS_Dead:
	 thread_report(joineeid, THE_NotAlive, "joining as joinee");
	 break;
      }
   }

   /* now the joiner... */
   if (joiner == NULL)
      thread_report(joineeid, THE_NotExist, "joining as joiner");
   else {
      switch(joiner->state) {
      case TS_Alive:		/* ? */
      case TS_Running:		/* OK */
	 break;

      case TS_Zombie:		/* back from the dead */
      case TS_Dead:
	 thread_report(joineeid, THE_NotAlive, "joining as joiner");
	 break;

      case TS_MutexBlocked:
      case TS_CVBlocked:
      case TS_JoinBlocked:
	 thread_report(joineeid, THE_Blocked, "joining as joiner");
	 break;
      }

      if (joinee->detached)
	 thread_report(joineeid, THE_Detached, "joining as joiner");
      else {
	 /* block if the joinee hasn't exited yet */
	 if (joinee) {
	    switch(joinee->state) {
	    case TS_Dead:
	       break;

	    default:
	       if (joinee->state == TS_Zombie)
		  do_thread_dead(joinee);
	       else
		  do_thread_block_join(joiner, joinee);
	    }
	 }
      }
   }
}