void AMXStackFramePrinter::PrintCallerName(const AMXStackFrame &frame) {
  if (IsMain(frame.amx(), frame.caller_address())) {
    stream_ << "main";
    return;
  }

  if (debug_info_.IsLoaded()) {
    AMXDebugSymbol caller =
      debug_info_.GetExactFunction(frame.caller_address());
    if (caller) {
      if (IsPublicFunction(frame.amx(), caller.GetCodeStart())
          && !IsMain(frame.amx(), caller.GetCodeStart())) {
        stream_ << "public ";
      }
      PrintTag(caller);
      stream_ << caller.GetName();
      return;
    }
  }

  const char *name = 0;
  if (frame.caller_address() != 0) {
    name = frame.amx().FindPublic(frame.caller_address());
  }
  if (name != 0) {
    stream_ << "public " << name;
  } else {
    stream_ << "??";
  }
}
Exemplo n.º 2
0
AM_ERR CQueue::SendMsg(const void *pMsg, AM_UINT msgSize)
{
  AM_ASSERT(IsMain());

  AUTO_LOCK(mpMutex);
  while (1) {
    if (mpMsgResult == NULL) {
      WriteData(mpSendBuffer, pMsg, msgSize);

      if (mnGet > 0) {
        mnGet --;
        mpCondGet->Signal();
      }

      AM_ERR result;
      mpMsgResult = &result;
      mpCondReply->Wait(mpMutex);
      mpMsgResult = NULL;

      if (mnSendMsg > 0) {
        mnSendMsg --;
        mpCondSendMsg->Signal();
      }

      return result;
    }

    mnSendMsg ++;
    mpCondSendMsg->Wait(mpMutex);
  }
  return ME_ERROR;
}
Exemplo n.º 3
0
AM_ERR CQueue::Construct(AM_UINT blockSize, AM_UINT nReservedSlots)
{
  mBlockSize = ROUND_UP(blockSize, 4);

  // mpSendBuffer + list_node + list_node + ... + list_node
  mpReservedMemory = new AM_U8[NODE_SIZE * (nReservedSlots + 1)];
  if (mpReservedMemory == NULL) {
    return ME_NO_MEMORY;
  }

  // for SendMsg()
  mpSendBuffer = (List*) mpReservedMemory;
  mpSendBuffer->pNext = NULL;
  mpSendBuffer->bAllocated = false;

  // reserved nodes, keep in free-list
  List *pNode = (List*) (mpReservedMemory + NODE_SIZE);
  for (; nReservedSlots > 0; nReservedSlots --) {
    pNode->bAllocated = false;
    pNode->pNext = mpFreeList;
    mpFreeList = pNode;
    pNode = (List*) ((AM_U8*) pNode + NODE_SIZE);
  }

  if (IsMain()) {
    if ((mpMutex = CMutex::Create(false)) == NULL) {
      return ME_OS_ERROR;
    }

    if ((mpCondGet = CCondition::Create()) == NULL) {
      return ME_OS_ERROR;
    }

    if ((mpCondReply = CCondition::Create()) == NULL) {
      return ME_OS_ERROR;
    }

    if ((mpCondSendMsg = CCondition::Create()) == NULL) {
      return ME_OS_ERROR;
    }
  } else {
    mpMutex = mpMainQ->mpMutex;
    mpCondGet = mpMainQ->mpCondGet;
    mpCondReply = mpMainQ->mpCondReply;
    mpCondSendMsg = mpMainQ->mpCondSendMsg;

    // attach to main-Q
    AUTO_LOCK(mpMainQ->mpMutex);
    mpPrevQ = mpMainQ->mpPrevQ;
    mpNextQ = mpMainQ;
    mpPrevQ->mpNextQ = this;
    mpNextQ->mpPrevQ = this;
  }

  return ME_OK;
}
Exemplo n.º 4
0
void CQueue::Reply(AM_ERR result)
{
  AUTO_LOCK(mpMutex);

  AM_ASSERT(IsMain());
  AM_ASSERT(mpMsgResult);

  *mpMsgResult = result;
  mpCondReply->Signal();
}
Exemplo n.º 5
0
static void PrintHeader(const Proto* tf)
{
 printf("\n%s " SOURCE_FMT " (%d instruction%s/%d bytes at %p)\n",
 	IsMain(tf)?"main":"function",SOURCE,
	S(tf->ncode),tf->ncode*Sizeof(Instruction),tf);
 printf("%d%s param%s, %d stack%s, ",
	tf->numparams,tf->is_vararg?"+":"",SS(tf->numparams),S(tf->maxstacksize));
 printf("%d local%s, %d string%s, %d number%s, %d function%s, %d line%s\n",
	S(tf->nlocvars),S(tf->nkstr),S(tf->nknum),S(tf->nkproto),S(tf->nlineinfo));
}
Exemplo n.º 6
0
void PrintFunction(TFunc* tf)
{
 if (IsMain(tf))
  printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf);
 else
  printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n",
	tf->fileName,tf->lineDefined,tf->size,tf,tf->marked);
 V=tf->locvars;
 PrintCode(tf->code,tf->code+tf->size);
}
Exemplo n.º 7
0
static void PrintHeader(const Proto* f)
{
    printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n",
           IsMain(f)?"main":"function",Source(f),f->lineDefined,
           S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
    printf("%d%s param%s, %d stack%s, %d upvalue%s, ",
           f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize),
           S(f->nups));
    printf("%d local%s, %d constant%s, %d function%s\n",
           S(f->sizelocvars),S(f->sizek),S(f->sizep));
}
Exemplo n.º 8
0
bool wxThread::SetConcurrency(size_t level)
{
    wxASSERT_MSG( IsMain(), wxT("should only be called from the main thread") );

    // ok only for the default one
    if ( level == 0 )
        return 0;

    // Don't know how to realize this on OS/2.
    return level == 1;
}
void AMXStackFramePrinter::PrintCallerName(const AMXStackFrame &frame,
                                           const AMXDebugSymbol &caller) {
  bool is_public = IsPublicFunction(frame.amx(),
                                    caller.GetCodeStart());
  bool is_main = IsMain(frame.amx(), caller.GetCodeStart());
  if (is_public && !is_main) {
    *stream_ << "public ";
  }
  PrintTag(caller);
  *stream_ << caller.GetName();
}
Exemplo n.º 10
0
bool CQueue::PeekMsg(void *pMsg, AM_UINT msgSize)
{
  AM_ASSERT(IsMain());

  AUTO_LOCK(mpMutex);
  if (mnData > 0) {
    if (pMsg)
      ReadData(pMsg, msgSize);
    return true;
  }

  return false;
}
Exemplo n.º 11
0
void DumpFunction(TFunc* tf, FILE* D)
{
 lastF=tf;
 ThreadCode(tf->code,tf->code+tf->size);
 fputc(ID_FUN,D);
 DumpSize(tf->size,D);
 DumpWord(tf->lineDefined,D);
 if (IsMain(tf))
  DumpString(tf->fileName,D);
 else
  DumpWord(tf->marked,D);
 DumpBlock(tf->code,tf->size,D);
 DumpStrings(D);
}
void AMXStackFramePrinter::PrintCallerName(const AMXStackFrame &frame) {
  if (IsMain(frame.amx(), frame.caller_address())) {
    *stream_ << "main";
  } else {
    const char *name = 0;
    if (frame.caller_address() != 0) {
      name = frame.amx().FindPublic(frame.caller_address());
    }
    if (name != 0) {
      *stream_ << "public " << name;
    } else {
      *stream_ << "??";
    }
  }
}
Exemplo n.º 13
0
void CQueue::GetMsg(void *pMsg, AM_UINT msgSize)
{
  AM_ASSERT(IsMain());

  AUTO_LOCK(mpMutex);
  while (1) {
    if (mnData > 0) {
      ReadData(pMsg, msgSize);
      return;
    }

    mnGet ++;
    mpCondGet->Wait(mpMutex);
  }
}
Exemplo n.º 14
0
bool wxThread::SetConcurrency(size_t level)
{
    wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );

    // ok only for the default one
    if ( level == 0 )
        return 0;

    // how many CPUs have we got?
    if ( GetCPUCount() == 1 )
    {
        // don't bother with all this complicated stuff - on a single
        // processor system it doesn't make much sense anyhow
        return level == 1;
    }

    return TRUE ;
}
Exemplo n.º 15
0
AM_ERR CQueue::PostMsg(const void *pMsg, AM_UINT msgSize)
{
  AM_ASSERT(IsMain());
  AUTO_LOCK(mpMutex);

  List *pNode = AllocNode();
  if (pNode == NULL) {
    return ME_NO_MEMORY;
  }

  WriteData(pNode, pMsg, msgSize);

  if (mnGet > 0) {
    mnGet --;
    mpCondGet->Signal();
  }

  return ME_OK;
}
Exemplo n.º 16
0
bool CQueue::GetMsgEx(void *pMsg, AM_UINT msgSize)
{
  AM_ASSERT(IsMain());

  AUTO_LOCK(mpMutex);
  while (1) {
    if (mbDisabled)
      return false;

    if (mnData > 0) {
      ReadData(pMsg, msgSize);
      return true;
    }

    mnGet ++;
    mpCondGet->Wait(mpMutex);
  }

  return false;
}
Exemplo n.º 17
0
// wait this main-Q and all its sub-Qs
CQueue::QType CQueue::WaitDataMsg(void *pMsg,
                                  AM_UINT msgSize,
                                  WaitResult *pResult)
{
  AM_ASSERT(IsMain());

  AUTO_LOCK(mpMutex);
  while (1) {
    if (mnData > 0) {
      ReadData(pMsg, msgSize);
      return Q_MSG;
    }

    for (CQueue *q = mpNextQ; q != this; q = q->mpNextQ) {
      if (q->mnData > 0 && !q->mbDisabled) {
        pResult->pDataQ = q;
        pResult->pOwner = q->mpOwner;
        pResult->blockSize = q->mBlockSize;

        /* move the hit Q to the tail, semi Round Robin
         if (q != mpPrevQ) {		// if q is not the tail
         q->mpPrevQ->mpNextQ = q->mpNextQ;
         q->mpNextQ->mpPrevQ = q->mpPrevQ;
         mpPrevQ->mpNextQ = q;
         q->mpPrevQ = mpPrevQ;
         mpPrevQ = q;
         q->mpNextQ = this;
         }	*/
        return Q_DATA;
      }
    }

    mnGet ++;
    mpCondGet->Wait(mpMutex);
  }

  return Q_MSG; // Add this line to shut up code analysis warning
}
	//-------------------------------------------------------------------------------------------------
	void TextureMemory::Initialize()
	{
		// Todo: texture palette can probably have more slots, and other palette memory types can also expand. For now just 1 for testing texture palettes
		// Todo: If VRAM_E is mapped to texture or extended palette, it occupies more than 1 slot. Make this possible
		// Todo: Implement palette support. Only direct colored textures for now
		//PaletteMemory.Initialize(this);
		//PaletteMemory.AddSlot(BankE | BankF | BankG);

		if (IsMain())
		{
			InitializeSlots(4);

			Slots[0]->AddSupportedMapping(BankA, VRAM_A_TEXTURE_SLOT0);
			Slots[0]->AddSupportedMapping(BankB, VRAM_B_TEXTURE_SLOT0);
			Slots[0]->AddSupportedMapping(BankC, VRAM_C_TEXTURE_SLOT0);
			Slots[0]->AddSupportedMapping(BankD, VRAM_D_TEXTURE_SLOT0);

			Slots[1]->AddSupportedMapping(BankA, VRAM_A_TEXTURE_SLOT1);
			Slots[1]->AddSupportedMapping(BankB, VRAM_B_TEXTURE_SLOT1);
			Slots[1]->AddSupportedMapping(BankC, VRAM_C_TEXTURE_SLOT1);
			Slots[1]->AddSupportedMapping(BankD, VRAM_D_TEXTURE_SLOT1);

			Slots[2]->AddSupportedMapping(BankA, VRAM_A_TEXTURE_SLOT2);
			Slots[2]->AddSupportedMapping(BankB, VRAM_B_TEXTURE_SLOT2);
			Slots[2]->AddSupportedMapping(BankC, VRAM_C_TEXTURE_SLOT2);
			Slots[2]->AddSupportedMapping(BankD, VRAM_D_TEXTURE_SLOT2);

			Slots[3]->AddSupportedMapping(BankA, VRAM_A_TEXTURE_SLOT3);
			Slots[3]->AddSupportedMapping(BankB, VRAM_B_TEXTURE_SLOT3);
			Slots[3]->AddSupportedMapping(BankC, VRAM_C_TEXTURE_SLOT3);
			Slots[3]->AddSupportedMapping(BankD, VRAM_D_TEXTURE_SLOT3);

			// Todo: hack, only works if BankA is mapped to TextureMemory
			nextAvailableAddress = VRAM_A;
		}
	}
