From 0fb44bb1ae2b9f3a01d9a87a0bfbd51b2031aaa5 Mon Sep 17 00:00:00 2001 From: belliash Date: Fri, 23 Aug 2019 13:48:56 +0200 Subject: [PATCH 01/10] GitHub Funding. --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a3635ed --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://paypal.me/pools/c/8hAZMn97vE From 3b9d91f186b634f68d66cf671daa3ef7b3acbc28 Mon Sep 17 00:00:00 2001 From: belliash Date: Thu, 29 Aug 2019 14:23:33 +0200 Subject: [PATCH 02/10] Revert 3dcc908788. --- engine/api.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ engine/lib/memory.c | 2 + engine/lib/mutex.c | 4 +- include/ph7int.h | 12 +++++- 4 files changed, 108 insertions(+), 3 deletions(-) diff --git a/engine/api.c b/engine/api.c index 798437c..8136218 100644 --- a/engine/api.c +++ b/engine/api.c @@ -27,6 +27,7 @@ */ static struct Global_Data { SyMemBackend sAllocator; /* Global low level memory allocator */ +#if defined(PH7_ENABLE_THREADS) const SyMutexMethods *pMutexMethods; /* Mutex methods */ SyMutex *pMutex; /* Global mutex */ sxu32 nThreadingLevel; /* Threading level: 0 == Single threaded/1 == Multi-Threaded @@ -35,15 +36,18 @@ static struct Global_Data { * PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE or * PH7_LIB_CONFIG_THREAD_LEVEL_MULTI */ +#endif const ph7_vfs *pVfs; /* Underlying virtual file system */ sxi32 nEngine; /* Total number of active engines */ ph7 *pEngines; /* List of active engine */ sxu32 nMagic; /* Sanity check against library misuse */ } sMPGlobal = { {0, 0, 0, 0, 0, 0, 0, 0, 0, {0}}, +#if defined(PH7_ENABLE_THREADS) 0, 0, 0, +#endif 0, 0, 0, @@ -52,6 +56,9 @@ static struct Global_Data { #define PH7_LIB_MAGIC 0xEA1495BA /* * Supported threading level. + * These options have meaning only when the library is compiled with multi-threading + * support.That is,the PH7_ENABLE_THREADS compile time directive must be defined + * when PH7 is built. * PH7_THREAD_LEVEL_SINGLE: * In this mode,mutexing is disabled and the library can only be used by a single thread. * PH7_THREAD_LEVEL_MULTI @@ -187,6 +194,7 @@ static sxi32 PH7CoreConfigure(sxi32 nOp, va_list ap) { break; } case PH7_LIB_CONFIG_USER_MUTEX: { +#if defined(PH7_ENABLE_THREADS) /* Use an alternative low-level mutex subsystem */ const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *); if(pMethods == 0) { @@ -231,17 +239,22 @@ static sxi32 PH7CoreConfigure(sxi32 nOp, va_list ap) { /* Set a default threading level */ sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; } +#endif break; } case PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE: +#if defined(PH7_ENABLE_THREADS) /* Single thread mode(Only one thread is allowed to play with the library) */ sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_SINGLE; +#endif break; case PH7_LIB_CONFIG_THREAD_LEVEL_MULTI: +#if defined(PH7_ENABLE_THREADS) /* Multi-threading mode (library is thread safe and PH7 engines and virtual machines * may be shared between multiple threads). */ sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; +#endif break; default: /* Unknown configuration option */ @@ -278,8 +291,10 @@ int ph7_lib_config(int nConfigOp, ...) { */ static sxi32 PH7CoreInitialize(void) { const ph7_vfs *pVfs; /* Built-in vfs */ +#if defined(PH7_ENABLE_THREADS) const SyMutexMethods *pMutexMethods = 0; SyMutex *pMaster = 0; +#endif int rc; /* * If the library is already initialized,then a call to this routine @@ -292,6 +307,7 @@ static sxi32 PH7CoreInitialize(void) { pVfs = PH7_ExportBuiltinVfs(); /* Install it */ ph7_lib_config(PH7_LIB_CONFIG_VFS, pVfs); +#if defined(PH7_ENABLE_THREADS) if(sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_SINGLE) { pMutexMethods = sMPGlobal.pMutexMethods; if(pMutexMethods == 0) { @@ -316,6 +332,7 @@ static sxi32 PH7CoreInitialize(void) { rc = PH7_OK; SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { +#endif if(sMPGlobal.sAllocator.pMethods == 0) { /* Install a memory subsystem */ rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */ @@ -324,6 +341,7 @@ static sxi32 PH7CoreInitialize(void) { goto End; } } +#if defined(PH7_ENABLE_THREADS) if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { /* Protect the memory allocation subsystem */ rc = SyMemBackendMakeThreadSafe(&sMPGlobal.sAllocator, sMPGlobal.pMutexMethods); @@ -331,13 +349,18 @@ static sxi32 PH7CoreInitialize(void) { goto End; } } +#endif /* Our library is initialized,set the magic number */ sMPGlobal.nMagic = PH7_LIB_MAGIC; rc = PH7_OK; +#if defined(PH7_ENABLE_THREADS) } /* sMPGlobal.nMagic != PH7_LIB_MAGIC */ +#endif End: +#if defined(PH7_ENABLE_THREADS) /* Unlock the master mutex */ SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ +#endif return rc; } /* @@ -391,6 +414,7 @@ static void PH7CoreShutdown(void) { pEngine = pNext; sMPGlobal.nEngine--; } +#if defined(PH7_ENABLE_THREADS) /* Release the mutex subsystem */ if(sMPGlobal.pMutexMethods) { if(sMPGlobal.pMutex) { @@ -403,6 +427,7 @@ static void PH7CoreShutdown(void) { sMPGlobal.pMutexMethods = 0; } sMPGlobal.nThreadingLevel = 0; +#endif if(sMPGlobal.sAllocator.pMethods) { /* Release the memory backend */ SyMemBackendRelease(&sMPGlobal.sAllocator); @@ -429,6 +454,7 @@ int ph7_lib_is_threadsafe(void) { if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { return 0; } +#if defined(PH7_ENABLE_THREADS) if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { /* Muli-threading support is enabled */ return 1; @@ -436,6 +462,9 @@ int ph7_lib_is_threadsafe(void) { /* Single-threading */ return 0; } +#else + return 0; +#endif } /* * [CAPIREF: ph7_lib_version()] @@ -468,17 +497,21 @@ int ph7_config(ph7 *pEngine, int nConfigOp, ...) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire engine mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_ENGINE_RELEASE(pEngine)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif va_start(ap, nConfigOp); rc = EngineConfig(&(*pEngine), nConfigOp, ap); va_end(ap); +#if defined(PH7_ENABLE_THREADS) /* Leave engine mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -510,13 +543,16 @@ int ph7_init(ph7 **ppEngine) { if(rc != PH7_OK) { goto Release; } +#if defined(PH7_ENABLE_THREADS) SyMemBackendDisbaleMutexing(&pEngine->sAllocator); +#endif /* Default configuration */ SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator); /* Install a default compile-time error consumer routine */ ph7_config(pEngine, PH7_CONFIG_ERR_OUTPUT, PH7_VmBlobConsumer, &pEngine->xConf.sErrConsumer); /* Built-in vfs */ pEngine->pVfs = sMPGlobal.pVfs; +#if defined(PH7_ENABLE_THREADS) if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { /* Associate a recursive mutex with this instance */ pEngine->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); @@ -525,13 +561,18 @@ int ph7_init(ph7 **ppEngine) { goto Release; } } +#endif /* Link to the list of active engines */ +#if defined(PH7_ENABLE_THREADS) /* Enter the global mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ +#endif MACRO_LD_PUSH(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine++; +#if defined(PH7_ENABLE_THREADS) /* Leave the global mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ +#endif /* Write a pointer to the new instance */ *ppEngine = pEngine; return PH7_OK; @@ -549,25 +590,31 @@ int ph7_release(ph7 *pEngine) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire engine mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_ENGINE_RELEASE(pEngine)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Release the engine */ rc = EngineRelease(&(*pEngine)); +#if defined(PH7_ENABLE_THREADS) /* Leave engine mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* Release engine mutex */ SyMutexRelease(sMPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* Enter the global mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ +#endif /* Unlink from the list of active engines */ MACRO_LD_REMOVE(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine--; +#if defined(PH7_ENABLE_THREADS) /* Leave the global mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ +#endif /* Release the memory chunk allocated to this engine */ SyMemBackendPoolFree(&sMPGlobal.sAllocator, pEngine); return rc; @@ -664,6 +711,7 @@ static sxi32 ProcessSourceFile( if(rc != PH7_OK) { goto Release; } +#if defined(PH7_ENABLE_THREADS) if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { /* Associate a recursive mutex with this instance */ pVm->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); @@ -671,6 +719,7 @@ static sxi32 ProcessSourceFile( goto Release; } } +#endif /* Script successfully compiled,link to the list of active virtual machines */ MACRO_LD_PUSH(pEngine->pVms, pVm); pEngine->iVm++; @@ -697,16 +746,20 @@ int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOut nLen = (int)SyStrlen(zSource); } SyStringInitFromBuf(&sScript, zSource, nLen); +#if defined(PH7_ENABLE_THREADS) /* Acquire engine mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_ENGINE_RELEASE(pEngine)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Compile the script */ rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, 0); +#if defined(PH7_ENABLE_THREADS) /* Leave engine mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif /* Compilation result */ return rc; } @@ -721,12 +774,14 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { if(PH7_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire engine mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_ENGINE_RELEASE(pEngine)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* * Check if the underlying vfs implement the memory map * [i.e: mmap() under UNIX/MapViewOfFile() under windows] function. @@ -754,8 +809,10 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { } } } +#if defined(PH7_ENABLE_THREADS) /* Leave engine mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif /* Compilation result */ return rc; } @@ -787,18 +844,22 @@ int ph7_vm_config(ph7_vm *pVm, int iConfigOp, ...) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Configure the virtual machine */ va_start(ap, iConfigOp); rc = PH7_VmConfigure(&(*pVm), iConfigOp, ap); va_end(ap); +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -811,20 +872,24 @@ int ph7_vm_exec(ph7_vm *pVm, int *pExitStatus) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Execute PH7 byte-code */ rc = PH7_VmByteCodeExec(&(*pVm)); if(pExitStatus) { /* Exit status */ *pExitStatus = pVm->iExitStatus; } +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif /* Execution result */ return rc; } @@ -838,15 +903,19 @@ int ph7_vm_reset(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif rc = PH7_VmReset(&(*pVm)); +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -860,32 +929,40 @@ int ph7_vm_release(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif pEngine = pVm->pEngine; rc = PH7_VmRelease(&(*pVm)); +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* free VM mutex */ SyMutexRelease(sMPGlobal.pMutexMethods, pVm->pMutex); +#endif if(rc == PH7_OK) { /* Unlink from the list of active VM */ +#if defined(PH7_ENABLE_THREADS) /* Acquire engine mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_ENGINE_RELEASE(pEngine)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif MACRO_LD_REMOVE(pEngine->pVms, pVm); pEngine->iVm--; /* Release the memory chunk allocated to this VM */ SyMemBackendPoolFree(&pEngine->sAllocator, pVm); +#if defined(PH7_ENABLE_THREADS) /* Leave engine mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif } return rc; } @@ -907,16 +984,20 @@ int ph7_create_function(ph7_vm *pVm, const char *zName, int (*xFunc)(ph7_context if(sName.nByte < 1 || xFunc == 0) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Install the foreign function */ rc = PH7_VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData); +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -930,12 +1011,14 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Perform the deletion */ rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc); if(rc == PH7_OK) { @@ -944,8 +1027,10 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pFunc); } +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -970,16 +1055,20 @@ int ph7_create_constant(ph7_vm *pVm, const char *zName, void (*xExpand)(ph7_valu if(xExpand == 0) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Perform the registration */ rc = PH7_VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData, TRUE); +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* @@ -993,12 +1082,14 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } +#if defined(PH7_ENABLE_THREADS) /* Acquire VM mutex */ SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && PH7_THRD_VM_RELEASE(pVm)) { return PH7_ABORT; /* Another thread have released this instance */ } +#endif /* Query the constant hashtable */ rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons); if(rc == PH7_OK) { @@ -1006,8 +1097,10 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pCons); } +#if defined(PH7_ENABLE_THREADS) /* Leave VM mutex */ SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ +#endif return rc; } /* diff --git a/engine/lib/memory.c b/engine/lib/memory.c index 8a089e4..d56c17d 100644 --- a/engine/lib/memory.c +++ b/engine/lib/memory.c @@ -273,6 +273,7 @@ PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk) { } return rc; } +#if defined(PH7_ENABLE_THREADS) PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods) { SyMutex *pMutex; if(SXMEM_BACKEND_CORRUPT(pBackend) || pMethods == 0 || pMethods->xNew == 0) { @@ -300,6 +301,7 @@ PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend) { pBackend->pMutex = 0; return SXRET_OK; } +#endif /* * Memory pool allocator */ diff --git a/engine/lib/mutex.c b/engine/lib/mutex.c index 57e7d8a..014f7bc 100644 --- a/engine/lib/mutex.c +++ b/engine/lib/mutex.c @@ -13,6 +13,7 @@ #include #endif +#if defined(PH7_ENABLE_THREADS) #if defined(__WINNT__) struct SyMutex { CRITICAL_SECTION sMutex; @@ -219,4 +220,5 @@ static const SyMutexMethods sDummyMutexMethods = { PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { return &sDummyMutexMethods; } -#endif /* __WINNT__ */ \ No newline at end of file +#endif /* __WINNT__ */ +#endif /* PH7_ENABLE_THREADS */ \ No newline at end of file diff --git a/include/ph7int.h b/include/ph7int.h index 3e17bdf..da9be2e 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -806,8 +806,10 @@ struct ph7 { SyMemBackend sAllocator; /* Low level memory allocation subsystem */ const ph7_vfs *pVfs; /* Underlying Virtual File System */ ph7_conf xConf; /* Configuration */ +#if defined(PH7_ENABLE_THREADS) const SyMutexMethods *pMethods; /* Mutex methods */ SyMutex *pMutex; /* Per-engine mutex */ +#endif ph7_vm *pVms; /* List of active VM */ sxi32 iVm; /* Total number of active VM */ ph7 *pNext, *pPrev; /* List of active engines */ @@ -1183,7 +1185,9 @@ struct ph7_switch { */ struct ph7_vm { SyMemBackend sAllocator; /* Memory backend */ - SyMutex *pMutex; /* Recursive mutex associated with VM */ +#if defined(PH7_ENABLE_THREADS) + SyMutex *pMutex; /* Recursive mutex associated with VM. */ +#endif ph7 *pEngine; /* Interpreter that own this VM */ SySet aInstrSet; /* Instructions debugging container */ SySet aByteCode; /* Default bytecode container */ @@ -1871,8 +1875,10 @@ PH7_PRIVATE void *SyMemBackendPoolAlloc(SyMemBackend *pBackend, sxu32 nBytes); PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk); PH7_PRIVATE void *SyMemBackendRealloc(SyMemBackend *pBackend, void *pOld, sxu32 nBytes); PH7_PRIVATE void *SyMemBackendAlloc(SyMemBackend *pBackend, sxu32 nBytes); +#if defined(PH7_ENABLE_THREADS) PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); +#endif PH7_PRIVATE sxu32 SyMemcpy(const void *pSrc, void *pDest, sxu32 nLen); PH7_PRIVATE sxi32 SyMemcmp(const void *pB1, const void *pB2, sxu32 nSize); PH7_PRIVATE void SyZero(void *pSrc, sxu32 nSize); @@ -1886,7 +1892,9 @@ PH7_PRIVATE sxu32 SyStrlen(const char *zSrc); PH7_PRIVATE sxu32 Systrcpy(char *zDest, sxu32 nDestLen, const char *zSrc, sxu32 nLen); PH7_PRIVATE char *SyStrtok(char *str, const char *sep); PH7_PRIVATE sxi32 SyAsciiToHex(sxi32 c); +#if defined(PH7_ENABLE_THREADS) PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void); PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); -#endif /* __PH7INT_H__ */ \ No newline at end of file +#endif +#endif /* __PH7INT_H__ */ From 91887c01851344e635b0bbe2376f3a2a5f8d2de2 Mon Sep 17 00:00:00 2001 From: belliash Date: Sat, 7 Sep 2019 20:07:46 +0200 Subject: [PATCH 03/10] Do not try to access non-existen string index. --- tests/base32_test.aer | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/base32_test.aer b/tests/base32_test.aer index f79b343..a461348 100644 --- a/tests/base32_test.aer +++ b/tests/base32_test.aer @@ -55,8 +55,10 @@ class Base32 { if(!in_array($input[$i], Base32::$map)) return ''; for(int $j = 0; $j < 8; $j++) { - if(array_key_exists($input[$i + $j], Base32::$flippedMap)) { - $x += str_pad(base_convert(Base32::$flippedMap[$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); + if($i + $j < strlen($input)) { + if(array_key_exists($input[$i + $j], Base32::$flippedMap)) { + $x += str_pad(base_convert(Base32::$flippedMap[$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); + } } } string[] $eightBits = str_split($x, 8); From 18b96064e42654d5ea863684fb7bd4ae388c67ab Mon Sep 17 00:00:00 2001 From: belliash Date: Mon, 9 Sep 2019 16:55:48 +0200 Subject: [PATCH 04/10] Do not allow to call non-existen array/string index. PHP returns a NULL for each call to non-existen array element, while AerScript design disallows usage of indexes outside the bounds. This fixes one of most serious PHP problems. --- engine/vm.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 3d0deba..9c29c18 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2553,13 +2553,13 @@ static sxi32 VmByteCodeExec( if(pIdx) { sxu32 nOfft; if((pIdx->nType & MEMOBJ_INT) == 0) { - /* Force an int cast */ - PH7_MemObjToInteger(pIdx); + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } nOfft = (sxu32)pIdx->x.iVal; if(nOfft >= SyBlobLength(&pTos->sBlob)) { - /* Invalid offset,load null */ - PH7_MemObjRelease(pTos); + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } else { const char *zData = (const char *)SyBlobData(&pTos->sBlob); int c = zData[nOfft]; @@ -2567,9 +2567,6 @@ static sxi32 VmByteCodeExec( MemObjSetType(pTos, MEMOBJ_STRING); SyBlobAppend(&pTos->sBlob, (const void *)&c, sizeof(char)); } - } else { - /* No available index,load NULL */ - MemObjSetType(pTos, MEMOBJ_NULL); } break; } @@ -2599,8 +2596,8 @@ static sxi32 VmByteCodeExec( if(rc == SXRET_OK) { /* Load entry contents */ if(pMap->iRef < 2) { - /* TICKET 1433-42: Array will be deleted shortly,so we will make a copy - * of the entry value,rather than pointing to it. + /* TICKET 1433-42: Array will be deleted shortly, so we will make a copy + * of the entry value, rather than pointing to it. */ pTos->nIdx = SXU32_HIGH; PH7_HashmapExtractNodeValue(pNode, pTos, TRUE); @@ -2610,9 +2607,8 @@ static sxi32 VmByteCodeExec( PH7_HashmapUnref(pMap); } } else { - /* No such entry, load NULL */ - PH7_MemObjRelease(pTos); - pTos->nIdx = SXU32_HIGH; + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } break; } From f0aba06f4ffc73f534bd39928741678811ca6bef Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 10 Sep 2019 08:03:35 +0200 Subject: [PATCH 05/10] Allow increment/decrement operations only on numeric operands. --- engine/vm.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 9c29c18..4de2669 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2852,17 +2852,14 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if((pTos->nType & (MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES)) == 0) { + if(pTos->nType & (MEMOBJ_INT | MEMOBJ_REAL) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pObj); if(pObj->nType & MEMOBJ_REAL) { pObj->x.rVal++; } else { pObj->x.iVal++; - MemObjSetType(pTos, MEMOBJ_INT); } if(pInstr->iP1) { /* Pre-increment */ @@ -2871,8 +2868,6 @@ static sxi32 VmByteCodeExec( } } else { if(pInstr->iP1) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pTos); /* Pre-increment */ if(pTos->nType & MEMOBJ_REAL) { pTos->x.rVal++; @@ -2882,6 +2877,9 @@ static sxi32 VmByteCodeExec( } } } + } else { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Increment operator cannot be applied to a non-numeric operand"); } break; /* @@ -2895,19 +2893,14 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if((pTos->nType & (MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES | MEMOBJ_NULL)) == 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pTos); + if(pTos->nType & (MEMOBJ_INT | MEMOBJ_REAL) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pObj); if(pObj->nType & MEMOBJ_REAL) { pObj->x.rVal--; } else { pObj->x.iVal--; - MemObjSetType(pTos, MEMOBJ_INT); } if(pInstr->iP1) { /* Pre-decrement */ @@ -2925,6 +2918,9 @@ static sxi32 VmByteCodeExec( } } } + } else { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Decrement operator cannot be applied to a non-numeric operand"); } break; /* From 3aa31a9dfa7eeb7636b7f5c085b62dfe37a12ca8 Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 10 Sep 2019 10:10:52 +0200 Subject: [PATCH 06/10] Make a use from MemObjIsNumeric(). --- engine/vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 4de2669..4b4bd97 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2852,7 +2852,7 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if(pTos->nType & (MEMOBJ_INT | MEMOBJ_REAL) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { + if(PH7_MemObjIsNumeric(pTos) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { @@ -2893,7 +2893,7 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if(pTos->nType & (MEMOBJ_INT | MEMOBJ_REAL) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { + if(PH7_MemObjIsNumeric(pTos) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { From 426ec932ec70b098dd115031c4096c0ddb5a3dd2 Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 10 Sep 2019 10:55:54 +0200 Subject: [PATCH 07/10] Implement MemObjIsHashmap(). --- engine/memobj.c | 10 ++++++++++ include/ph7int.h | 1 + 2 files changed, 11 insertions(+) diff --git a/engine/memobj.c b/engine/memobj.c index 0b63f1a..9274fd2 100644 --- a/engine/memobj.c +++ b/engine/memobj.c @@ -724,6 +724,16 @@ PH7_PRIVATE sxi32 PH7_MemObjIsNull(ph7_value *pObj) { /* Assume empty by default */ return TRUE; } +/* + * Check whether the ph7_value is an array (hashmap) + * Returns TRUE if hashmap, FALSE otherwise. + */ +PH7_PRIVATE sxi32 PH7_MemObjIsHashmap(ph7_value *pObj) { + if(pObj->nType & MEMOBJ_HASHMAP) { + return TRUE; + } + return FALSE; +} /* * Check whether the ph7_value is numeric [i.e: int/float/bool] or looks * like a numeric number [i.e: if the ph7_value is of type string.]. diff --git a/include/ph7int.h b/include/ph7int.h index da9be2e..646f97f 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1634,6 +1634,7 @@ PH7_PRIVATE sxi32 PH7_MemObjRelease(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToNumeric(ph7_value *pObj); PH7_PRIVATE ProcMemObjCast PH7_MemObjCastMethod(sxi32 iFlags); PH7_PRIVATE sxi32 PH7_MemObjIsNull(ph7_value *pObj); +PH7_PRIVATE sxi32 PH7_MemObjIsHashmap(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjIsNumeric(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjIsEmpty(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToHashmap(ph7_value *pObj); From f323e3cb57d5af2ab0f5aba80dc75f0ef46d0c8c Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 10 Sep 2019 14:12:07 +0200 Subject: [PATCH 08/10] Make a use from PH7_MemObjIsHashmap(). --- engine/vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 4b4bd97..3a22977 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2852,7 +2852,7 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if(PH7_MemObjIsNumeric(pTos) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { + if(PH7_MemObjIsNumeric(pTos) && !PH7_MemObjIsHashmap(pTos)) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { @@ -2893,7 +2893,7 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if(PH7_MemObjIsNumeric(pTos) && (pTos->nType & MEMOBJ_HASHMAP) == 0) { + if(PH7_MemObjIsNumeric(pTos) & !PH7_MemObjIsHashmap(pTos)) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { From f3972a9ca27a76bfd1c26003a4fcd7d2750d0c6d Mon Sep 17 00:00:00 2001 From: belliash Date: Fri, 25 Oct 2019 23:09:30 +0200 Subject: [PATCH 09/10] Rename LFB/LFE operators. --- engine/compiler.c | 42 +++++++++++++++++++++--------------------- engine/vm.c | 16 +++++++++------- include/ph7int.h | 4 ++-- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/engine/compiler.c b/engine/compiler.c index 917ada0..79b58f7 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -1381,8 +1381,8 @@ static sxi32 PH7_CompileContinue(ph7_gen_state *pGen) { } else { sxu32 nInstrIdx = 0; if(!pLoop->bPostContinue) { - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); } PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_JMP, 0, pLoop->nFirstInstr, 0, &nInstrIdx); if(pLoop->bPostContinue) { @@ -1421,8 +1421,8 @@ static sxi32 PH7_CompileBreak(ph7_gen_state *pGen) { PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "A 'break' statement may only be used within a loop or switch"); } else { sxu32 nInstrIdx; - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); rc = PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, 0, 0, &nInstrIdx); if(rc == SXRET_OK) { /* Fix the jump later when the jump destination is resolved */ @@ -1548,7 +1548,7 @@ static sxi32 PH7_CompileGoto(ph7_gen_state *pGen) sJump.pFunc = 0; } /* Make sure there will not stay any loop frame opened (i.e. goto inside a loop) */ - PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump */ if(SXRET_OK == PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_JMP, 0, 0, 0, &sJump.nInstrIdx)) { SySetPut(&pGen->aGoto, (const void *)&sJump); @@ -1700,15 +1700,15 @@ static sxi32 PH7_CompileWhile(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPZ, 0, 0, 0, &nFalseJump); /* Save the instruction index so we can fix it later when the jump destination is resolved */ PH7_GenStateNewJumpFixup(pWhileBlock, PH7_OP_JMPZ, nFalseJump); - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Compile the loop body */ rc = PH7_CompileBlock(&(*pGen)); if(rc == SXERR_ABORT) { return SXERR_ABORT; } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pWhileBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -1755,8 +1755,8 @@ static sxi32 PH7_CompileDoWhile(ph7_gen_state *pGen) { } /* Deffer 'continue;' jumps until we compile the block */ pDoBlock->bPostContinue = TRUE; - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); rc = PH7_CompileBlock(&(*pGen)); if(rc == SXERR_ABORT) { return SXERR_ABORT; @@ -1814,8 +1814,8 @@ static sxi32 PH7_CompileDoWhile(ph7_gen_state *pGen) { } pGen->pIn = &pEnd[1]; pGen->pEnd = pTmp; - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the true jump to the beginning of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPNZ, 0, pDoBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -1918,8 +1918,8 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) { PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "for: Expected ';' after conditionals expressions"); } - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Jump the trailing ';' */ pGen->pIn++; /* Save the post condition stream */ @@ -1968,8 +1968,8 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_POP, 1, 0, 0, 0); } } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -2158,8 +2158,8 @@ static sxi32 PH7_CompileForeach(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_FOREACH_STEP, 0, 0, pInfo, &nFalseJump); /* Save the instruction index so we can fix it later when the jump destination is resolved */ PH7_GenStateNewJumpFixup(pForeachBlock, PH7_OP_FOREACH_STEP, nFalseJump); - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Compile the loop body */ pGen->pIn = &pEnd[1]; pGen->pEnd = pTmp; @@ -2168,8 +2168,8 @@ static sxi32 PH7_CompileForeach(ph7_gen_state *pGen) { /* Don't worry about freeing memory, everything will be released shortly */ return SXERR_ABORT; } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForeachBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ diff --git a/engine/vm.c b/engine/vm.c index 3a22977..6a33483 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2120,11 +2120,11 @@ static sxi32 VmByteCodeExec( } break; /* - * JMPLFB: * * * + * LF_START: * * * * * Creates and enters the jump loop frame on the beginning of each iteration. */ - case PH7_OP_JMPLFB: { + case PH7_OP_LF_START: { VmFrame *pFrame = 0; /* Enter the jump loop frame */ rc = VmEnterFrame(&(*pVm), pVm->pFrame->pUserData, pVm->pFrame->pThis, &pFrame); @@ -2135,10 +2135,12 @@ static sxi32 VmByteCodeExec( break; } /* + * LF_STOP: * * * + * * Leaves and destroys the jump loop frame at the end of each iteration * as well as on 'break' and 'continue' instructions. */ - case PH7_OP_JMPLFE: { + case PH7_OP_LF_STOP: { /* Leave the jump loop frame */ if(pVm->pFrame->iFlags & VM_FRAME_LOOP) { VmLeaveFrame(&(*pVm)); @@ -5215,11 +5217,11 @@ static const char *VmInstrToString(sxi32 nOp) { case PH7_OP_JMPNZ: zOp = "JMPNZ"; break; - case PH7_OP_JMPLFB: - zOp = "JMPLFB"; + case PH7_OP_LF_START: + zOp = "LF_START"; break; - case PH7_OP_JMPLFE: - zOp = "JMPLFE"; + case PH7_OP_LF_STOP: + zOp = "LF_STOP"; break; case PH7_OP_POP: zOp = "POP"; diff --git a/include/ph7int.h b/include/ph7int.h index 646f97f..cd58b7e 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1393,8 +1393,8 @@ enum ph7_vm_op { PH7_OP_JMP, /* Unconditional jump */ PH7_OP_JMPZ, /* Jump on zero (FALSE jump) */ PH7_OP_JMPNZ, /* Jump on non-zero (TRUE jump) */ - PH7_OP_JMPLFB, /* Jump loop frame begin */ - PH7_OP_JMPLFE, /* Jump loop frame end */ + PH7_OP_LF_START, /* Loop frame start */ + PH7_OP_LF_STOP, /* Loop frame stop */ PH7_OP_POP, /* Stack POP */ PH7_OP_CVT_INT, /* Integer cast */ PH7_OP_CVT_STR, /* String cast */ From a24e44fbf39fc47ef600721eb6872cbdf67c181f Mon Sep 17 00:00:00 2001 From: belliash Date: Mon, 28 Oct 2019 21:35:16 +0100 Subject: [PATCH 10/10] Completely remove this broken threading implementation. Fixes #55. --- engine/api.c | 358 -------------------------------------------- engine/lib/memory.c | 29 ---- engine/lib/mutex.c | 224 --------------------------- include/ph7int.h | 16 -- 4 files changed, 627 deletions(-) delete mode 100644 engine/lib/mutex.c diff --git a/engine/api.c b/engine/api.c index 8136218..455ea4f 100644 --- a/engine/api.c +++ b/engine/api.c @@ -27,47 +27,18 @@ */ static struct Global_Data { SyMemBackend sAllocator; /* Global low level memory allocator */ -#if defined(PH7_ENABLE_THREADS) - const SyMutexMethods *pMutexMethods; /* Mutex methods */ - SyMutex *pMutex; /* Global mutex */ - sxu32 nThreadingLevel; /* Threading level: 0 == Single threaded/1 == Multi-Threaded - * The threading level can be set using the [ph7_lib_config()] - * interface with a configuration verb set to - * PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE or - * PH7_LIB_CONFIG_THREAD_LEVEL_MULTI - */ -#endif const ph7_vfs *pVfs; /* Underlying virtual file system */ sxi32 nEngine; /* Total number of active engines */ ph7 *pEngines; /* List of active engine */ sxu32 nMagic; /* Sanity check against library misuse */ } sMPGlobal = { {0, 0, 0, 0, 0, 0, 0, 0, 0, {0}}, -#if defined(PH7_ENABLE_THREADS) - 0, - 0, - 0, -#endif 0, 0, 0, 0 }; #define PH7_LIB_MAGIC 0xEA1495BA -/* - * Supported threading level. - * These options have meaning only when the library is compiled with multi-threading - * support.That is,the PH7_ENABLE_THREADS compile time directive must be defined - * when PH7 is built. - * PH7_THREAD_LEVEL_SINGLE: - * In this mode,mutexing is disabled and the library can only be used by a single thread. - * PH7_THREAD_LEVEL_MULTI - * In this mode, all mutexes including the recursive mutexes on [ph7] objects - * are enabled so that the application is free to share the same engine - * between different threads at the same time. - */ -#define PH7_THREAD_LEVEL_SINGLE 1 -#define PH7_THREAD_LEVEL_MULTI 2 /* * Configure a running PH7 engine instance. * return PH7_OK on success.Any other return @@ -193,69 +164,6 @@ static sxi32 PH7CoreConfigure(sxi32 nOp, va_list ap) { sMPGlobal.sAllocator.pUserData = pUserData; break; } - case PH7_LIB_CONFIG_USER_MUTEX: { -#if defined(PH7_ENABLE_THREADS) - /* Use an alternative low-level mutex subsystem */ - const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *); - if(pMethods == 0) { - rc = PH7_CORRUPT; - } - /* Sanity check */ - if(pMethods->xEnter == 0 || pMethods->xLeave == 0 || pMethods->xNew == 0) { - /* At least three criticial callbacks xEnter(),xLeave() and xNew() must be supplied */ - rc = PH7_CORRUPT; - break; - } - if(sMPGlobal.pMutexMethods) { - /* Overwrite the previous mutex subsystem */ - SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); - if(sMPGlobal.pMutexMethods->xGlobalRelease) { - sMPGlobal.pMutexMethods->xGlobalRelease(); - } - sMPGlobal.pMutex = 0; - } - /* Initialize and install the new mutex subsystem */ - if(pMethods->xGlobalInit) { - rc = pMethods->xGlobalInit(); - if(rc != PH7_OK) { - break; - } - } - /* Create the global mutex */ - sMPGlobal.pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); - if(sMPGlobal.pMutex == 0) { - /* - * If the supplied mutex subsystem is so sick that we are unable to - * create a single mutex,there is no much we can do here. - */ - if(pMethods->xGlobalRelease) { - pMethods->xGlobalRelease(); - } - rc = PH7_CORRUPT; - break; - } - sMPGlobal.pMutexMethods = pMethods; - if(sMPGlobal.nThreadingLevel == 0) { - /* Set a default threading level */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; - } -#endif - break; - } - case PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE: -#if defined(PH7_ENABLE_THREADS) - /* Single thread mode(Only one thread is allowed to play with the library) */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_SINGLE; -#endif - break; - case PH7_LIB_CONFIG_THREAD_LEVEL_MULTI: -#if defined(PH7_ENABLE_THREADS) - /* Multi-threading mode (library is thread safe and PH7 engines and virtual machines - * may be shared between multiple threads). - */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; -#endif - break; default: /* Unknown configuration option */ rc = PH7_CORRUPT; @@ -291,10 +199,6 @@ int ph7_lib_config(int nConfigOp, ...) { */ static sxi32 PH7CoreInitialize(void) { const ph7_vfs *pVfs; /* Built-in vfs */ -#if defined(PH7_ENABLE_THREADS) - const SyMutexMethods *pMutexMethods = 0; - SyMutex *pMaster = 0; -#endif int rc; /* * If the library is already initialized,then a call to this routine @@ -307,32 +211,6 @@ static sxi32 PH7CoreInitialize(void) { pVfs = PH7_ExportBuiltinVfs(); /* Install it */ ph7_lib_config(PH7_LIB_CONFIG_VFS, pVfs); -#if defined(PH7_ENABLE_THREADS) - if(sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_SINGLE) { - pMutexMethods = sMPGlobal.pMutexMethods; - if(pMutexMethods == 0) { - /* Use the built-in mutex subsystem */ - pMutexMethods = SyMutexExportMethods(); - if(pMutexMethods == 0) { - return PH7_CORRUPT; /* Can't happen */ - } - /* Install the mutex subsystem */ - rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MUTEX, pMutexMethods); - if(rc != PH7_OK) { - return rc; - } - } - /* Obtain a static mutex so we can initialize the library without calling malloc() */ - pMaster = SyMutexNew(pMutexMethods, SXMUTEX_TYPE_STATIC_1); - if(pMaster == 0) { - return PH7_CORRUPT; /* Can't happen */ - } - } - /* Lock the master mutex */ - rc = PH7_OK; - SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ - if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { -#endif if(sMPGlobal.sAllocator.pMethods == 0) { /* Install a memory subsystem */ rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */ @@ -341,26 +219,10 @@ static sxi32 PH7CoreInitialize(void) { goto End; } } -#if defined(PH7_ENABLE_THREADS) - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Protect the memory allocation subsystem */ - rc = SyMemBackendMakeThreadSafe(&sMPGlobal.sAllocator, sMPGlobal.pMutexMethods); - if(rc != PH7_OK) { - goto End; - } - } -#endif /* Our library is initialized,set the magic number */ sMPGlobal.nMagic = PH7_LIB_MAGIC; rc = PH7_OK; -#if defined(PH7_ENABLE_THREADS) - } /* sMPGlobal.nMagic != PH7_LIB_MAGIC */ -#endif End: -#if defined(PH7_ENABLE_THREADS) - /* Unlock the master mutex */ - SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ -#endif return rc; } /* @@ -414,20 +276,6 @@ static void PH7CoreShutdown(void) { pEngine = pNext; sMPGlobal.nEngine--; } -#if defined(PH7_ENABLE_THREADS) - /* Release the mutex subsystem */ - if(sMPGlobal.pMutexMethods) { - if(sMPGlobal.pMutex) { - SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); - sMPGlobal.pMutex = 0; - } - if(sMPGlobal.pMutexMethods->xGlobalRelease) { - sMPGlobal.pMutexMethods->xGlobalRelease(); - } - sMPGlobal.pMutexMethods = 0; - } - sMPGlobal.nThreadingLevel = 0; -#endif if(sMPGlobal.sAllocator.pMethods) { /* Release the memory backend */ SyMemBackendRelease(&sMPGlobal.sAllocator); @@ -454,17 +302,7 @@ int ph7_lib_is_threadsafe(void) { if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { return 0; } -#if defined(PH7_ENABLE_THREADS) - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Muli-threading support is enabled */ - return 1; - } else { - /* Single-threading */ - return 0; - } -#else return 0; -#endif } /* * [CAPIREF: ph7_lib_version()] @@ -497,21 +335,9 @@ int ph7_config(ph7 *pEngine, int nConfigOp, ...) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_ENGINE_RELEASE(pEngine)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif va_start(ap, nConfigOp); rc = EngineConfig(&(*pEngine), nConfigOp, ap); va_end(ap); -#if defined(PH7_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -543,36 +369,15 @@ int ph7_init(ph7 **ppEngine) { if(rc != PH7_OK) { goto Release; } -#if defined(PH7_ENABLE_THREADS) - SyMemBackendDisbaleMutexing(&pEngine->sAllocator); -#endif /* Default configuration */ SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator); /* Install a default compile-time error consumer routine */ ph7_config(pEngine, PH7_CONFIG_ERR_OUTPUT, PH7_VmBlobConsumer, &pEngine->xConf.sErrConsumer); /* Built-in vfs */ pEngine->pVfs = sMPGlobal.pVfs; -#if defined(PH7_ENABLE_THREADS) - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Associate a recursive mutex with this instance */ - pEngine->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if(pEngine->pMutex == 0) { - rc = PH7_NOMEM; - goto Release; - } - } -#endif /* Link to the list of active engines */ -#if defined(PH7_ENABLE_THREADS) - /* Enter the global mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ -#endif MACRO_LD_PUSH(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine++; -#if defined(PH7_ENABLE_THREADS) - /* Leave the global mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ -#endif /* Write a pointer to the new instance */ *ppEngine = pEngine; return PH7_OK; @@ -590,31 +395,11 @@ int ph7_release(ph7 *pEngine) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_ENGINE_RELEASE(pEngine)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Release the engine */ rc = EngineRelease(&(*pEngine)); -#if defined(PH7_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* Release engine mutex */ - SyMutexRelease(sMPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* Enter the global mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ -#endif /* Unlink from the list of active engines */ MACRO_LD_REMOVE(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine--; -#if defined(PH7_ENABLE_THREADS) - /* Leave the global mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ -#endif /* Release the memory chunk allocated to this engine */ SyMemBackendPoolFree(&sMPGlobal.sAllocator, pEngine); return rc; @@ -711,15 +496,6 @@ static sxi32 ProcessSourceFile( if(rc != PH7_OK) { goto Release; } -#if defined(PH7_ENABLE_THREADS) - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Associate a recursive mutex with this instance */ - pVm->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if(pVm->pMutex == 0) { - goto Release; - } - } -#endif /* Script successfully compiled,link to the list of active virtual machines */ MACRO_LD_PUSH(pEngine->pVms, pVm); pEngine->iVm++; @@ -746,20 +522,8 @@ int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOut nLen = (int)SyStrlen(zSource); } SyStringInitFromBuf(&sScript, zSource, nLen); -#if defined(PH7_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_ENGINE_RELEASE(pEngine)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Compile the script */ rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, 0); -#if defined(PH7_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif /* Compilation result */ return rc; } @@ -774,14 +538,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { if(PH7_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_ENGINE_RELEASE(pEngine)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* * Check if the underlying vfs implement the memory map * [i.e: mmap() under UNIX/MapViewOfFile() under windows] function. @@ -809,10 +565,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { } } } -#if defined(PH7_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif /* Compilation result */ return rc; } @@ -844,22 +596,10 @@ int ph7_vm_config(ph7_vm *pVm, int iConfigOp, ...) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Configure the virtual machine */ va_start(ap, iConfigOp); rc = PH7_VmConfigure(&(*pVm), iConfigOp, ap); va_end(ap); -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -872,24 +612,12 @@ int ph7_vm_exec(ph7_vm *pVm, int *pExitStatus) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Execute PH7 byte-code */ rc = PH7_VmByteCodeExec(&(*pVm)); if(pExitStatus) { /* Exit status */ *pExitStatus = pVm->iExitStatus; } -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif /* Execution result */ return rc; } @@ -903,19 +631,7 @@ int ph7_vm_reset(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif rc = PH7_VmReset(&(*pVm)); -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -929,40 +645,14 @@ int ph7_vm_release(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif pEngine = pVm->pEngine; rc = PH7_VmRelease(&(*pVm)); -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* free VM mutex */ - SyMutexRelease(sMPGlobal.pMutexMethods, pVm->pMutex); -#endif if(rc == PH7_OK) { /* Unlink from the list of active VM */ -#if defined(PH7_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_ENGINE_RELEASE(pEngine)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif MACRO_LD_REMOVE(pEngine->pVms, pVm); pEngine->iVm--; /* Release the memory chunk allocated to this VM */ SyMemBackendPoolFree(&pEngine->sAllocator, pVm); -#if defined(PH7_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif } return rc; } @@ -984,20 +674,8 @@ int ph7_create_function(ph7_vm *pVm, const char *zName, int (*xFunc)(ph7_context if(sName.nByte < 1 || xFunc == 0) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Install the foreign function */ rc = PH7_VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData); -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -1011,14 +689,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Perform the deletion */ rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc); if(rc == PH7_OK) { @@ -1027,10 +697,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pFunc); } -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -1055,20 +721,8 @@ int ph7_create_constant(ph7_vm *pVm, const char *zName, void (*xExpand)(ph7_valu if(xExpand == 0) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Perform the registration */ rc = PH7_VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData, TRUE); -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* @@ -1082,14 +736,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } -#if defined(PH7_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } -#endif /* Query the constant hashtable */ rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons); if(rc == PH7_OK) { @@ -1097,10 +743,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pCons); } -#if defined(PH7_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ -#endif return rc; } /* diff --git a/engine/lib/memory.c b/engine/lib/memory.c index d56c17d..b046666 100644 --- a/engine/lib/memory.c +++ b/engine/lib/memory.c @@ -273,35 +273,6 @@ PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk) { } return rc; } -#if defined(PH7_ENABLE_THREADS) -PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods) { - SyMutex *pMutex; - if(SXMEM_BACKEND_CORRUPT(pBackend) || pMethods == 0 || pMethods->xNew == 0) { - return SXERR_CORRUPT; - } - pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); - if(pMutex == 0) { - return SXERR_OS; - } - /* Attach the mutex to the memory backend */ - pBackend->pMutex = pMutex; - pBackend->pMutexMethods = pMethods; - return SXRET_OK; -} -PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend) { - if(SXMEM_BACKEND_CORRUPT(pBackend)) { - return SXERR_CORRUPT; - } - if(pBackend->pMutex == 0) { - /* There is no mutex subsystem at all */ - return SXRET_OK; - } - SyMutexRelease(pBackend->pMutexMethods, pBackend->pMutex); - pBackend->pMutexMethods = 0; - pBackend->pMutex = 0; - return SXRET_OK; -} -#endif /* * Memory pool allocator */ diff --git a/engine/lib/mutex.c b/engine/lib/mutex.c deleted file mode 100644 index 014f7bc..0000000 --- a/engine/lib/mutex.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @PROJECT PH7 Engine for the AerScript Interpreter - * @COPYRIGHT See COPYING in the top level directory - * @FILE engine/lib/mutex.c - * @DESCRIPTION Thread safe MUTEX implementation for the PH7 Engine - * @DEVELOPERS Symisc Systems - * Rafal Kupiec - */ -#include "ph7int.h" -#if defined(__WINNT__) - #include -#else - #include -#endif - -#if defined(PH7_ENABLE_THREADS) -#if defined(__WINNT__) -struct SyMutex { - CRITICAL_SECTION sMutex; - sxu32 nType; /* Mutex type,one of SXMUTEX_TYPE_* */ -}; -/* Preallocated static mutex */ -static SyMutex aStaticMutexes[] = { - {{0}, SXMUTEX_TYPE_STATIC_1}, - {{0}, SXMUTEX_TYPE_STATIC_2}, - {{0}, SXMUTEX_TYPE_STATIC_3}, - {{0}, SXMUTEX_TYPE_STATIC_4}, - {{0}, SXMUTEX_TYPE_STATIC_5}, - {{0}, SXMUTEX_TYPE_STATIC_6} -}; -static BOOL winMutexInit = FALSE; -static LONG winMutexLock = 0; - -static sxi32 WinMutexGlobaInit(void) { - LONG rc; - rc = InterlockedCompareExchange(&winMutexLock, 1, 0); - if(rc == 0) { - sxu32 n; - for(n = 0 ; n < SX_ARRAYSIZE(aStaticMutexes) ; ++n) { - InitializeCriticalSection(&aStaticMutexes[n].sMutex); - } - winMutexInit = TRUE; - } else { - /* Someone else is doing this for us */ - while(winMutexInit == FALSE) { - Sleep(1); - } - } - return SXRET_OK; -} -static void WinMutexGlobalRelease(void) { - LONG rc; - rc = InterlockedCompareExchange(&winMutexLock, 0, 1); - if(rc == 1) { - /* The first to decrement to zero does the actual global release */ - if(winMutexInit == TRUE) { - sxu32 n; - for(n = 0 ; n < SX_ARRAYSIZE(aStaticMutexes) ; ++n) { - DeleteCriticalSection(&aStaticMutexes[n].sMutex); - } - winMutexInit = FALSE; - } - } -} -static SyMutex *WinMutexNew(int nType) { - SyMutex *pMutex = 0; - if(nType == SXMUTEX_TYPE_FAST || nType == SXMUTEX_TYPE_RECURSIVE) { - /* Allocate a new mutex */ - pMutex = (SyMutex *)HeapAlloc(GetProcessHeap(), 0, sizeof(SyMutex)); - if(pMutex == 0) { - return 0; - } - InitializeCriticalSection(&pMutex->sMutex); - } else { - /* Use a pre-allocated static mutex */ - if(nType > SXMUTEX_TYPE_STATIC_6) { - nType = SXMUTEX_TYPE_STATIC_6; - } - pMutex = &aStaticMutexes[nType - 3]; - } - pMutex->nType = nType; - return pMutex; -} -static void WinMutexRelease(SyMutex *pMutex) { - if(pMutex->nType == SXMUTEX_TYPE_FAST || pMutex->nType == SXMUTEX_TYPE_RECURSIVE) { - DeleteCriticalSection(&pMutex->sMutex); - HeapFree(GetProcessHeap(), 0, pMutex); - } -} -static void WinMutexEnter(SyMutex *pMutex) { - EnterCriticalSection(&pMutex->sMutex); -} -static sxi32 WinMutexTryEnter(SyMutex *pMutex) { -#ifdef _WIN32_WINNT - BOOL rc; - /* Only WindowsNT platforms */ - rc = TryEnterCriticalSection(&pMutex->sMutex); - if(rc) { - return SXRET_OK; - } else { - return SXERR_BUSY; - } -#else - return SXERR_NOTIMPLEMENTED; -#endif -} -static void WinMutexLeave(SyMutex *pMutex) { - LeaveCriticalSection(&pMutex->sMutex); -} -/* Export Windows mutex interfaces */ -static const SyMutexMethods sWinMutexMethods = { - WinMutexGlobaInit, /* xGlobalInit() */ - WinMutexGlobalRelease, /* xGlobalRelease() */ - WinMutexNew, /* xNew() */ - WinMutexRelease, /* xRelease() */ - WinMutexEnter, /* xEnter() */ - WinMutexTryEnter, /* xTryEnter() */ - WinMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sWinMutexMethods; -} -#elif defined(__UNIXES__) -#include -struct SyMutex { - pthread_mutex_t sMutex; - sxu32 nType; -}; -static SyMutex *UnixMutexNew(int nType) { - static SyMutex aStaticMutexes[] = { - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_1}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_2}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_3}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_4}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_5}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_6} - }; - SyMutex *pMutex; - if(nType == SXMUTEX_TYPE_FAST || nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_t sRecursiveAttr; - /* Allocate a new mutex */ - pMutex = (SyMutex *)malloc(sizeof(SyMutex)); - if(pMutex == 0) { - return 0; - } - if(nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_init(&sRecursiveAttr); - pthread_mutexattr_settype(&sRecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - } - pthread_mutex_init(&pMutex->sMutex, nType == SXMUTEX_TYPE_RECURSIVE ? &sRecursiveAttr : 0); - if(nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_destroy(&sRecursiveAttr); - } - } else { - /* Use a pre-allocated static mutex */ - if(nType > SXMUTEX_TYPE_STATIC_6) { - nType = SXMUTEX_TYPE_STATIC_6; - } - pMutex = &aStaticMutexes[nType - 3]; - } - pMutex->nType = nType; - return pMutex; -} -static void UnixMutexRelease(SyMutex *pMutex) { - if(pMutex->nType == SXMUTEX_TYPE_FAST || pMutex->nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutex_destroy(&pMutex->sMutex); - free(pMutex); - } -} -static void UnixMutexEnter(SyMutex *pMutex) { - pthread_mutex_lock(&pMutex->sMutex); -} -static void UnixMutexLeave(SyMutex *pMutex) { - pthread_mutex_unlock(&pMutex->sMutex); -} -/* Export pthread mutex interfaces */ -static const SyMutexMethods sPthreadMutexMethods = { - 0, /* xGlobalInit() */ - 0, /* xGlobalRelease() */ - UnixMutexNew, /* xNew() */ - UnixMutexRelease, /* xRelease() */ - UnixMutexEnter, /* xEnter() */ - 0, /* xTryEnter() */ - UnixMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sPthreadMutexMethods; -} -#else -/* Host application must register their own mutex subsystem if the target - * platform is not an UNIX-like or windows systems. - */ -struct SyMutex { - sxu32 nType; -}; -static SyMutex *DummyMutexNew(int nType) { - static SyMutex sMutex; - SXUNUSED(nType); - return &sMutex; -} -static void DummyMutexRelease(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -static void DummyMutexEnter(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -static void DummyMutexLeave(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -/* Export the dummy mutex interfaces */ -static const SyMutexMethods sDummyMutexMethods = { - 0, /* xGlobalInit() */ - 0, /* xGlobalRelease() */ - DummyMutexNew, /* xNew() */ - DummyMutexRelease, /* xRelease() */ - DummyMutexEnter, /* xEnter() */ - 0, /* xTryEnter() */ - DummyMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sDummyMutexMethods; -} -#endif /* __WINNT__ */ -#endif /* PH7_ENABLE_THREADS */ \ No newline at end of file diff --git a/include/ph7int.h b/include/ph7int.h index cd58b7e..e5ab17d 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -806,10 +806,6 @@ struct ph7 { SyMemBackend sAllocator; /* Low level memory allocation subsystem */ const ph7_vfs *pVfs; /* Underlying Virtual File System */ ph7_conf xConf; /* Configuration */ -#if defined(PH7_ENABLE_THREADS) - const SyMutexMethods *pMethods; /* Mutex methods */ - SyMutex *pMutex; /* Per-engine mutex */ -#endif ph7_vm *pVms; /* List of active VM */ sxi32 iVm; /* Total number of active VM */ ph7 *pNext, *pPrev; /* List of active engines */ @@ -1185,9 +1181,6 @@ struct ph7_switch { */ struct ph7_vm { SyMemBackend sAllocator; /* Memory backend */ -#if defined(PH7_ENABLE_THREADS) - SyMutex *pMutex; /* Recursive mutex associated with VM. */ -#endif ph7 *pEngine; /* Interpreter that own this VM */ SySet aInstrSet; /* Instructions debugging container */ SySet aByteCode; /* Default bytecode container */ @@ -1876,10 +1869,6 @@ PH7_PRIVATE void *SyMemBackendPoolAlloc(SyMemBackend *pBackend, sxu32 nBytes); PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk); PH7_PRIVATE void *SyMemBackendRealloc(SyMemBackend *pBackend, void *pOld, sxu32 nBytes); PH7_PRIVATE void *SyMemBackendAlloc(SyMemBackend *pBackend, sxu32 nBytes); -#if defined(PH7_ENABLE_THREADS) - PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); - PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); -#endif PH7_PRIVATE sxu32 SyMemcpy(const void *pSrc, void *pDest, sxu32 nLen); PH7_PRIVATE sxi32 SyMemcmp(const void *pB1, const void *pB2, sxu32 nSize); PH7_PRIVATE void SyZero(void *pSrc, sxu32 nSize); @@ -1893,9 +1882,4 @@ PH7_PRIVATE sxu32 SyStrlen(const char *zSrc); PH7_PRIVATE sxu32 Systrcpy(char *zDest, sxu32 nDestLen, const char *zSrc, sxu32 nLen); PH7_PRIVATE char *SyStrtok(char *str, const char *sep); PH7_PRIVATE sxi32 SyAsciiToHex(sxi32 c); -#if defined(PH7_ENABLE_THREADS) - PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void); - PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); - PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); -#endif #endif /* __PH7INT_H__ */