Example #1
0
void Dispatcher(){
	MEMORY_MAPPED_IO mmio;
	struct ready_PCB *runningPCB;
	int runnningPID;

//	runningPcb = FindCurrent(runningProcessPid);

	runningPCB=Get_R_Head();
	while(runningPCB==NULL) {

//		if(GetHead(&pcb_timer_queue)!= NULL || GetHead(&pcb_disk_queue!=NULL)) {
//			mmio.Mode=Z502Action;
//			mmio.Field1=mmio.Field2=mmio.Field3=0;
//			MEM_WRITE(Z502Idle, &mmio);
//
//		}
		CALL(WasteTime());
	}
	//pcb not null, start PCB if pcb is null call idle

	    runnningPID = runningPCB->pid;
	    Queue_R_Dequeue();

		mmio.Mode = Z502StartContext;
		mmio.Field1 =runningPCB->context.Field1;
		mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND;
		MEM_WRITE(Z502Context, &mmio);


}
Example #2
0
bool SoundCardPMO::WaitForDrain(void)
{
   unsigned iLoop, iNumHeadersPending = 0;

   for(; !m_bExit && !m_bPause; )
   {   
       g_pHeaderMutex->Acquire();

       for(iLoop = 0, iNumHeadersPending = 0; iLoop < m_num_headers; iLoop++)
       {
           if ((int)m_wavehdr_array[iLoop].dwUser > 0)
               iNumHeadersPending++;
       }
       g_pHeaderMutex->Release();
   
       if (iNumHeadersPending == 0)
       {
          return true;
       }
       WasteTime();
       HandleTimeInfoEvent(NULL);
   }

   return false;
}
Example #3
0
File: TEST.C Project: FDOS/defrag
int main()
{
   time_t t1, t2;
   time(&t1);    

   WasteTime(19);

   time(&t2);

   printf("%u", t2-t1);
}
Example #4
0
// PORTING: This function returns when the sound card is done playing, or
// when exit or pause is signaled. Returns true if the card naturally ran
// out of things to play. False if m_bExit or m_bPause became true
bool SoundCardPMO::WaitForDrain(void)
{
   struct audio_info info;

   for(; !m_bExit && !m_bPause; )
   {
       ioctl(audio_fd, AUDIO_GETINFO, &info);
       if (info.play.error)
       {
           return true;
       }
       WasteTime();
   }
   return false;
}
Example #5
0
bool AlsaPMO::WaitForDrain(void)
{
   snd_pcm_channel_status_t ainfo;

   for(; !m_bExit && !m_bPause; )
   {
       ainfo.channel = SND_PCM_CHANNEL_PLAYBACK;
       snd_pcm_channel_status(m_handle,&ainfo);

       if (ainfo.underrun || ainfo.status == SND_PCM_STATUS_UNDERRUN)
       {
           return true;
       }
       WasteTime();
   }

   return false;
} 
Example #6
0
void AlsaPMO::WorkerThread(void)
{
   void                      *pBuffer;
   Error                      eErr;
   int                        iRet = -1;
   Event                     *pEvent;
   snd_pcm_channel_status_t  ainfo;

   // Don't do anything until resume is called.
   m_pPauseSem->Wait();

   // Sleep for a pre buffer period
   PreBuffer();

   // The following should be abstracted out into the general thread
   // classes:
#ifdef __linux__
   struct sched_param sParam;

   sParam.sched_priority = sched_get_priority_max(SCHED_OTHER);
   pthread_setschedparam(pthread_self(), SCHED_OTHER, &sParam);
#endif

   ainfo.channel = SND_PCM_CHANNEL_PLAYBACK;
   for(; !m_bExit;)
   {
      if (m_bPause)
      {
          m_pPauseSem->Wait();
          continue;
      }

      // Loop until we get an Init event from the LMC
      if (!m_properlyInitialized)
      {
          pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

          if (pEvent == NULL)
          {
              m_pLmc->Wake();
              WasteTime();

              continue;
          }

          if (pEvent->Type() == PMO_Init)
          {
              if (IsError(Init(((PMOInitEvent *)pEvent)->GetInfo())))
              {
                  delete pEvent;
                  break;
              }
          }
          delete pEvent;

          continue;
      }

      // Set up reading a block from the buffer. If not enough bytes are
      // available, sleep for a little while and try again.
      for(;;)
      {
          eErr = ((EventBuffer *)m_pInputBuffer)->BeginRead(pBuffer, 
                                                             m_iDataSize);
          if (eErr == kError_EndOfStream || eErr == kError_Interrupt)
             break;

          if (eErr == kError_NoDataAvail)
          {
              m_pLmc->Wake();
              CheckForBufferUp();

              WasteTime();
              continue;
          }

          // Is there an event pending that we need to take care of
          // before we play this block of samples?
          if (eErr == kError_EventPending)
          {
              pEvent = ((EventBuffer *)m_pInputBuffer)->PeekEvent();
			  if (pEvent == NULL)
				  continue;
                  
              if (pEvent->Type() == PMO_Quit && 
                  ((EventBuffer *)m_pInputBuffer)->GetNumBytesInBuffer() > 0) 
              {
                  if (WaitForDrain())
				  {
                     Reset(true);
                     m_pTarget->AcceptEvent(new Event(INFO_DoneOutputting));
                     return;
				  }
                  continue;
              }
              
              pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

              if (pEvent->Type() == PMO_Init)
                  Init(((PMOInitEvent *)pEvent)->GetInfo());
    
              if (pEvent->Type() == PMO_Reset)
                  Reset(false);
    
              if (pEvent->Type() == PMO_Info) 
                  HandleTimeInfoEvent((PMOTimeInfoEvent *)pEvent);
    
              if (pEvent->Type() == PMO_Quit) 
              {
                  delete pEvent;
                  m_pTarget->AcceptEvent(new Event(INFO_DoneOutputting));
                  return;
              }
 
              delete pEvent;
    
              continue;
          }
          
          if (IsError(eErr))
          {
              ReportError("Internal error occured.");
              m_pContext->log->Error("Cannot read from buffer in PMO "
                                    "worker tread: %d\n", eErr);
              break;
          }
          break;
      }

      // Now write the block to the audio device. If the block doesn't
      // all fit, pause and loop until the entire block has been played.
      // This loop could be written using non-blocking io...
      for(;!m_bExit && !m_bPause;)
      {
          iRet = snd_pcm_write(m_handle,pBuffer,m_iDataSize);
          if (iRet == -EAGAIN)
          {
               CheckForBufferUp();
               WasteTime();
               continue;
          }
          if (iRet == -EIO)
          {
               snd_pcm_channel_prepare(m_handle, SND_PCM_CHANNEL_PLAYBACK);
               continue;
          }
          break;
      }
      if (m_bExit)
      {
          m_pInputBuffer->EndRead(0);
          return;
      }

      if (m_bPause)
      {
         if (iRet == -EAGAIN)
             m_pInputBuffer->EndRead(0);
         else
         {
             m_pInputBuffer->EndRead(iRet);
             UpdateBufferStatus();
         }
         continue;   
      }

      if (iRet < 0)
      {
         m_pInputBuffer->EndRead(0);
         ReportError("Could not write sound data to the soundcard.");
         m_pContext->log->Error("Failed to write to the soundcard: %s\n", 
                               strerror(errno));
         break;
      }

      m_pInputBuffer->EndRead(iRet);
      m_pLmc->Wake();
      UpdateBufferStatus();
   }
}
Example #7
0
void SoundCardPMO::WorkerThread(void)
{
   void       *pBuffer;
   Error       eErr;
   size_t      iRet;
   Event      *pEvent;
   //   audio_info info;
   bool        bPerfWarn = false;

   // Don't do anything until resume is called.
   m_pPauseSem->Wait();

   // Wait a specified prebuffer time... 
   PreBuffer();

   // The following should be abstracted out into the general thread
   // classes:
#ifdef __linux__
   struct sched_param sParam;

   sParam.sched_priority = sched_get_priority_max(SCHED_OTHER);
   pthread_setschedparam(pthread_self(), SCHED_OTHER, &sParam);
#endif

   for(; !m_bExit;)
   {
      if (m_bPause)
      {
          m_pPauseSem->Wait();
          continue;
      }

      // Loop until we get an Init event from the LMC
      if (!m_properlyInitialized)
      {
          pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

          if (pEvent == NULL)
          {
              m_pLmc->Wake();
              WasteTime();

              continue;
          }

          if (pEvent->Type() == PMO_Init)
          {
              if (IsError(Init(((PMOInitEvent *)pEvent)->GetInfo())))
              {
                  delete pEvent;
                  break;
              }
          }
          delete pEvent;

          continue;
      }

      // Set up reading a block from the buffer. If not enough bytes are
      // available, sleep for a little while and try again.
      for(;;)
      {
          eErr = ((EventBuffer *)m_pInputBuffer)->BeginRead(pBuffer, 
                                                             m_iDataSize);
          if (eErr == kError_EndOfStream || eErr == kError_Interrupt)
             break;

          if (eErr == kError_NoDataAvail)
          {
              m_pLmc->Wake();

              if (!bPerfWarn)
              {
                  time_t t;
    
                  time(&t);
                  m_pContext->log->Log(LogPerf, "Output buffer underflow: %s", 
                             ctime(&t));
                  bPerfWarn = true;
              }
    
              WasteTime();
              continue;
          }

          // Is there an event pending that we need to take care of
          // before we play this block of samples?
          if (eErr == kError_EventPending)
          {
              pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

              if (pEvent->Type() == PMO_Init)
                  Init(((PMOInitEvent *)pEvent)->GetInfo());
    
              if (pEvent->Type() == PMO_Reset)
                  Reset(false);
    
              if (pEvent->Type() == PMO_Info) 
                  HandleTimeInfoEvent((PMOTimeInfoEvent *)pEvent);
    
              if (pEvent->Type() == PMO_Quit) 
              {
                  delete pEvent;
                  if (WaitForDrain())
                     m_pTarget->AcceptEvent(new Event(INFO_DoneOutputting));

                  return;
              }
 
              delete pEvent;
    
              continue;
          }
          
          if (IsError(eErr))
          {
              ReportError("Internal error occured.");
              m_pContext->log->Error("Cannot read from buffer in PMO "
                                    "worker tread: %d\n", eErr);
              break;
          }
          bPerfWarn = false;
          break;
      }

      // Now write the block to the audio device. If the block doesn't
      // all fit, pause and loop until the entire block has been played.
      // This loop could be written using non-blocking io...
      for(;;)
      {
          if (m_bExit || m_bPause)
              break;

	  //          ioctl(audio_fd, AUDIO_GETINFO, &info);
          if (0) //((unsigned)(info.fragments * info.fragsize) < m_iDataSize)
          {
              WasteTime();
              continue;
          }
          break;
      }        
      if (m_bExit || m_bPause)
      {
          m_pInputBuffer->EndRead(0);
          continue;
      }

      iRet = write(audio_fd, pBuffer, m_iDataSize);
      // write(audio_fd, pBuffer, 0); // for WaitForDrain(), maybe?
      if (iRet < 0)
      {
         m_pInputBuffer->EndRead(0);
         ReportError("Could not write sound data to the soundcard.");
         m_pContext->log->Error("Failed to write to the soundcard: %s\n", 
                               strerror(errno));
         break;
      }

      m_iTotalBytesWritten += iRet;
      m_pInputBuffer->EndRead(iRet);
      m_pLmc->Wake();
      UpdateBufferStatus();
   }
}
Example #8
0
void svc(SYSTEM_CALL_DATA *SystemCallData) {
	short call_type;
	static short do_print = 10;
	short i;
	INT32 Time;
	int Status;
	void *PageTable;
	char* processName;

	MEMORY_MAPPED_IO mmio;
	call_type = (short) SystemCallData->SystemCallNumber;

	if (do_print > 0) {
		printf("SVC handler: %s\n", call_names[call_type]);
		for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++) {
			//Value = (long)*SystemCallData->Argument[i];
			printf("Arg %d: Contents = (Decimal) %8ld,  (Hex) %8lX\n", i,
					(unsigned long) SystemCallData->Argument[i],
					(unsigned long) SystemCallData->Argument[i]);
		}
		do_print--;
	}

