提交 1b2b28c0 编写于 作者: 微希夷 提交者: yitter

!16 兼容Windows平台

* add PHP extension Win DLL
* 兼容Windows平台
上级 ef94d955
// $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');
}
......@@ -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;
}
......
#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
#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;
}
#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
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册