aboutsummaryrefslogtreecommitdiff
path: root/engines/tony/mpal/mpal.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2012-05-06 15:18:03 +1000
committerPaul Gilbert2012-05-06 15:18:03 +1000
commit770e55d06578f7f51959ea331da7baaaaa0e360d (patch)
treeceb34a9ee2e031f7e66c66e580b66db8e359875b /engines/tony/mpal/mpal.cpp
parent20a47ff7c9bba866ccfb0df232de58c9cc8d6880 (diff)
downloadscummvm-rg350-770e55d06578f7f51959ea331da7baaaaa0e360d.tar.gz
scummvm-rg350-770e55d06578f7f51959ea331da7baaaaa0e360d.tar.bz2
scummvm-rg350-770e55d06578f7f51959ea331da7baaaaa0e360d.zip
TONY: Further conversion of initially launched threads to processes.
This includes all the dependent routines that they call.
Diffstat (limited to 'engines/tony/mpal/mpal.cpp')
-rw-r--r--engines/tony/mpal/mpal.cpp310
1 files changed, 169 insertions, 141 deletions
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 78111753ce..851de7cb0c 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -138,7 +138,7 @@ bool bExecutingDialog;
uint32 nPollingLocations[MAXPOLLINGLOCATIONS];
HANDLE hEndPollingLocations[MAXPOLLINGLOCATIONS];
-HANDLE PollingThreads[MAXPOLLINGLOCATIONS];
+uint32 PollingThreads[MAXPOLLINGLOCATIONS];
HANDLE hAskChoice;
HANDLE hDoneChoice;
@@ -996,7 +996,7 @@ void ShutUpActionThread(CORO_PARAM, const void *param) {
CORO_BEGIN_CONTEXT;
CORO_END_CONTEXT(_ctx);
- int pid = *(const int *)param;
+ uint32 pid = *(const uint32 *)param;
CORO_BEGIN_CODE(_ctx);
@@ -1021,17 +1021,7 @@ void ShutUpActionThread(CORO_PARAM, const void *param) {
*
\****************************************************************************/
-void PASCAL LocationPollThread(uint32 id) {
- uint32 *il;
- int i,j,k;
- int numitems;
- int nRealItems;
- LPMPALITEM curItem,newItem;
- int nIdleActions;
- uint32 curTime;
- uint32 dwSleepTime;
- uint32 dwId;
-
+void LocationPollThread(CORO_PARAM, const void *param) {
typedef struct {
uint32 nItem, nAction;
@@ -1046,59 +1036,77 @@ void PASCAL LocationPollThread(uint32 id) {
typedef struct {
uint32 nItem;
- HANDLE hThread;
+ uint32 hThread;
} MYTHREAD;
- MYACTION *MyActions;
- MYTHREAD *MyThreads;
+ CORO_BEGIN_CONTEXT;
+ uint32 *il;
+ int i, j, k;
+ int numitems;
+ int nRealItems;
+ LPMPALITEM curItem,newItem;
+ int nIdleActions;
+ uint32 curTime;
+ uint32 dwSleepTime;
+ uint32 dwId;
+ int ord;
+ bool delayExpired;
+
+ MYACTION *MyActions;
+ MYTHREAD *MyThreads;
+ CORO_END_CONTEXT(_ctx);
+
+ uint32 id = *((const uint32 *)param);
+
+ CORO_BEGIN_CODE(_ctx);
/* Tanto per cominciare, e' necessario richiedere la lista degli item
presenti nella locazione. */
- il = mpalQueryItemList(nPollingLocations[id]);
+ _ctx->il = mpalQueryItemList(nPollingLocations[id]);
/* Contiamo gli items */
- for (numitems = 0; il[numitems] != 0; numitems++)
+ for (_ctx->numitems = 0; _ctx->il[_ctx->numitems] != 0; _ctx->numitems++)
;
/* Cerchiamo gli items della locazione senza idle actions e li eliminiamo
dalla lista */
LockItems();
- nIdleActions = 0;
- nRealItems = 0;
- for (i = 0; i < numitems; i++) {
- int ord = itemGetOrderFromNum(il[i]);
+ _ctx->nIdleActions = 0;
+ _ctx->nRealItems = 0;
+ for (_ctx->i = 0; _ctx->i < _ctx->numitems; _ctx->i++) {
+ _ctx->ord = itemGetOrderFromNum(_ctx->il[_ctx->i]);
- if (ord == -1) continue;
+ if (_ctx->ord == -1) continue;
- curItem = lpmiItems + ord;
+ _ctx->curItem = lpmiItems + _ctx->ord;
- k = 0;
- for (j = 0; j < curItem->nActions; j++)
- if (curItem->Action[j].num == 0xFF)
- k++;
+ _ctx->k = 0;
+ for (_ctx->j = 0; _ctx->j < _ctx->curItem->nActions; _ctx->j++)
+ if (_ctx->curItem->Action[_ctx->j].num == 0xFF)
+ _ctx->k++;
- nIdleActions += k;
+ _ctx->nIdleActions += _ctx->k;
- if (k == 0)
+ if (_ctx->k == 0)
/* Possiamo eliminare questo item dalla lista */
- il[i] = (uint32)NULL;
+ _ctx->il[_ctx->i] = (uint32)NULL;
else
- nRealItems++;
+ _ctx->nRealItems++;
}
UnlockItems();
/* Se non e' rimasto nessuno possiamo uscire */
- if (nRealItems == 0) {
- GlobalFree(il);
- ExitThread(0);
-// _endthread();
+ if (_ctx->nRealItems == 0) {
+ GlobalFree(_ctx->il);
+ CORO_KILL_SELF();
+ return;
}
- MyThreads=(MYTHREAD *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, nRealItems * sizeof(MYTHREAD));
- if (MyThreads == NULL) {
- GlobalFree(il);
- ExitThread(0);
-// _endthread();
+ _ctx->MyThreads = (MYTHREAD *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, _ctx->nRealItems * sizeof(MYTHREAD));
+ if (_ctx->MyThreads == NULL) {
+ GlobalFree(_ctx->il);
+ CORO_KILL_SELF();
+ return;
}
/* Inizializziamo le routine random */
@@ -1108,142 +1116,147 @@ void PASCAL LocationPollThread(uint32 id) {
/* Abbiamo appurato che esiste almeno un item che contiene idle actions.
Ora creaiamo le copie speculari delle idle actions */
- MyActions = (MYACTION *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, nIdleActions * sizeof(MYACTION));
- if (MyActions == NULL) {
- GlobalFree(MyThreads);
- GlobalFree(il);
- ExitThread(0);
-// _endthread();
+ _ctx->MyActions = (MYACTION *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, _ctx->nIdleActions * sizeof(MYACTION));
+ if (_ctx->MyActions == NULL) {
+ GlobalFree(_ctx->MyThreads);
+ GlobalFree(_ctx->il);
+ CORO_KILL_SELF();
+ return;
}
LockItems();
- k = 0;
+ _ctx->k = 0;
- for (i = 0; i < numitems; i++) {
- if (il[i] == 0)
+ for (_ctx->i = 0; _ctx->i < _ctx->numitems; _ctx->i++) {
+ if (_ctx->il[_ctx->i] == 0)
continue;
- curItem = lpmiItems + itemGetOrderFromNum(il[i]);
+ _ctx->curItem = lpmiItems + itemGetOrderFromNum(_ctx->il[_ctx->i]);
- for (j = 0; j < curItem->nActions; j++)
- if (curItem->Action[j].num == 0xFF) {
- MyActions[k].nItem = il[i];
- MyActions[k].nAction = j;
+ for (_ctx->j = 0; _ctx->j < _ctx->curItem->nActions; _ctx->j++)
+ if (_ctx->curItem->Action[_ctx->j].num == 0xFF) {
+ _ctx->MyActions[_ctx->k].nItem = _ctx->il[_ctx->i];
+ _ctx->MyActions[_ctx->k].nAction = _ctx->j;
- MyActions[k].wTime = curItem->Action[j].wTime;
- MyActions[k].perc = curItem->Action[j].perc;
- MyActions[k].when = curItem->Action[j].when;
- MyActions[k].nCmds = curItem->Action[j].nCmds;
- CopyMemory(MyActions[k].CmdNum, curItem->Action[j].CmdNum,
+ _ctx->MyActions[_ctx->k].wTime = _ctx->curItem->Action[_ctx->j].wTime;
+ _ctx->MyActions[_ctx->k].perc = _ctx->curItem->Action[_ctx->j].perc;
+ _ctx->MyActions[_ctx->k].when = _ctx->curItem->Action[_ctx->j].when;
+ _ctx->MyActions[_ctx->k].nCmds = _ctx->curItem->Action[_ctx->j].nCmds;
+ CopyMemory(_ctx->MyActions[_ctx->k].CmdNum, _ctx->curItem->Action[_ctx->j].CmdNum,
MAX_COMMANDS_PER_ACTION * sizeof(uint16));
- MyActions[k].dwLastTime = timeGetTime();
- k++;
+ _ctx->MyActions[_ctx->k].dwLastTime = timeGetTime();
+ _ctx->k++;
}
}
UnlockItems();
/* La item list non ci serve piu' */
- GlobalFree(il);
+ GlobalFree(_ctx->il);
/* Eccoci al ciclo principale. */
while (1) {
/* Cerchiamo tra tutte le idle actions quella a cui manca meno tempo per
l'esecuzione */
- curTime = timeGetTime();
- dwSleepTime=(uint32) - 1L;
+ _ctx->curTime = timeGetTime();
+ _ctx->dwSleepTime = (uint32)-1L;
- for (k = 0;k<nIdleActions;k++)
- if (curTime >= MyActions[k].dwLastTime + MyActions[k].wTime) {
- dwSleepTime = 0;
+ for (_ctx->k = 0;_ctx->k<_ctx->nIdleActions;_ctx->k++)
+ if (_ctx->curTime >= _ctx->MyActions[_ctx->k].dwLastTime + _ctx->MyActions[_ctx->k].wTime) {
+ _ctx->dwSleepTime = 0;
break;
} else
- dwSleepTime = MIN(dwSleepTime,MyActions[k].dwLastTime+MyActions[k].wTime-curTime);
+ _ctx->dwSleepTime = MIN(_ctx->dwSleepTime, _ctx->MyActions[_ctx->k].dwLastTime + _ctx->MyActions[_ctx->k].wTime - _ctx->curTime);
/* Ci addormentiamo, ma controllando sempre l'evento che viene settato
quando viene richiesta la nostra chiusura */
- k = WaitForSingleObject(hEndPollingLocations[id], dwSleepTime);
- if (k == WAIT_OBJECT_0)
+ _ctx->k = WaitForSingleObject(hEndPollingLocations[id], _ctx->dwSleepTime);
+ if (_ctx->k == WAIT_OBJECT_0)
break;
- for (i = 0; i < nRealItems; i++)
- if (MyThreads[i].nItem != 0) {
- if (WaitForSingleObject(MyThreads[i].hThread, 0) == WAIT_OBJECT_0)
- MyThreads[i].nItem = 0;
+ for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
+ if (_ctx->MyThreads[_ctx->i].nItem != 0) {
+ CORO_INVOKE_3(_vm->_scheduler.waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 0, &_ctx->delayExpired);
+
+ // if result ) == WAIT_OBJECT_0)
+ if (!_ctx->delayExpired)
+ _ctx->MyThreads[_ctx->i].nItem = 0;
}
- curTime = timeGetTime();
+ _ctx->curTime = timeGetTime();
/* Cerchiamo all'interno delle idle actions quale e' necessario eseguire */
- for (k = 0; k < nIdleActions; k++)
- if (curTime >= MyActions[k].dwLastTime + MyActions[k].wTime) {
- MyActions[k].dwLastTime += MyActions[k].wTime;
+ for (_ctx->k = 0; _ctx->k < _ctx->nIdleActions; _ctx->k++)
+ if (_ctx->curTime >= _ctx->MyActions[_ctx->k].dwLastTime + _ctx->MyActions[_ctx->k].wTime) {
+ _ctx->MyActions[_ctx->k].dwLastTime += _ctx->MyActions[_ctx->k].wTime;
- /* E' il momento di tirare il nostro dado virtuale, e controllare
+ /* E' _ctx->il momento di tirare _ctx->il nostro dado virtuale, e controllare
se la sorte e' dalla parte della idle action */
byte randomVal = (byte)_vm->_randomSource.getRandomNumber(99);
- if (randomVal < MyActions[k].perc) {
+ if (randomVal < _ctx->MyActions[_ctx->k].perc) {
/* Controlliamo se c'e' una action in esecuzione sull'item */
- if ((bExecutingAction) && (nExecutingAction == MyActions[k].nItem))
+ if ((bExecutingAction) && (nExecutingAction == _ctx->MyActions[_ctx->k].nItem))
continue;
/* Controlliamo se c'e' gia' un'altra idle function in esecuzione
sullo stesso item */
- for (i = 0; i < nRealItems; i++)
- if (MyThreads[i].nItem == MyActions[k].nItem)
+ for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
+ if (_ctx->MyThreads[_ctx->i].nItem == _ctx->MyActions[_ctx->k].nItem)
break;
- if (i < nRealItems)
+ if (_ctx->i < _ctx->nRealItems)
continue;
/* Ok, siamo gli unici :) */
LockItems();
- curItem=lpmiItems+itemGetOrderFromNum(MyActions[k].nItem);
+ _ctx->curItem=lpmiItems+itemGetOrderFromNum(_ctx->MyActions[_ctx->k].nItem);
/* Controlliamo se c'e' un esperessione WhenExecute */
- j=MyActions[k].nAction;
- if (curItem->Action[j].when != NULL)
- if (!EvaluateExpression(curItem->Action[j].when)) {
+ _ctx->j=_ctx->MyActions[_ctx->k].nAction;
+ if (_ctx->curItem->Action[_ctx->j].when != NULL)
+ if (!EvaluateExpression(_ctx->curItem->Action[_ctx->j].when)) {
UnlockItems();
continue;
}
/* Ok, possiamo eseguire la azione. Per comodita' lo facciamo in
un nuovo thread */
- newItem=(LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM));
- if (newItem == false) {
- GlobalFree(MyThreads);
- GlobalFree(MyActions);
- ExitThread(0);
-// _endthread();
+ _ctx->newItem = (LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM));
+ if (_ctx->newItem == false) {
+ GlobalFree(_ctx->MyThreads);
+ GlobalFree(_ctx->MyActions);
+
+ CORO_KILL_SELF();
+ return;
}
- CopyMemory(newItem,curItem, sizeof(MPALITEM));
+ CopyMemory(_ctx->newItem,_ctx->curItem, sizeof(MPALITEM));
UnlockItems();
/* Copiamo l'azione nella #0 */
-// newItem->Action[0].nCmds = curItem->Action[j].nCmds;
-// CopyMemory(newItem->Action[0].CmdNum,curItem->Action[j].CmdNum,newItem->Action[0].nCmds*sizeof(newItem->Action[0].CmdNum[0]));
- newItem->dwRes=j;
+// _ctx->newItem->Action[0].nCmds = _ctx->curItem->Action[_ctx->j].nCmds;
+// CopyMemory(_ctx->newItem->Action[0].CmdNum,_ctx->curItem->Action[_ctx->j].CmdNum,_ctx->newItem->Action[0].nCmds*sizeof(_ctx->newItem->Action[0].CmdNum[0]));
+ _ctx->newItem->dwRes=_ctx->j;
/* Creaiamo l'action thread. Provvedera' lui a liberare la memoria
- allocata per il nuovo item */
- for (i = 0; i < nRealItems; i++)
- if (MyThreads[i].nItem == 0)
+ allocata per _ctx->il nuovo item */
+ for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
+ if (_ctx->MyThreads[_ctx->i].nItem == 0)
break;
- MyThreads[i].nItem=MyActions[k].nItem;
+ _ctx->MyThreads[_ctx->i].nItem = _ctx->MyActions[_ctx->k].nItem;
// !!! Nuova gestione dei thread
- if ((MyThreads[i].hThread = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)ActionThread,(void *)newItem, 0, &dwId)) == NULL) {
- //if ((MyThreads[i].hThread=(void*)_beginthread(ActionThread, 10240,(void *)newItem))==(void*)-1)
- GlobalFree(newItem);
- GlobalFree(MyThreads);
- GlobalFree(MyActions);
- ExitThread(0);
-// _endthread();
+ if ((_ctx->MyThreads[_ctx->i].hThread = _vm->_scheduler.createProcess(ActionThread, &_ctx->newItem, sizeof(LPMPALITEM))) == 0) {
+ //if ((_ctx->MyThreads[_ctx->i].hThread=(void*)_beginthread(ActionThread, 10240,(void *)_ctx->newItem))==(void*)-1)
+ GlobalFree(_ctx->newItem);
+ GlobalFree(_ctx->MyThreads);
+ GlobalFree(_ctx->MyActions);
+
+ CORO_KILL_SELF();
+ return;
}
/* Skippa tutte le idle action dello stesso item */
@@ -1251,16 +1264,16 @@ void PASCAL LocationPollThread(uint32 id) {
}
}
- /* Chiude tutti i thread interni */
+ /* Chiude tutti _ctx->i thread interni */
/*
CODICE OBSOLETO: ANDIAMO DI SKIP CHE RULLA
- for (i = 0; i < nRealItems; i++)
- if (MyThreads[i].nItem != 0) {
- TerminateThread(MyThreads[i].hThread, 0);
- CloseHandle(MyThreads[i].hThread);
+ for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
+ if (_ctx->MyThreads[_ctx->i].nItem != 0) {
+ TerminateThread(_ctx->MyThreads[_ctx->i].hThread, 0);
+ CloseHandle(_ctx->MyThreads[_ctx->i].hThread);
}
*/
@@ -1268,23 +1281,28 @@ void PASCAL LocationPollThread(uint32 id) {
// FIXME: Convert to co-routine
lplpFunctions[200](nullContext, 0, 0, 0, 0);
- for (i = 0; i < nRealItems; i++)
- if (MyThreads[i].nItem != 0) {
- if (WaitForSingleObject(MyThreads[i].hThread,5000) != WAIT_OBJECT_0)
- TerminateThread(MyThreads[i].hThread, 0);
+ for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
+ if (_ctx->MyThreads[_ctx->i].nItem != 0) {
+ CORO_INVOKE_3(_vm->_scheduler.waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 5000, &_ctx->delayExpired);
- CloseHandle(MyThreads[i].hThread);
+/*
+ //if (result != WAIT_OBJECT_0)
+ if (_ctx->delayExpired)
+ TerminateThread(_ctx->MyThreads[_ctx->i].hThread, 0);
+*/
+ _vm->_scheduler.killMatchingProcess(_ctx->MyThreads[_ctx->i].hThread);
}
// Set idle skip off
- // FIXME: Convert to co-routine
- lplpFunctions[201](nullContext, 0, 0, 0, 0);
+ CORO_INVOKE_4(lplpFunctions[201], 0, 0, 0, 0);
/* Abbiamo finito */
- GlobalFree(MyThreads);
- GlobalFree(MyActions);
- ExitThread(1);
-//endthread();
+ GlobalFree(_ctx->MyThreads);
+ GlobalFree(_ctx->MyActions);
+
+ CORO_KILL_SELF();
+
+ CORO_END_CODE;
}
@@ -1516,7 +1534,7 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
LPMPALITEM item = lpmiItems;
int i;
LPMPALITEM newitem;
- PROCESS *h;
+ uint32 h;
item+=ordItem;
Common::String buf = Common::String::format("Status.%u", item->nObj);
@@ -1552,10 +1570,10 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
// 0 dell'item, e poi liberera' la memoria con la GlobalFree()
// !!! New thread management
- if ((h = g_scheduler->createProcess(ActionThread, newitem)) == NULL)
+ if ((h = g_scheduler->createProcess(ActionThread, &newitem, sizeof(LPMPALITEM))) == NULL)
return INVALID_HANDLE_VALUE;
- if ((h = g_scheduler->createProcess(ShutUpActionThread, &h->pid, sizeof(int))) == NULL)
+ if ((h = g_scheduler->createProcess(ShutUpActionThread, &h, sizeof(uint32))) == NULL)
return INVALID_HANDLE_VALUE;
/*
@@ -2182,7 +2200,7 @@ void EXPORT mpalInstallItemIrq(LPITEMIRQFUNCTION lpiifCus) {
*
\****************************************************************************/
-bool EXPORT mpalStartIdlePoll(int nLoc) {
+bool mpalStartIdlePoll(int nLoc) {
uint32 i;
uint32 dwId;
@@ -2196,7 +2214,7 @@ bool EXPORT mpalStartIdlePoll(int nLoc) {
hEndPollingLocations[i] = CreateEvent(NULL, true, false, NULL);
// !!! Nuova gestione dei thread
- if ((PollingThreads[i] = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)LocationPollThread,(void *)i, 0, &dwId)) == NULL)
+ if ((PollingThreads[i] = _vm->_scheduler.createProcess(LocationPollThread, &i, sizeof(uint32))) == 0)
// if ((hEndPollingLocations[i]=(void*)_beginthread(LocationPollThread, 10240,(void *)i))==(void*)-1)
return false;
@@ -2222,22 +2240,32 @@ bool EXPORT mpalStartIdlePoll(int nLoc) {
*
\****************************************************************************/
-bool EXPORT mpalEndIdlePoll(int nLoc) {
- uint32 i;
+void mpalEndIdlePoll(CORO_PARAM, int nLoc, bool *result) {
+ CORO_BEGIN_CONTEXT;
+ int i;
+ CORO_END_CONTEXT(_ctx);
- for (i = 0; i < MAXPOLLINGLOCATIONS; i++)
- if (nPollingLocations[i] == (uint32)nLoc) {
- SetEvent(hEndPollingLocations[i]);
+ CORO_BEGIN_CODE(_ctx);
+
+ for (_ctx->i = 0; _ctx->i < MAXPOLLINGLOCATIONS; _ctx->i++) {
+ if (nPollingLocations[_ctx->i] == (uint32)nLoc) {
+ SetEvent(hEndPollingLocations[_ctx->i]);
- WaitForSingleObject(PollingThreads[i], INFINITE);
+ CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, PollingThreads[_ctx->i], INFINITE);
- CloseHandle(hEndPollingLocations[i]);
- nPollingLocations[i] = 0;
+ CloseHandle(hEndPollingLocations[_ctx->i]);
+ nPollingLocations[_ctx->i] = 0;
- return true;
+ if (result)
+ *result = true;
+ return;
+ }
}
- return false;
+ if (result)
+ *result = false;
+
+ CORO_END_CODE;
}