Exemplo n.º 19
0
CQueue::~CQueue()
{
  if (mpMutex) {
    __LOCK(mpMutex);
  }

  AM_ASSERT(mnGet == 0);
  AM_ASSERT(mnSendMsg == 0);

  if (IsSub()) {
    // detach from main-Q
    mpPrevQ->mpNextQ = mpNextQ;
    mpNextQ->mpPrevQ = mpPrevQ;
  } else {
    // all sub-Qs should be removed
    AM_ASSERT(mpPrevQ == this);
    AM_ASSERT(mpNextQ == this);
    AM_ASSERT(mpMsgResult == NULL);
  }

  mpHead->Delete();
  mpFreeList->Delete();

  delete[] mpReservedMemory;

  if (mpMutex) {
    __UNLOCK(mpMutex);
  }

  if (IsMain()) {
    AM_DELETE(mpCondSendMsg);
    AM_DELETE(mpCondReply);
    AM_DELETE(mpCondGet);
    AM_DELETE(mpMutex);
  }
}
Exemplo n.º 20
0
wxThreadError wxThread::Delete(ExitCode *pRc)
{
    ExitCode rc = 0;

    // Delete() is always safe to call, so consider all possible states

    // has the thread started to run?
    bool shouldResume = FALSE;

    {
        wxCriticalSectionLocker lock(m_critsect);

        if ( m_internal->GetState() == STATE_NEW )
        {
            // WinThreadStart() will see it and terminate immediately
            m_internal->SetState(STATE_EXITED);

            shouldResume = TRUE;
        }
    }

    // is the thread paused?
    if ( shouldResume || IsPaused() )
        Resume();

    // does is still run?
    if ( IsRunning() )
    {
        if ( IsMain() )
        {
            // set flag for wxIsWaitingForThread()
            gs_waitingForThread = TRUE;

#if wxUSE_GUI
            wxBeginBusyCursor();
#endif // wxUSE_GUI
        }

        // ask the thread to terminate
        {
            wxCriticalSectionLocker lock(m_critsect);

            m_internal->Cancel();
        }

#if wxUSE_GUI
        // simply wait for the thread to terminate
        while( TestDestroy() )
        {
            ::YieldToAnyThread() ;
        }
#else // !wxUSE_GUI
        // simply wait for the thread to terminate
        while( TestDestroy() )
        {
            ::YieldToAnyThread() ;
        }
#endif // wxUSE_GUI/!wxUSE_GUI

        if ( IsMain() )
        {
            gs_waitingForThread = FALSE;

#if wxUSE_GUI
            wxEndBusyCursor();
#endif // wxUSE_GUI
        }
    }

    if ( IsDetached() )
    {
        // if the thread exits normally, this is done in WinThreadStart, but in
        // this case it would have been too early because
        // MsgWaitForMultipleObject() would fail if the therad handle was
        // closed while we were waiting on it, so we must do it here
        delete this;
    }

    if ( pRc )
        *pRc = rc;

    return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;
}
Exemplo n.º 21
0
wxThreadError wxThread::Delete(ExitCode *pRc)
{
    ExitCode rc = 0;

    // Delete() is always safe to call, so consider all possible states

    // we might need to resume the thread, but we might also not need to cancel
    // it if it doesn't run yet
    bool shouldResume = false,
         shouldCancel = true,
         isRunning = false;

    // check if the thread already started to run
    {
        wxCriticalSectionLocker         lock((wxCriticalSection &)m_critsect);

        if ( m_internal->GetState() == STATE_NEW )
        {
            // WinThreadStart() will see it and terminate immediately, no need
            // to cancel the thread - but we still need to resume it to let it
            // run
            m_internal->SetState(STATE_EXITED);

            Resume();   // it knows about STATE_EXITED special case

            shouldCancel = false;
            isRunning = true;

            // shouldResume is correctly set to false here
        }
        else
        {
            shouldResume = IsPaused();
        }
    }

    // resume the thread if it is paused
    if ( shouldResume )
        Resume();

    TID hThread = m_internal->GetHandle();

    if ( isRunning || IsRunning())
    {
        if (IsMain())
        {
            // set flag for wxIsWaitingForThread()
            gs_bWaitingForThread = true;
        }

        // ask the thread to terminate
        if ( shouldCancel )
        {
            wxCriticalSectionLocker lock(m_critsect);

            m_internal->Cancel();
        }

#if 0
        // we can't just wait for the thread to terminate because it might be
        // calling some GUI functions and so it will never terminate before we
        // process the Windows messages that result from these functions
        DWORD result = 0;       // suppress warnings from broken compilers
        do
        {
            if ( IsMain() )
            {
                // give the thread we're waiting for chance to do the GUI call
                // it might be in
                if ( (gs_nWaitingForGui > 0) && wxGuiOwnedByMainThread() )
                {
                    wxMutexGuiLeave();
                }
            }

            result = ::DosWaitThread(&hThread, DCWW_NOWAIT);
            // FIXME: We ought to have a message processing loop here!!

            switch ( result )
            {
                case ERROR_INTERRUPT:
                case ERROR_THREAD_NOT_TERMINATED:
                    break;
                case ERROR_INVALID_THREADID:
                case NO_ERROR:
                    // thread we're waiting for just terminated
                    // or even does not exist any more.
                    result = NO_ERROR;
                    break;
                default:
                    wxFAIL_MSG(wxT("unexpected result of DosWaitThread"));
            }
            if ( IsMain() )
            {
                // event processing - needed if we are the main thread
                // to give other threads a chance to do remaining GUI
                // processing and terminate cleanly.
                wxTheApp->HandleSockets();
                if (wxTheApp->Pending())
                  if ( !wxTheApp->DoMessage() )
                  {
                      // WM_QUIT received: kill the thread
                      Kill();

                      return wxTHREAD_KILLED;
                  }
                  else
                    wxUsleep(10);
            }
            else
                wxUsleep(10);
        } while ( result != NO_ERROR );
#else // !wxUSE_GUI
        // simply wait for the thread to terminate
        //
        // OTOH, even console apps create windows (in wxExecute, for WinSock
        // &c), so may be use MsgWaitForMultipleObject() too here?
        if ( ::DosWaitThread(&hThread, DCWW_WAIT) != NO_ERROR )
        {
            wxFAIL_MSG(wxT("unexpected result of DosWaitThread"));
        }
#endif // wxUSE_GUI/!wxUSE_GUI

        if ( IsMain() )
        {
            gs_bWaitingForThread = false;
        }
    }

#if 0
    // although the thread might be already in the EXITED state it might not
    // have terminated yet and so we are not sure that it has actually
    // terminated if the "if" above hadn't been taken
    do
    {
        if ( !::GetExitCodeThread(hThread, (LPDWORD)&rc) )
        {
            wxLogLastError(wxT("GetExitCodeThread"));

            rc = (ExitCode)-1;
        }
    } while ( (DWORD)rc == STILL_ACTIVE );
#endif

    if ( IsDetached() )
    {
        // if the thread exits normally, this is done in WinThreadStart, but in
        // this case it would have been too early because
        // MsgWaitForMultipleObject() would fail if the thread handle was
        // closed while we were waiting on it, so we must do it here
        delete this;
    }

    if ( pRc )
        *pRc = rc;

    return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;
}
	//-------------------------------------------------------------------------------------------------
	int TextureMemory::Maximum() const
	{
		// Main engine can use 512kb (Bank A through D) for textures. Sub engine has no 3D, so no textures
		return (IsMain()) ? 0x80000 : 0; 
	}