//	printf((char *) SystemCallData->Argument[i]);
	switch (call_type) {
	//get time service call
	case SYSNUM_GET_TIME_OF_DAY:
		mmio.Mode = Z502ReturnValue;
		mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
		MEM_READ(Z502Clock, &mmio);
		*(long *) SystemCallData->Argument[0] = mmio.Field1;
		break;
		//system sleep call
	case SYSNUM_SLEEP:

		mmio.Mode = Z502ReturnValue;
		mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
		MEM_READ(Z502Clock, &mmio);

		Time = (long) SystemCallData->Argument[0];

		pcb = FindCurrent(runningProcessPid);
		pcb->wakeUpTimer = Time;
		EnTimerQueue(&pcb_timer_queue, pcb);

		//start timer

		headPCB = GetHead(&pcb_timer_queue)->data;
		if (pcb == headPCB) {
			mmio.Mode = Z502Start;
			mmio.Field1 = (long) SystemCallData->Argument[0];
			mmio.Field2 = mmio.Field3 = 0;
			MEM_WRITE(Z502Timer, &mmio);
		}

		Dispatcher();

		break;
		//system create process
	case SYSNUM_CREATE_PROCESS:
		if ((long) SystemCallData->Argument[2] < 0) {
			*SystemCallData->Argument[4] = ERR_BAD_PARAM;
		} else {
			PageTable = (void *) calloc(2, NUMBER_VIRTUAL_PAGES);
			mmio.Mode = Z502InitializeContext;
			mmio.Field1 = 0;
			mmio.Field2 = (long) SystemCallData->Argument[1];
			mmio.Field3 = (long) PageTable;
			MEM_WRITE(Z502Context, &mmio);
			pcb = OSCreateProcess((char*) SystemCallData->Argument[0],
					(long) mmio.Field1, (long) SystemCallData->Argument[2],
					(long) SystemCallData->Argument[3],
					(long) SystemCallData->Argument[4]);
			if (pcb != NULL) {
				EnQueue(&pcb_ready_queue, (void*) pcb);
				*SystemCallData->Argument[3] = pcb->pid;
				*SystemCallData->Argument[4] = ERR_SUCCESS;
			} else {
				*SystemCallData->Argument[4] = ERR_BAD_PARAM;
			}
		}
		break;
		//system get process id

	case SYSNUM_GET_PROCESS_ID:
		processName = (char*) SystemCallData->Argument[0];
		if (strlen(processName) == 0) {
			*SystemCallData->Argument[1] = runningProcessPid;
			*SystemCallData->Argument[2] = ERR_SUCCESS;
		} else {
			pcb = FindPCBByName(processName);

		}
		if (pcb != NULL) {
			*SystemCallData->Argument[1] = pcb->pid;
			*SystemCallData->Argument[2] = ERR_SUCCESS;
		} else {
			*SystemCallData->Argument[2] = ERR_BAD_PARAM;
		}
		break;

	case SYSNUM_PHYSICAL_DISK_READ:
		do {
			mmio.Mode = Z502Status;
			mmio.Field1 = (long) SystemCallData->Argument[0];
			mmio.Field2 = mmio.Field3 = 0;
			MEM_READ(Z502Disk, &mmio);
			CALL(WasteTime());
		} while (mmio.Field2 != DEVICE_FREE);

		pcb = FindCurrent(runningProcessPid);
		if (pcb != NULL) {
			pcb->diskID = (int) SystemCallData->Argument[0];
			pcb->sectorID = (int) SystemCallData->Argument[1];
			pcb->memoryBuffer = (void*) SystemCallData->Argument[2];
			EnQueue(&(pcb_disk_queue[pcb->diskID]), (void*) pcb);
		}

		mmio.Mode = Z502DiskRead;
		mmio.Field1 = (long) SystemCallData->Argument[0];
		mmio.Field2 = (long) SystemCallData->Argument[1];
		mmio.Field3 = (long) SystemCallData->Argument[2];
		mmio.Field4 = 0;
		MEM_READ(Z502Disk, &mmio);

		do {
			mmio.Mode = Z502Status;
			mmio.Field1 = (long) SystemCallData->Argument[0];
			mmio.Field2 = mmio.Field3 = 0;
			MEM_READ(Z502Disk, &mmio);
			CALL(WasteTime());
		} while (mmio.Field2 != DEVICE_FREE);

		Dispatcher();

		break;
	case SYSNUM_PHYSICAL_DISK_WRITE:
		do {
			mmio.Mode = Z502Status;
			mmio.Field1 = (long) SystemCallData->Argument[0];
			mmio.Field2 = mmio.Field3 = 0;
			MEM_READ(Z502Disk, &mmio);
			CALL(WasteTime());
		} while (mmio.Field2 != DEVICE_FREE);

		pcb = FindCurrent(runningProcessPid);
		if (pcb != NULL) {
			pcb->diskID = (int) SystemCallData->Argument[0];
			pcb->sectorID = (int) SystemCallData->Argument[1];
			pcb->memoryBuffer = (void*) SystemCallData->Argument[2];
			EnQueue(&(pcb_disk_queue[pcb->diskID]), (void*) pcb);
		}

		mmio.Mode = Z502DiskWrite;
		mmio.Field1 = (long) SystemCallData->Argument[0];
		mmio.Field2 = (long) SystemCallData->Argument[1];
		mmio.Field3 = (long) SystemCallData->Argument[2];
		MEM_WRITE(Z502Disk, &mmio);

//		mmio.Mode = Z502Action;
//		mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
//		MEM_WRITE(Z502Idle, &mmio);
		do {
			mmio.Mode = Z502Status;
			mmio.Field1 = (long) SystemCallData->Argument[0];
			mmio.Field2 = mmio.Field3 = 0;
			MEM_READ(Z502Disk, &mmio);
			CALL(WasteTime());
		} while (mmio.Field2 != DEVICE_FREE);
		Dispatcher();
		break;

		//system terminate call
	case SYSNUM_TERMINATE_PROCESS:
		//If ProcessID = -1, then terminate self
		if ((long) SystemCallData->Argument[0] == -1) {
			pcb = FindCurrent(runningProcessPid);
			if (pcb != NULL) {
//				ReleasePCB();
//				RemovePCB(&pcb_ready_queue,(void*)pcb);
//				RemovePCB(&pcb_timer_queue,(void*)pcb);
//				*SystemCallData->Argument[1] = ERR_SUCCESS;
				if (pcb_ready_queue.size == 0 && pcb_timer_queue.size == 0) {
					mmio.Mode = Z502ReturnValue;
					mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0;
					MEM_WRITE(Z502Halt, &mmio);
					*SystemCallData->Argument[1] = ERR_SUCCESS;
				} else {
					Dispatcher();
				}
			} else {
				ReleasePCB();
				mmio.Mode = Z502ReturnValue;
				mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0;
				MEM_WRITE(Z502Halt, &mmio);
				*SystemCallData->Argument[1] = ERR_SUCCESS;
			}

		} else if ((long) SystemCallData->Argument[0] == -2) {
			// terminite all halt
			ReleasePCB();
			mmio.Mode = Z502ReturnValue;
			mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0;
			MEM_WRITE(Z502Halt, &mmio);
			*SystemCallData->Argument[1] = ERR_SUCCESS;
//			pcb = FindCurrent(runningProcessPid);
//			RemovePCB(&pcb_ready_queue, (void*) pcb);
//			RemovePCB(&pcb_timer_queue, (void*) pcb);
//			RemovePCB(&pcb_ready_queue, (void*) pcb->childProcesses);
//			RemovePCB(&pcb_timer_queue, (void*) pcb->childProcesses);

		} else {
			pcb = FindPCBByPID(SystemCallData->Argument[0]);
			RemovePCB(&pcb_ready_queue, (void*) pcb);
			*SystemCallData->Argument[1] = ERR_SUCCESS;

		}
		break;
		defaut: printf("ERROR! call_type not recognized!\n");
		printf("Call_type is %i\n", call_type);
	}
}                                               // End of svc
Example #9
0
void SoundCardPMO::WorkerThread(void)
{
   void       *pBuffer;
   Error       eErr;
   size_t      iRet;
   Event      *pEvent;
   audio_buf_info info;
   bool        bPerfWarn = false;

   // Don't do anything until resume is called.
   m_pPauseSem->Wait();

   //CheckForBufferUp();

   // Wait a specified prebuffer time...
   PreBuffer();

   for(; !m_bExit;)
   {
      if (m_bPause)
      {
          m_pPauseSem->Wait();
          continue;
      }

      // Loop until we get an Init event from the LMC
      if (!m_properlyInitialized)
      {
          pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

          if (pEvent == NULL)
          {
              m_pLmc->Wake();
              WasteTime();

              continue;
          }

          if (pEvent->Type() == PMO_Init)
          {
              if (IsError(Init(((PMOInitEvent *)pEvent)->GetInfo())))
              {
                  delete pEvent;
                  break;
              }
          }
          delete pEvent;
          continue;
      }

      // Set up reading a block from the buffer. If not enough bytes are
      // available, sleep for a little while and try again.
      for(;;)
      {
          eErr = ((EventBuffer *)m_pInputBuffer)->BeginRead(pBuffer, 
                                                             m_iDataSize);
          if (eErr == kError_EndOfStream || eErr == kError_Interrupt)
             break;

          if (eErr == kError_NoDataAvail)
          {
              m_pLmc->Wake();
              CheckForBufferUp();

              if (!bPerfWarn)
              {
                  time_t t;
    
                  time(&t);
                  m_pContext->log->Log(LogPerf, "Output buffer underflow: %s", 
                             ctime(&t));
                  bPerfWarn = true;
              }
    
              WasteTime();
              continue;
          }

          // Is there an event pending that we need to take care of
          // before we play this block of samples?
          if (eErr == kError_EventPending)
          {
              pEvent = ((EventBuffer *)m_pInputBuffer)->PeekEvent();
              if (pEvent == NULL)
                  continue;

              if (pEvent->Type() == PMO_Quit &&
                  ((EventBuffer *)m_pInputBuffer)->GetNumBytesInBuffer() > 0)
              {
                  if (WaitForDrain())
                  {
                     m_pTarget->AcceptEvent(new Event(INFO_DoneOutputting));
                     return;
                  }
                  continue;
              }  

              pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent();

              if (pEvent->Type() == PMO_Init)
                  Init(((PMOInitEvent *)pEvent)->GetInfo());
    
              if (pEvent->Type() == PMO_Reset)
                  Reset(false);
    
              if (pEvent->Type() == PMO_Info) 
                  HandleTimeInfoEvent((PMOTimeInfoEvent *)pEvent);

              if (pEvent->Type() == PMO_Quit) 
              {
                  delete pEvent;
                  m_pTarget->AcceptEvent(new Event(INFO_DoneOutputting));
                  return;
              }
 
              delete pEvent;
    
              continue;
          }
          
          if (IsError(eErr))
          {
              ReportError("Internal error occured.");
              m_pContext->log->Error("Cannot read from buffer in PMO "
                                    "worker tread: %d\n", eErr);
              break;
          }
          bPerfWarn = false;
          break;
      }

      if (m_bExit || m_bPause)
      {
          m_pInputBuffer->EndRead(0);
          continue;
      }

      iRet = ALwritesamps(outaudioport, pBuffer, m_iDataSize);
      if ((int)iRet < 0)
      {
         m_pInputBuffer->EndRead(0);
         ReportError("Could not write sound data to the soundcard.");
         m_pContext->log->Error("Failed to write to the soundcard: %s\n", 
                               strerror(errno));
         break;
      }

      m_iTotalBytesWritten += iRet;
      m_pInputBuffer->EndRead(iRet);
      m_pLmc->Wake();
      UpdateBufferStatus();
   }
}