Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yitter
雪花ID全家桶(SnowFlake IdGenerator)
提交
1b2b28c0
雪
雪花ID全家桶(SnowFlake IdGenerator)
项目概览
yitter
/
雪花ID全家桶(SnowFlake IdGenerator)
11 个月 前同步成功
通知
201
Star
3
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
雪
雪花ID全家桶(SnowFlake IdGenerator)
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1b2b28c0
编写于
12月 09, 2021
作者:
微
微希夷
提交者:
yitter
12月 09, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
!16 兼容Windows平台
* add PHP extension Win DLL * 兼容Windows平台
上级
ef94d955
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
380 addition
and
310 deletion
+380
-310
PHP/Release/php7.3nts-vc15-php_snowdrift.zip
PHP/Release/php7.3nts-vc15-php_snowdrift.zip
+0
-0
PHP/Release/php7.4nts-vc15-php_snowdrift.zip
PHP/Release/php7.4nts-vc15-php_snowdrift.zip
+0
-0
PHP/Release/php8.0nts-vs16-php_snowdrift.zip
PHP/Release/php8.0nts-vs16-php_snowdrift.zip
+0
-0
PHP/config.w32
PHP/config.w32
+4
-9
PHP/snowdrift.c
PHP/snowdrift.c
+2
-4
PHP/src/snowflake/shm.c
PHP/src/snowflake/shm.c
+78
-38
PHP/src/snowflake/snowflake.c
PHP/src/snowflake/snowflake.c
+235
-224
PHP/src/snowflake/spinlock.c
PHP/src/snowflake/spinlock.c
+61
-35
未找到文件。
PHP/Release/php7.3nts-vc15-php_snowdrift.zip
0 → 100644
浏览文件 @
1b2b28c0
文件已添加
PHP/Release/php7.4nts-vc15-php_snowdrift.zip
0 → 100644
浏览文件 @
1b2b28c0
文件已添加
PHP/Release/php8.0nts-vs16-php_snowdrift.zip
0 → 100644
浏览文件 @
1b2b28c0
文件已添加
PHP/config.w32
浏览文件 @
1b2b28c0
// $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
'
);
}
PHP/snowdrift.c
浏览文件 @
1b2b28c0
...
...
@@ -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
(),
"
|l
l"
,
&
num
,
&
wid
)
==
FAILURE
)
{
RETURN_FALSE
;
}
...
...
PHP/src/snowflake/shm.c
浏览文件 @
1b2b28c0
#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
PHP/src/snowflake/snowflake.c
浏览文件 @
1b2b28c0
#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
Get
Sys
CurrentTime
();
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
>
Get
CurrentTime
())
{
perror
(
"BaseTime error."
);
exit
(
1
);
}
if
(
ncpu
<=
0
)
{
ncpu
=
1
;
}
}
if
(
flake
->
BaseTime
==
0
)
{
flake
->
BaseTime
=
1582136402000
;
}
else
if
(
flake
->
BaseTime
<
631123200000
||
flake
->
BaseTime
>
GetSys
CurrentTime
())
{
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
Get
Sys
CurrentTime
()
{
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
Get
CurrentTime
()
-
flake
->
BaseTime
;
return
GetSys
CurrentTime
()
-
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
;
}
PHP/src/snowflake/spinlock.c
浏览文件 @
1b2b28c0
#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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录