diff --git a/PHP/Release/php7.3nts-vc15-php_snowdrift.zip b/PHP/Release/php7.3nts-vc15-php_snowdrift.zip new file mode 100644 index 0000000..3eb07ef Binary files /dev/null and b/PHP/Release/php7.3nts-vc15-php_snowdrift.zip differ diff --git a/PHP/Release/php7.4nts-vc15-php_snowdrift.zip b/PHP/Release/php7.4nts-vc15-php_snowdrift.zip new file mode 100644 index 0000000..c34673b Binary files /dev/null and b/PHP/Release/php7.4nts-vc15-php_snowdrift.zip differ diff --git a/PHP/Release/php8.0nts-vs16-php_snowdrift.zip b/PHP/Release/php8.0nts-vs16-php_snowdrift.zip new file mode 100644 index 0000000..639b86a Binary files /dev/null and b/PHP/Release/php8.0nts-vs16-php_snowdrift.zip differ diff --git a/PHP/config.w32 b/PHP/config.w32 index 8d6432e..4a8ded4 100644 --- a/PHP/config.w32 +++ b/PHP/config.w32 @@ -1,18 +1,13 @@ -// $Id$ // vim:ft=javascript -// If your extension references something external, use ARG_WITH -// ARG_WITH("snowdrift", "for snowdrift support", "no"); - -// Otherwise, use ARG_ENABLE -ARG_ENABLE("snowdrift", "enable snowdrift support", "no"); +ARG_ENABLE('snowdrift', 'snowdrift support', 'no'); if (PHP_SNOWDRIFT != "no") { + AC_DEFINE('HAVE_SNOWDRIFT', 1, 'snowdrift support enabled'); snowdrift_source_file="snowdrift.c\ src/snowflake/snowflake.c\ src/snowflake/shm.c\ - src/snowflake/spinlock.c - " - EXTENSION("snowdrift", $snowdrift_source_file, PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + src/snowflake/spinlock.c" + EXTENSION("snowdrift", snowdrift_source_file, null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); } diff --git a/PHP/snowdrift.c b/PHP/snowdrift.c index 94749bc..8cd13e7 100644 --- a/PHP/snowdrift.c +++ b/PHP/snowdrift.c @@ -66,9 +66,8 @@ static int snowdrift_init() shmctx.size = wid_num * sizeof(snowflake); if (shm_alloc(&shmctx) == -1) { - return FAILURE; + return FAILURE; } - bzero(shmctx.addr, wid_num * sizeof(snowflake)); sf = (snowflake *)shmctx.addr; int i; for (i = 0; i < wid_num; i++) @@ -92,7 +91,6 @@ static int snowdrift_init() { return FAILURE; } - bzero(shmctx.addr, sizeof(snowflake)); sf = (snowflake *)shmctx.addr; sf->Method = SD_G(Method); sf->BaseTime = SD_G(BaseTime); @@ -138,7 +136,7 @@ PHP_METHOD(snowdrift, NextNumId) { zend_long num = 1; zend_long wid = SD_G(WorkerId); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &num, &wid) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &num, &wid) == FAILURE) { RETURN_FALSE; } diff --git a/PHP/src/snowflake/shm.c b/PHP/src/snowflake/shm.c index 942e5bb..cf3496a 100644 --- a/PHP/src/snowflake/shm.c +++ b/PHP/src/snowflake/shm.c @@ -1,65 +1,105 @@ #include #include #include +#ifdef WIN32 +#include "windows.h" +#else #include +#endif #include "shm.h" -#ifdef MAP_ANON +#ifdef WIN32 +#define NAME "SnowDrift" +static HANDLE hMapFile; -int shm_alloc(struct shm *shm) -{ - shm->addr = (void *)mmap(NULL, shm->size, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_SHARED, -1, 0); +int shm_alloc(struct shm* shm) { + hMapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + shm->size, + NAME + ); + + if (hMapFile == NULL) + { + return 0; + } + + LPVOID pBuffer = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, shm->size); + + if (pBuffer == NULL) + { + CloseHandle(hMapFile); + return 0; + } + memset((char*)pBuffer, 0, shm->size); + shm->addr = (void*)pBuffer; + return 1; +} + +void shm_free(struct shm* shm) { + UnmapViewOfFile(shm->addr); + CloseHandle(hMapFile); +} - if (shm->addr == NULL) - { - return -1; - } +#elif defined(MAP_ANON) - return 0; +int shm_alloc(struct shm* shm) +{ + shm->addr = (void*)mmap(NULL, shm->size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + + if (shm->addr == NULL) + { + return -1; + } + bzero(shm->addr, shm->size); + return 0; } -void shm_free(struct shm *shm) +void shm_free(struct shm* shm) { - if (shm->addr) - { - munmap((void *)shm->addr, shm->size); - } + if (shm->addr) + { + munmap((void*)shm->addr, shm->size); + } } #else -int shm_alloc(struct shm *shm) +int shm_alloc(struct shm* shm) { - int fd; - - fd = open("/dev/zero", O_RDWR); - if (fd == -1) - { - return -1; - } + int fd; - shm->addr = (void *)mmap(NULL, shm->size, - PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); + fd = open("/dev/zero", O_RDWR); + if (fd == -1) + { + return -1; + } - close(fd); + shm->addr = (void*)mmap(NULL, shm->size, + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); - if (shm->addr == NULL) - { - return -1; - } + close(fd); - return 0; + if (shm->addr == NULL) + { + return -1; + } + bzero(shm->addr, shm->size); + return 0; } -void shm_free(struct shm *shm) +void shm_free(struct shm* shm) { - if (shm->addr) - { - munmap((void *)shm->addr, shm->size); - } + if (shm->addr) + { + munmap((void*)shm->addr, shm->size); + } } #endif diff --git a/PHP/src/snowflake/snowflake.c b/PHP/src/snowflake/snowflake.c index ff875ea..d4325cc 100644 --- a/PHP/src/snowflake/snowflake.c +++ b/PHP/src/snowflake/snowflake.c @@ -1,125 +1,127 @@ +#ifdef WIN32 +#include "windows.h" +#include +#else #include #include +#endif #include #include #include "snowflake.h" #include "spinlock.h" -#if defined(WIN32) -#include "windows.h" -#endif - // static void EndOverCostAction(uint64_t useTimeTick, snowflake *flake); -static inline uint64_t NextOverCostId(snowflake *flake); -static inline uint64_t NextNormalId(snowflake *flake); -static inline uint64_t GetCurrentTimeTick(snowflake *flake); -static inline uint64_t GetNextTimeTick(snowflake *flake); -static inline uint64_t CalcId(snowflake *flake); -static inline uint64_t CalcTurnBackId(snowflake *flake); -static inline uint64_t GetCurrentTime(); +static inline uint64_t NextOverCostId(snowflake* flake); +static inline uint64_t NextNormalId(snowflake* flake); +static inline uint64_t GetCurrentTimeTick(snowflake* flake); +static inline uint64_t GetNextTimeTick(snowflake* flake); +static inline uint64_t CalcId(snowflake* flake); +static inline uint64_t CalcTurnBackId(snowflake* flake); +static inline uint64_t GetSysCurrentTime(); int ncpu; uint16_t spin = 2048; uint32_t pid = 0; -void Config(snowflake *flake) +void Config(snowflake* flake) { - if (pid == 0) - { - pid = (uint32_t)getpid(); -#if defined(WIN32) - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - ncpu = sysInfo.dwNumberOfProcessors; + if (pid == 0) + { +#ifdef WIN32 + pid = (uint32_t)GetCurrentProcessId(); + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + ncpu = sysInfo.dwNumberOfProcessors; #else - ncpu = sysconf(_SC_NPROCESSORS_ONLN); + pid = (uint32_t)getpid(); + ncpu = sysconf(_SC_NPROCESSORS_ONLN); #endif - if (ncpu <= 0) - { - ncpu = 1; - } - } - if (flake->BaseTime == 0) - { - flake->BaseTime = 1582136402000; - } - else if (flake->BaseTime < 631123200000 || flake->BaseTime > GetCurrentTime()) - { - perror("BaseTime error."); - exit(1); - } + if (ncpu <= 0) + { + ncpu = 1; + } + } + if (flake->BaseTime == 0) + { + flake->BaseTime = 1582136402000; + } + else if (flake->BaseTime < 631123200000 || flake->BaseTime > GetSysCurrentTime()) + { + perror("BaseTime error."); + exit(1); + } - // 2.WorkerIdBitLength - if (flake->WorkerIdBitLength <= 0) - { - perror("WorkerIdBitLength error.(range:[1, 21])"); - exit(1); - } - if (flake->SeqBitLength + flake->WorkerIdBitLength > 22) - { - perror("error:WorkerIdBitLength + SeqBitLength <= 22"); - exit(1); - } - else - { - flake->WorkerIdBitLength = flake->WorkerIdBitLength <= 0 ? 6 : flake->WorkerIdBitLength; - } + // 2.WorkerIdBitLength + if (flake->WorkerIdBitLength <= 0) + { + perror("WorkerIdBitLength error.(range:[1, 21])"); + exit(1); + } + if (flake->SeqBitLength + flake->WorkerIdBitLength > 22) + { + perror("error:WorkerIdBitLength + SeqBitLength <= 22"); + exit(1); + } + else + { + flake->WorkerIdBitLength = flake->WorkerIdBitLength <= 0 ? 6 : flake->WorkerIdBitLength; + } - // 3.WorkerId - uint32_t maxWorkerIdNumber = (1 << flake->WorkerIdBitLength) - 1; - if (maxWorkerIdNumber == 0) - { - maxWorkerIdNumber = 63; - } - if (flake->WorkerId < 0 || flake->WorkerId > maxWorkerIdNumber) - { - perror("WorkerId error. (range:[0, {2^WorkerIdBitLength-1]}"); - exit(1); - } + // 3.WorkerId + uint32_t maxWorkerIdNumber = (1 << flake->WorkerIdBitLength) - 1; + if (maxWorkerIdNumber == 0) + { + maxWorkerIdNumber = 63; + } + if (flake->WorkerId < 0 || flake->WorkerId > maxWorkerIdNumber) + { + perror("WorkerId error. (range:[0, {2^WorkerIdBitLength-1]}"); + exit(1); + } - // 4.SeqBitLength - if (flake->SeqBitLength < 2 || flake->SeqBitLength > 21) - { - perror("SeqBitLength error. (range:[2, 21])"); - exit(1); - } - else - { - flake->SeqBitLength = flake->SeqBitLength <= 0 ? 6 : flake->SeqBitLength; - } + // 4.SeqBitLength + if (flake->SeqBitLength < 2 || flake->SeqBitLength > 21) + { + perror("SeqBitLength error. (range:[2, 21])"); + exit(1); + } + else + { + flake->SeqBitLength = flake->SeqBitLength <= 0 ? 6 : flake->SeqBitLength; + } - // 5.MaxSeqNumber - uint32_t maxSeqNumber = (1 << flake->SeqBitLength) - 1; - if (maxSeqNumber == 0) - { - maxSeqNumber = 63; - } - if (flake->MaxSeqNumber > maxSeqNumber) - { - perror("MaxSeqNumber error. (range:[1, {2^SeqBitLength-1}]"); - exit(1); - } - else - { - flake->MaxSeqNumber = flake->MaxSeqNumber <= 0 ? maxSeqNumber : flake->MaxSeqNumber; - } + // 5.MaxSeqNumber + uint32_t maxSeqNumber = (1 << flake->SeqBitLength) - 1; + if (maxSeqNumber == 0) + { + maxSeqNumber = 63; + } + if (flake->MaxSeqNumber > maxSeqNumber) + { + perror("MaxSeqNumber error. (range:[1, {2^SeqBitLength-1}]"); + exit(1); + } + else + { + flake->MaxSeqNumber = flake->MaxSeqNumber <= 0 ? maxSeqNumber : flake->MaxSeqNumber; + } - // 6.MinSeqNumber - if (flake->MinSeqNumber < 5 || flake->MinSeqNumber > maxSeqNumber) - { - perror("MinSeqNumber error. (range:[5, {MinSeqNumber}]"); - exit(1); - } - else - { - flake->MinSeqNumber = flake->MinSeqNumber <= 0 ? 5 : flake->MinSeqNumber; - } + // 6.MinSeqNumber + if (flake->MinSeqNumber < 5 || flake->MinSeqNumber > maxSeqNumber) + { + perror("MinSeqNumber error. (range:[5, {MinSeqNumber}]"); + exit(1); + } + else + { + flake->MinSeqNumber = flake->MinSeqNumber <= 0 ? 5 : flake->MinSeqNumber; + } - // 7.Others - flake->TopOverCostCount = flake->TopOverCostCount <= 0 ? 2000 : flake->TopOverCostCount; - flake->_TimestampShift = flake->WorkerIdBitLength + flake->SeqBitLength; - flake->_CurrentSeqNumber = flake->MinSeqNumber; - flake->Method = flake->Method; + // 7.Others + flake->TopOverCostCount = flake->TopOverCostCount <= 0 ? 2000 : flake->TopOverCostCount; + flake->_TimestampShift = flake->WorkerIdBitLength + flake->SeqBitLength; + flake->_CurrentSeqNumber = flake->MinSeqNumber; + flake->Method = flake->Method; } // static inline void EndOverCostAction(uint64_t useTimeTick, snowflake *flake) @@ -130,160 +132,169 @@ void Config(snowflake *flake) // } // } -static inline uint64_t NextOverCostId(snowflake *flake) +static inline uint64_t NextOverCostId(snowflake* flake) { - uint64_t currentTimeTick = GetCurrentTimeTick(flake); - if (currentTimeTick > flake->_LastTimeTick) - { - // EndOverCostAction(currentTimeTick, flake); - flake->_LastTimeTick = currentTimeTick; - flake->_CurrentSeqNumber = flake->MinSeqNumber; - flake->_IsOverCost = 0; - flake->_OverCostCountInOneTerm = 0; - // flake->_GenCountInOneTerm = 0; - return CalcId(flake); - } - if (flake->_OverCostCountInOneTerm > flake->TopOverCostCount) - { - // EndOverCostAction(currentTimeTick, flake); - flake->_LastTimeTick = GetNextTimeTick(flake); - flake->_CurrentSeqNumber = flake->MinSeqNumber; - flake->_IsOverCost = 0; - flake->_OverCostCountInOneTerm = 0; - // flake->_GenCountInOneTerm = 0; - return CalcId(flake); - } - if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) - { - flake->_LastTimeTick++; - flake->_CurrentSeqNumber = flake->MinSeqNumber; - flake->_IsOverCost = 1; - flake->_OverCostCountInOneTerm++; - // flake->_GenCountInOneTerm++; - return CalcId(flake); - } + uint64_t currentTimeTick = GetCurrentTimeTick(flake); + if (currentTimeTick > flake->_LastTimeTick) + { + // EndOverCostAction(currentTimeTick, flake); + flake->_LastTimeTick = currentTimeTick; + flake->_CurrentSeqNumber = flake->MinSeqNumber; + flake->_IsOverCost = 0; + flake->_OverCostCountInOneTerm = 0; + // flake->_GenCountInOneTerm = 0; + return CalcId(flake); + } + if (flake->_OverCostCountInOneTerm > flake->TopOverCostCount) + { + // EndOverCostAction(currentTimeTick, flake); + flake->_LastTimeTick = GetNextTimeTick(flake); + flake->_CurrentSeqNumber = flake->MinSeqNumber; + flake->_IsOverCost = 0; + flake->_OverCostCountInOneTerm = 0; + // flake->_GenCountInOneTerm = 0; + return CalcId(flake); + } + if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) + { + flake->_LastTimeTick++; + flake->_CurrentSeqNumber = flake->MinSeqNumber; + flake->_IsOverCost = 1; + flake->_OverCostCountInOneTerm++; + // flake->_GenCountInOneTerm++; + return CalcId(flake); + } - // flake->_GenCountInOneTerm++; - return CalcId(flake); + // flake->_GenCountInOneTerm++; + return CalcId(flake); } -static inline uint64_t NextNormalId(snowflake *flake) +static inline uint64_t NextNormalId(snowflake* flake) { - uint64_t currentTimeTick = GetCurrentTimeTick(flake); - if (currentTimeTick < flake->_LastTimeTick) - { - if (flake->_TurnBackTimeTick < 1) - { - flake->_TurnBackTimeTick = flake->_LastTimeTick - 1; - flake->_TurnBackIndex++; - if (flake->_TurnBackIndex > 4) - { - flake->_TurnBackIndex = 1; - } - } - return CalcTurnBackId(flake); - } - if (flake->_TurnBackTimeTick > 0) - { - flake->_TurnBackTimeTick = 0; - } - if (currentTimeTick > flake->_LastTimeTick) - { - flake->_LastTimeTick = currentTimeTick; - flake->_CurrentSeqNumber = flake->MinSeqNumber; - return CalcId(flake); - } - if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) - { - // flake->_TermIndex++; - flake->_LastTimeTick++; - flake->_CurrentSeqNumber = flake->MinSeqNumber; - flake->_IsOverCost = 1; - flake->_OverCostCountInOneTerm = 1; - // flake->_GenCountInOneTerm = 1; - return CalcId(flake); - } - return CalcId(flake); + uint64_t currentTimeTick = GetCurrentTimeTick(flake); + if (currentTimeTick < flake->_LastTimeTick) + { + if (flake->_TurnBackTimeTick < 1) + { + flake->_TurnBackTimeTick = flake->_LastTimeTick - 1; + flake->_TurnBackIndex++; + if (flake->_TurnBackIndex > 4) + { + flake->_TurnBackIndex = 1; + } + } + return CalcTurnBackId(flake); + } + if (flake->_TurnBackTimeTick > 0) + { + flake->_TurnBackTimeTick = 0; + } + if (currentTimeTick > flake->_LastTimeTick) + { + flake->_LastTimeTick = currentTimeTick; + flake->_CurrentSeqNumber = flake->MinSeqNumber; + return CalcId(flake); + } + if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) + { + // flake->_TermIndex++; + flake->_LastTimeTick++; + flake->_CurrentSeqNumber = flake->MinSeqNumber; + flake->_IsOverCost = 1; + flake->_OverCostCountInOneTerm = 1; + // flake->_GenCountInOneTerm = 1; + return CalcId(flake); + } + return CalcId(flake); } -static inline uint64_t GetCurrentTime() +static inline uint64_t GetSysCurrentTime() { - struct timeval t; - gettimeofday(&t, NULL); - return (uint64_t)(t.tv_sec * 1000 + t.tv_usec / 1000); +#ifdef WIN32 + FILETIME file_time; + GetSystemTimeAsFileTime(&file_time); + uint64_t time = ((uint64_t)file_time.dwLowDateTime) + ((uint64_t)file_time.dwHighDateTime << 32); + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + return (uint64_t)((time - EPOCH) / 10000LL); +#else + struct timeval t; + gettimeofday(&t, NULL); + return (uint64_t)(t.tv_sec * 1000 + t.tv_usec / 1000); +#endif + } -static inline uint64_t GetCurrentTimeTick(snowflake *flake) +static inline uint64_t GetCurrentTimeTick(snowflake* flake) { - return GetCurrentTime() - flake->BaseTime; + return GetSysCurrentTime() - flake->BaseTime; } -static inline uint64_t GetNextTimeTick(snowflake *flake) +static inline uint64_t GetNextTimeTick(snowflake* flake) { - uint64_t tempTimeTicker = GetCurrentTimeTick(flake); - while (tempTimeTicker <= flake->_LastTimeTick) - { - tempTimeTicker = GetCurrentTimeTick(flake); - } - return tempTimeTicker; + uint64_t tempTimeTicker = GetCurrentTimeTick(flake); + while (tempTimeTicker <= flake->_LastTimeTick) + { + tempTimeTicker = GetCurrentTimeTick(flake); + } + return tempTimeTicker; } -static inline uint64_t CalcId(snowflake *flake) +static inline uint64_t CalcId(snowflake* flake) { - uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_CurrentSeqNumber); - flake->_CurrentSeqNumber++; - return result; + uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_CurrentSeqNumber); + flake->_CurrentSeqNumber++; + return result; } -static inline uint64_t CalcTurnBackId(snowflake *flake) +static inline uint64_t CalcTurnBackId(snowflake* flake) { - uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_TurnBackTimeTick); - flake->_TurnBackTimeTick--; - return result; + uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_TurnBackTimeTick); + flake->_TurnBackTimeTick--; + return result; } -static inline uint64_t NextSonwId(snowflake *flake) +static inline uint64_t NextSonwId(snowflake* flake) { - uint64_t currentTimeTick = GetCurrentTimeTick(flake); - if (flake->_LastTimeTick == currentTimeTick) - { - flake->_CurrentSeqNumber++; - if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) - { - flake->_CurrentSeqNumber = flake->MinSeqNumber; - currentTimeTick = GetNextTimeTick(flake); - } - } - else - { - flake->_CurrentSeqNumber = flake->MinSeqNumber; - } - flake->_LastTimeTick = currentTimeTick; - return (uint64_t)((currentTimeTick << flake->_TimestampShift) | (flake->WorkerId << flake->SeqBitLength) | flake->_CurrentSeqNumber); + uint64_t currentTimeTick = GetCurrentTimeTick(flake); + if (flake->_LastTimeTick == currentTimeTick) + { + flake->_CurrentSeqNumber++; + if (flake->_CurrentSeqNumber > flake->MaxSeqNumber) + { + flake->_CurrentSeqNumber = flake->MinSeqNumber; + currentTimeTick = GetNextTimeTick(flake); + } + } + else + { + flake->_CurrentSeqNumber = flake->MinSeqNumber; + } + flake->_LastTimeTick = currentTimeTick; + return (uint64_t)((currentTimeTick << flake->_TimestampShift) | (flake->WorkerId << flake->SeqBitLength) | flake->_CurrentSeqNumber); } -static inline uint64_t GetId(snowflake *flake) +static inline uint64_t GetId(snowflake* flake) { - return flake->Method == 1 ? (flake->_IsOverCost != 0 ? NextOverCostId(flake) : NextNormalId(flake)) : NextSonwId(flake); + return flake->Method == 1 ? (flake->_IsOverCost != 0 ? NextOverCostId(flake) : NextNormalId(flake)) : NextSonwId(flake); } -uint64_t NextId(snowflake *flake) +uint64_t NextId(snowflake* flake) { - spin_lock(&flake->_Lock, pid); - uint64_t id = GetId(flake); - spin_unlock(&flake->_Lock, pid); - return id; + spin_lock(&flake->_Lock, pid); + uint64_t id = GetId(flake); + spin_unlock(&flake->_Lock, pid); + return id; } -uint64_t *NextNumId(snowflake *flake, uint32_t num) +uint64_t* NextNumId(snowflake* flake, uint32_t num) { - uint64_t *arr = (uint64_t *)malloc(sizeof(uint64_t) * num); - spin_lock(&flake->_Lock, pid); - uint32_t i; - for (i = 0; i < num; i++) - { - arr[i] = GetId(flake); - } - spin_unlock(&flake->_Lock, pid); - return arr; + uint64_t* arr = (uint64_t*)malloc(sizeof(uint64_t) * num); + spin_lock(&flake->_Lock, pid); + uint32_t i; + for (i = 0; i < num; i++) + { + arr[i] = GetId(flake); + } + spin_unlock(&flake->_Lock, pid); + return arr; } diff --git a/PHP/src/snowflake/spinlock.c b/PHP/src/snowflake/spinlock.c index 7a2de49..977a409 100644 --- a/PHP/src/snowflake/spinlock.c +++ b/PHP/src/snowflake/spinlock.c @@ -1,47 +1,73 @@ #include +#ifdef WIN32 +#include "windows.h" +#else #include +#endif + #include "spinlock.h" extern int ncpu; extern int spin; -void spin_lock(atomic_t *lock, uint32_t pid) +void spin_lock(atomic_t* lock, uint32_t pid) { - int i, n; - - for (;;) - { - - if (*lock == 0 && - __sync_bool_compare_and_swap(lock, 0, pid)) - { - return; - } - - if (ncpu > 1) - { - - for (n = 1; n < spin; n <<= 1) - { - - for (i = 0; i < n; i++) - { - __asm("pause"); - } - - if (*lock == 0 && - __sync_bool_compare_and_swap(lock, 0, pid)) - { - return; - } - } - } - - sched_yield(); - } + int i, n; + + for (;;) + { + + if (*lock == 0 && +#ifdef WIN32 + InterlockedCompareExchange(lock, pid, 0) == 0 +#else + __sync_bool_compare_and_swap(lock, 0, pid) +#endif + ) + { + return; + } + + if (ncpu > 1) + { + + for (n = 1; n < spin; n <<= 1) + { + + for (i = 0; i < n; i++) + { +#ifdef WIN32 + MemoryBarrier(); +#else + __asm("pause"); +#endif + } + + if (*lock == 0 && +#ifdef WIN32 + InterlockedCompareExchange(lock, pid, 0) == 0 +#else + __sync_bool_compare_and_swap(lock, 0, pid) +#endif + ) + { + return; + } + } + } +#ifdef WIN32 + SwitchToThread(); +#else + sched_yield(); +#endif + } } -void spin_unlock(atomic_t *lock, uint32_t pid) +void spin_unlock(atomic_t* lock, uint32_t pid) { - __sync_bool_compare_and_swap(lock, pid, 0); +#ifdef WIN32 + InterlockedCompareExchange(lock, 0, pid); +#else + __sync_bool_compare_and_swap(lock, pid, 0); +#endif }