Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-11-06 14:01:28 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
9d6c22d45e0fbb25d794fbcde5428a17b2172225
9d6c22d4
2 parents
85b987d1
8521762c
Merge branch 'srs.master'
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
291 行增加
和
307 行删除
trunk/research/st/stk.c
trunk/research/st/sync.c
trunk/research/st/stk.c
查看文件 @
9d6c22d
...
...
@@ -46,7 +46,6 @@
#include <sys/mman.h>
#include "common.h"
/* How much space to leave between the stacks, at each end */
#define REDZONE _ST_PAGE_SIZE
...
...
@@ -58,116 +57,118 @@ static char *_st_new_stk_segment(int size);
_st_stack_t
*
_st_stack_new
(
int
stack_size
)
{
_st_clist_t
*
qp
;
_st_stack_t
*
ts
;
int
extra
;
for
(
qp
=
_st_free_stacks
.
next
;
qp
!=
&
_st_free_stacks
;
qp
=
qp
->
next
)
{
ts
=
_ST_THREAD_STACK_PTR
(
qp
);
if
(
ts
->
stk_size
>=
stack_size
)
{
/* Found a stack that is big enough */
ST_REMOVE_LINK
(
&
ts
->
links
);
_st_num_free_stacks
--
;
ts
->
links
.
next
=
NULL
;
ts
->
links
.
prev
=
NULL
;
return
ts
;
_st_clist_t
*
qp
;
_st_stack_t
*
ts
;
int
extra
;
for
(
qp
=
_st_free_stacks
.
next
;
qp
!=
&
_st_free_stacks
;
qp
=
qp
->
next
)
{
ts
=
_ST_THREAD_STACK_PTR
(
qp
);
if
(
ts
->
stk_size
>=
stack_size
)
{
/* Found a stack that is big enough */
ST_REMOVE_LINK
(
&
ts
->
links
);
_st_num_free_stacks
--
;
ts
->
links
.
next
=
NULL
;
ts
->
links
.
prev
=
NULL
;
return
ts
;
}
}
}
/* Make a new thread stack object. */
if
((
ts
=
(
_st_stack_t
*
)
calloc
(
1
,
sizeof
(
_st_stack_t
)))
==
NULL
)
return
NULL
;
extra
=
_st_randomize_stacks
?
_ST_PAGE_SIZE
:
0
;
ts
->
vaddr_size
=
stack_size
+
2
*
REDZONE
+
extra
;
ts
->
vaddr
=
_st_new_stk_segment
(
ts
->
vaddr_size
);
if
(
!
ts
->
vaddr
)
{
free
(
ts
);
return
NULL
;
}
ts
->
stk_size
=
stack_size
;
ts
->
stk_bottom
=
ts
->
vaddr
+
REDZONE
;
ts
->
stk_top
=
ts
->
stk_bottom
+
stack_size
;
/* Make a new thread stack object. */
if
((
ts
=
(
_st_stack_t
*
)
calloc
(
1
,
sizeof
(
_st_stack_t
)))
==
NULL
)
{
return
NULL
;
}
extra
=
_st_randomize_stacks
?
_ST_PAGE_SIZE
:
0
;
ts
->
vaddr_size
=
stack_size
+
2
*
REDZONE
+
extra
;
ts
->
vaddr
=
_st_new_stk_segment
(
ts
->
vaddr_size
);
if
(
!
ts
->
vaddr
)
{
free
(
ts
);
return
NULL
;
}
ts
->
stk_size
=
stack_size
;
ts
->
stk_bottom
=
ts
->
vaddr
+
REDZONE
;
ts
->
stk_top
=
ts
->
stk_bottom
+
stack_size
;
#ifdef DEBUG
mprotect
(
ts
->
vaddr
,
REDZONE
,
PROT_NONE
);
mprotect
(
ts
->
stk_top
+
extra
,
REDZONE
,
PROT_NONE
);
mprotect
(
ts
->
vaddr
,
REDZONE
,
PROT_NONE
);
mprotect
(
ts
->
stk_top
+
extra
,
REDZONE
,
PROT_NONE
);
#endif
if
(
extra
)
{
long
offset
=
(
random
()
%
extra
)
&
~
0xf
;
ts
->
stk_bottom
+=
offset
;
ts
->
stk_top
+=
offset
;
}
return
ts
;
if
(
extra
)
{
long
offset
=
(
random
()
%
extra
)
&
~
0xf
;
ts
->
stk_bottom
+=
offset
;
ts
->
stk_top
+=
offset
;
}
return
ts
;
}
/*
* Free the stack for the current thread
*/
void
_st_stack_free
(
_st_stack_t
*
ts
)
{
if
(
!
ts
)
return
;
/* Put the stack on the free list */
ST_APPEND_LINK
(
&
ts
->
links
,
_st_free_stacks
.
prev
);
_st_num_free_stacks
++
;
if
(
!
ts
)
{
return
;
}
/* Put the stack on the free list */
ST_APPEND_LINK
(
&
ts
->
links
,
_st_free_stacks
.
prev
);
_st_num_free_stacks
++
;
}
static
char
*
_st_new_stk_segment
(
int
size
)
{
#ifdef MALLOC_STACK
void
*
vaddr
=
malloc
(
size
);
#else
static
int
zero_fd
=
-
1
;
int
mmap_flags
=
MAP_PRIVATE
;
void
*
vaddr
;
#if defined (MD_USE_SYSV_ANON_MMAP)
if
(
zero_fd
<
0
)
{
if
((
zero_fd
=
open
(
"/dev/zero"
,
O_RDWR
,
0
))
<
0
)
return
NULL
;
fcntl
(
zero_fd
,
F_SETFD
,
FD_CLOEXEC
);
}
#elif defined (MD_USE_BSD_ANON_MMAP)
mmap_flags
|=
MAP_ANON
;
void
*
vaddr
=
malloc
(
size
);
#else
#error Unknown OS
static
int
zero_fd
=
-
1
;
int
mmap_flags
=
MAP_PRIVATE
;
void
*
vaddr
;
#if defined (MD_USE_SYSV_ANON_MMAP)
if
(
zero_fd
<
0
)
{
if
((
zero_fd
=
open
(
"/dev/zero"
,
O_RDWR
,
0
))
<
0
)
{
return
NULL
;
}
fcntl
(
zero_fd
,
F_SETFD
,
FD_CLOEXEC
);
}
#elif defined (MD_USE_BSD_ANON_MMAP)
mmap_flags
|=
MAP_ANON
;
#else
#error Unknown OS
#endif
vaddr
=
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
mmap_flags
,
zero_fd
,
0
);
if
(
vaddr
==
(
void
*
)
MAP_FAILED
)
{
return
NULL
;
}
#endif
vaddr
=
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
mmap_flags
,
zero_fd
,
0
);
if
(
vaddr
==
(
void
*
)
MAP_FAILED
)
return
NULL
;
#endif
/* MALLOC_STACK */
return
(
char
*
)
vaddr
;
return
(
char
*
)
vaddr
;
}
/* Not used */
#if 0
void _st_delete_stk_segment(char *vaddr, int size)
{
#ifdef MALLOC_STACK
free(vaddr);
free(vaddr);
#else
(void) munmap(vaddr, size);
(void) munmap(vaddr, size);
#endif
}
#endif
int
st_randomize_stacks
(
int
on
)
{
int
wason
=
_st_randomize_stacks
;
_st_randomize_stacks
=
on
;
if
(
on
)
srandom
((
unsigned
int
)
st_utime
());
return
wason
;
int
wason
=
_st_randomize_stacks
;
_st_randomize_stacks
=
on
;
if
(
on
)
{
srandom
((
unsigned
int
)
st_utime
());
}
return
wason
;
}
...
...
trunk/research/st/sync.c
查看文件 @
9d6c22d
...
...
@@ -44,326 +44,309 @@
#include <errno.h>
#include "common.h"
extern
time_t
_st_curr_time
;
extern
st_utime_t
_st_last_tset
;
extern
int
_st_active_count
;
static
st_utime_t
(
*
_st_utime
)(
void
)
=
NULL
;
/*****************************************
* Time functions
*/
st_utime_t
st_utime
(
void
)
{
if
(
_st_utime
==
NULL
)
{
if
(
_st_utime
==
NULL
)
{
#ifdef MD_GET_UTIME
MD_GET_UTIME
();
MD_GET_UTIME
();
#else
#error Unknown OS
#error Unknown OS
#endif
}
return
(
*
_st_utime
)();
}
return
(
*
_st_utime
)();
}
int
st_set_utime_function
(
st_utime_t
(
*
func
)(
void
))
{
if
(
_st_active_count
)
{
errno
=
EINVAL
;
return
-
1
;
}
_st_utime
=
func
;
return
0
;
if
(
_st_active_count
)
{
errno
=
EINVAL
;
return
-
1
;
}
_st_utime
=
func
;
return
0
;
}
st_utime_t
st_utime_last_clock
(
void
)
{
return
_ST_LAST_CLOCK
;
return
_ST_LAST_CLOCK
;
}
int
st_timecache_set
(
int
on
)
{
int
wason
=
(
_st_curr_time
)
?
1
:
0
;
if
(
on
)
{
_st_curr_time
=
time
(
NULL
);
_st_last_tset
=
st_utime
();
}
else
_st_curr_time
=
0
;
return
wason
;
int
wason
=
(
_st_curr_time
)
?
1
:
0
;
if
(
on
)
{
_st_curr_time
=
time
(
NULL
);
_st_last_tset
=
st_utime
();
}
else
{
_st_curr_time
=
0
;
}
return
wason
;
}
time_t
st_time
(
void
)
{
if
(
_st_curr_time
)
return
_st_curr_time
;
return
time
(
NULL
);
if
(
_st_curr_time
)
{
return
_st_curr_time
;
}
return
time
(
NULL
);
}
int
st_usleep
(
st_utime_t
usecs
)
{
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
if
(
usecs
!=
ST_UTIME_NO_TIMEOUT
)
{
me
->
state
=
_ST_ST_SLEEPING
;
_ST_ADD_SLEEPQ
(
me
,
usecs
);
}
else
me
->
state
=
_ST_ST_SUSPENDED
;
_ST_SWITCH_CONTEXT
(
me
);
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
return
0
;
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
if
(
usecs
!=
ST_UTIME_NO_TIMEOUT
)
{
me
->
state
=
_ST_ST_SLEEPING
;
_ST_ADD_SLEEPQ
(
me
,
usecs
);
}
else
{
me
->
state
=
_ST_ST_SUSPENDED
;
}
_ST_SWITCH_CONTEXT
(
me
);
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
return
0
;
}
int
st_sleep
(
int
secs
)
{
return
st_usleep
((
secs
>=
0
)
?
secs
*
(
st_utime_t
)
1000000LL
:
ST_UTIME_NO_TIMEOUT
);
return
st_usleep
((
secs
>=
0
)
?
secs
*
(
st_utime_t
)
1000000LL
:
ST_UTIME_NO_TIMEOUT
);
}
/*****************************************
* Condition variable functions
*/
_st_cond_t
*
st_cond_new
(
void
)
{
_st_cond_t
*
cvar
;
cvar
=
(
_st_cond_t
*
)
calloc
(
1
,
sizeof
(
_st_cond_t
));
if
(
cvar
)
{
ST_INIT_CLIST
(
&
cvar
->
wait_q
);
}
return
cvar
;
_st_cond_t
*
cvar
;
cvar
=
(
_st_cond_t
*
)
calloc
(
1
,
sizeof
(
_st_cond_t
));
if
(
cvar
)
{
ST_INIT_CLIST
(
&
cvar
->
wait_q
);
}
return
cvar
;
}
int
st_cond_destroy
(
_st_cond_t
*
cvar
)
{
if
(
cvar
->
wait_q
.
next
!=
&
cvar
->
wait_q
)
{
errno
=
EBUSY
;
return
-
1
;
}
free
(
cvar
);
return
0
;
if
(
cvar
->
wait_q
.
next
!=
&
cvar
->
wait_q
)
{
errno
=
EBUSY
;
return
-
1
;
}
free
(
cvar
);
return
0
;
}
int
st_cond_timedwait
(
_st_cond_t
*
cvar
,
st_utime_t
timeout
)
{
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
int
rv
;
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
/* Put caller thread on the condition variable's wait queue */
me
->
state
=
_ST_ST_COND_WAIT
;
ST_APPEND_LINK
(
&
me
->
wait_links
,
&
cvar
->
wait_q
);
if
(
timeout
!=
ST_UTIME_NO_TIMEOUT
)
_ST_ADD_SLEEPQ
(
me
,
timeout
);
_ST_SWITCH_CONTEXT
(
me
);
ST_REMOVE_LINK
(
&
me
->
wait_links
);
rv
=
0
;
if
(
me
->
flags
&
_ST_FL_TIMEDOUT
)
{
me
->
flags
&=
~
_ST_FL_TIMEDOUT
;
errno
=
ETIME
;
rv
=
-
1
;
}
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
rv
=
-
1
;
}
return
rv
;
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
int
rv
;
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
/* Put caller thread on the condition variable's wait queue */
me
->
state
=
_ST_ST_COND_WAIT
;
ST_APPEND_LINK
(
&
me
->
wait_links
,
&
cvar
->
wait_q
);
if
(
timeout
!=
ST_UTIME_NO_TIMEOUT
)
{
_ST_ADD_SLEEPQ
(
me
,
timeout
);
}
_ST_SWITCH_CONTEXT
(
me
);
ST_REMOVE_LINK
(
&
me
->
wait_links
);
rv
=
0
;
if
(
me
->
flags
&
_ST_FL_TIMEDOUT
)
{
me
->
flags
&=
~
_ST_FL_TIMEDOUT
;
errno
=
ETIME
;
rv
=
-
1
;
}
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
rv
=
-
1
;
}
return
rv
;
}
int
st_cond_wait
(
_st_cond_t
*
cvar
)
{
return
st_cond_timedwait
(
cvar
,
ST_UTIME_NO_TIMEOUT
);
return
st_cond_timedwait
(
cvar
,
ST_UTIME_NO_TIMEOUT
);
}
static
int
_st_cond_signal
(
_st_cond_t
*
cvar
,
int
broadcast
)
{
_st_thread_t
*
thread
;
_st_clist_t
*
q
;
for
(
q
=
cvar
->
wait_q
.
next
;
q
!=
&
cvar
->
wait_q
;
q
=
q
->
next
)
{
thread
=
_ST_THREAD_WAITQ_PTR
(
q
);
if
(
thread
->
state
==
_ST_ST_COND_WAIT
)
{
if
(
thread
->
flags
&
_ST_FL_ON_SLEEPQ
)
_ST_DEL_SLEEPQ
(
thread
);
/* Make thread runnable */
thread
->
state
=
_ST_ST_RUNNABLE
;
_ST_ADD_RUNQ
(
thread
);
if
(
!
broadcast
)
break
;
_st_thread_t
*
thread
;
_st_clist_t
*
q
;
for
(
q
=
cvar
->
wait_q
.
next
;
q
!=
&
cvar
->
wait_q
;
q
=
q
->
next
)
{
thread
=
_ST_THREAD_WAITQ_PTR
(
q
);
if
(
thread
->
state
==
_ST_ST_COND_WAIT
)
{
if
(
thread
->
flags
&
_ST_FL_ON_SLEEPQ
)
{
_ST_DEL_SLEEPQ
(
thread
);
}
/* Make thread runnable */
thread
->
state
=
_ST_ST_RUNNABLE
;
_ST_ADD_RUNQ
(
thread
);
if
(
!
broadcast
)
{
break
;
}
}
}
}
return
0
;
return
0
;
}
int
st_cond_signal
(
_st_cond_t
*
cvar
)
{
return
_st_cond_signal
(
cvar
,
0
);
return
_st_cond_signal
(
cvar
,
0
);
}
int
st_cond_broadcast
(
_st_cond_t
*
cvar
)
{
return
_st_cond_signal
(
cvar
,
1
);
return
_st_cond_signal
(
cvar
,
1
);
}
/*****************************************
* Mutex functions
*/
_st_mutex_t
*
st_mutex_new
(
void
)
{
_st_mutex_t
*
lock
;
lock
=
(
_st_mutex_t
*
)
calloc
(
1
,
sizeof
(
_st_mutex_t
));
if
(
lock
)
{
ST_INIT_CLIST
(
&
lock
->
wait_q
);
lock
->
owner
=
NULL
;
}
return
lock
;
_st_mutex_t
*
lock
;
lock
=
(
_st_mutex_t
*
)
calloc
(
1
,
sizeof
(
_st_mutex_t
));
if
(
lock
)
{
ST_INIT_CLIST
(
&
lock
->
wait_q
);
lock
->
owner
=
NULL
;
}
return
lock
;
}
int
st_mutex_destroy
(
_st_mutex_t
*
lock
)
{
if
(
lock
->
owner
!=
NULL
||
lock
->
wait_q
.
next
!=
&
lock
->
wait_q
)
{
errno
=
EBUSY
;
return
-
1
;
}
free
(
lock
);
return
0
;
if
(
lock
->
owner
!=
NULL
||
lock
->
wait_q
.
next
!=
&
lock
->
wait_q
)
{
errno
=
EBUSY
;
return
-
1
;
}
free
(
lock
);
return
0
;
}
int
st_mutex_lock
(
_st_mutex_t
*
lock
)
{
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
if
(
lock
->
owner
==
NULL
)
{
/* Got the mutex */
lock
->
owner
=
me
;
_st_thread_t
*
me
=
_ST_CURRENT_THREAD
();
if
(
me
->
flags
&
_ST_FL_INTERRUPT
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
if
(
lock
->
owner
==
NULL
)
{
/* Got the mutex */
lock
->
owner
=
me
;
return
0
;
}
if
(
lock
->
owner
==
me
)
{
errno
=
EDEADLK
;
return
-
1
;
}
/* Put caller thread on the mutex's wait queue */
me
->
state
=
_ST_ST_LOCK_WAIT
;
ST_APPEND_LINK
(
&
me
->
wait_links
,
&
lock
->
wait_q
);
_ST_SWITCH_CONTEXT
(
me
);
ST_REMOVE_LINK
(
&
me
->
wait_links
);
if
((
me
->
flags
&
_ST_FL_INTERRUPT
)
&&
lock
->
owner
!=
me
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
return
0
;
}
if
(
lock
->
owner
==
me
)
{
errno
=
EDEADLK
;
return
-
1
;
}
/* Put caller thread on the mutex's wait queue */
me
->
state
=
_ST_ST_LOCK_WAIT
;
ST_APPEND_LINK
(
&
me
->
wait_links
,
&
lock
->
wait_q
);
_ST_SWITCH_CONTEXT
(
me
);
ST_REMOVE_LINK
(
&
me
->
wait_links
);
if
((
me
->
flags
&
_ST_FL_INTERRUPT
)
&&
lock
->
owner
!=
me
)
{
me
->
flags
&=
~
_ST_FL_INTERRUPT
;
errno
=
EINTR
;
return
-
1
;
}
return
0
;
}
int
st_mutex_unlock
(
_st_mutex_t
*
lock
)
{
_st_thread_t
*
thread
;
_st_clist_t
*
q
;
if
(
lock
->
owner
!=
_ST_CURRENT_THREAD
())
{
errno
=
EPERM
;
return
-
1
;
}
for
(
q
=
lock
->
wait_q
.
next
;
q
!=
&
lock
->
wait_q
;
q
=
q
->
next
)
{
thread
=
_ST_THREAD_WAITQ_PTR
(
q
);
if
(
thread
->
state
==
_ST_ST_LOCK_WAIT
)
{
lock
->
owner
=
thread
;
/* Make thread runnable */
thread
->
state
=
_ST_ST_RUNNABLE
;
_ST_ADD_RUNQ
(
thread
);
return
0
;
_st_thread_t
*
thread
;
_st_clist_t
*
q
;
if
(
lock
->
owner
!=
_ST_CURRENT_THREAD
())
{
errno
=
EPERM
;
return
-
1
;
}
}
/* No threads waiting on this mutex */
lock
->
owner
=
NULL
;
return
0
;
for
(
q
=
lock
->
wait_q
.
next
;
q
!=
&
lock
->
wait_q
;
q
=
q
->
next
)
{
thread
=
_ST_THREAD_WAITQ_PTR
(
q
);
if
(
thread
->
state
==
_ST_ST_LOCK_WAIT
)
{
lock
->
owner
=
thread
;
/* Make thread runnable */
thread
->
state
=
_ST_ST_RUNNABLE
;
_ST_ADD_RUNQ
(
thread
);
return
0
;
}
}
/* No threads waiting on this mutex */
lock
->
owner
=
NULL
;
return
0
;
}
int
st_mutex_trylock
(
_st_mutex_t
*
lock
)
{
if
(
lock
->
owner
!=
NULL
)
{
errno
=
EBUSY
;
return
-
1
;
}
/* Got the mutex */
lock
->
owner
=
_ST_CURRENT_THREAD
();
return
0
;
if
(
lock
->
owner
!=
NULL
)
{
errno
=
EBUSY
;
return
-
1
;
}
/* Got the mutex */
lock
->
owner
=
_ST_CURRENT_THREAD
();
return
0
;
}
...
...
请
注册
或
登录
后发表评论