Browse Source

!16 兼容Windows平台

* add PHP extension Win DLL
* 兼容Windows平台
tags/v1.3.1
微希夷 yitter 2 years ago
parent
commit
1b2b28c095
8 changed files with 380 additions and 310 deletions
  1. BIN
      PHP/Release/php7.3nts-vc15-php_snowdrift.zip
  2. BIN
      PHP/Release/php7.4nts-vc15-php_snowdrift.zip
  3. BIN
      PHP/Release/php8.0nts-vs16-php_snowdrift.zip
  4. +4
    -9
      PHP/config.w32
  5. +2
    -4
      PHP/snowdrift.c
  6. +78
    -38
      PHP/src/snowflake/shm.c
  7. +235
    -224
      PHP/src/snowflake/snowflake.c
  8. +61
    -35
      PHP/src/snowflake/spinlock.c

BIN
PHP/Release/php7.3nts-vc15-php_snowdrift.zip View File


BIN
PHP/Release/php7.4nts-vc15-php_snowdrift.zip View File


BIN
PHP/Release/php8.0nts-vs16-php_snowdrift.zip View File


+ 4
- 9
PHP/config.w32 View File

@@ -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');
}


+ 2
- 4
PHP/snowdrift.c View File

@@ -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;
}


+ 78
- 38
PHP/src/snowflake/shm.c View File

@@ -1,65 +1,105 @@
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#ifdef WIN32
#include "windows.h"
#else
#include <sys/mman.h>
#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

+ 235
- 224
PHP/src/snowflake/snowflake.c View File

@@ -1,125 +1,127 @@
#ifdef WIN32
#include "windows.h"
#include <sys/timeb.h>
#else
#include <unistd.h>
#include <sys/time.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#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;
}

+ 61
- 35
PHP/src/snowflake/spinlock.c View File

@@ -1,47 +1,73 @@
#include <stdlib.h>
#ifdef WIN32
#include "windows.h"
#else
#include <sched.h>
#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
}

Loading…
Cancel
Save