Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
08ee945e
Commit
08ee945e
authored
Nov 29, 2011
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
runtime: If no sem_timedwait, use pthread_cond_timedwait.
From-SVN: r181821
parent
85b8555e
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
114 additions
and
11 deletions
+114
-11
libgo/config.h.in
+3
-0
libgo/configure
+18
-0
libgo/configure.ac
+8
-0
libgo/runtime/lock_sema.c
+8
-1
libgo/runtime/thread-sema.c
+77
-10
No files found.
libgo/config.h.in
View file @
08ee945e
...
...
@@ -36,6 +36,9 @@
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the `sem_timedwait' function. */
#undef HAVE_SEM_TIMEDWAIT
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
...
...
libgo/configure
View file @
08ee945e
...
...
@@ -14559,6 +14559,24 @@ else
fi
CFLAGS_hold
=
"
$CFLAGS
"
CFLAGS
=
"
$CFLAGS
$PTHREAD_CFLAGS
"
LIBS_hold
=
"
$LIBS
"
LIBS
=
"
$LIBS
$PTHREAD_LIBS
"
for
ac_func
in
sem_timedwait
do
:
ac_fn_c_check_func
"
$LINENO
"
"sem_timedwait"
"ac_cv_func_sem_timedwait"
if
test
"x
$ac_cv_func_sem_timedwait
"
=
x
""
yes
;
then
:
cat
>>
confdefs.h
<<
_ACEOF
#define HAVE_SEM_TIMEDWAIT 1
_ACEOF
fi
done
CFLAGS
=
"
$CFLAGS_hold
"
LIBS
=
"
$LIBS_hold
"
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking for __sync_bool_compare_and_swap_4"
>
&5
$as_echo_n
"checking for __sync_bool_compare_and_swap_4... "
>
&6
;
}
if
test
"
${
libgo_cv_func___sync_bool_compare_and_swap_4
+set
}
"
=
set
;
then
:
...
...
libgo/configure.ac
View file @
08ee945e
...
...
@@ -456,6 +456,14 @@ AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore setenv)
AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
CFLAGS_hold="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS_hold="$LIBS"
LIBS="$LIBS $PTHREAD_LIBS"
AC_CHECK_FUNCS(sem_timedwait)
CFLAGS="$CFLAGS_hold"
LIBS="$LIBS_hold"
AC_CACHE_CHECK([for __sync_bool_compare_and_swap_4],
[libgo_cv_func___sync_bool_compare_and_swap_4],
[AC_LINK_IFELSE([
...
...
libgo/runtime/lock_sema.c
View file @
08ee945e
...
...
@@ -32,9 +32,11 @@ enum
void
runtime_lock
(
Lock
*
l
)
{
M
*
m
;
uintptr
v
;
uint32
i
,
spin
;
m
=
runtime_m
();
if
(
m
->
locks
++
<
0
)
runtime_throw
(
"runtime_lock: lock count"
);
...
...
@@ -91,7 +93,7 @@ runtime_unlock(Lock *l)
uintptr
v
;
M
*
mp
;
if
(
--
m
->
locks
<
0
)
if
(
--
runtime_m
()
->
locks
<
0
)
runtime_throw
(
"runtime_unlock: lock count"
);
for
(;;)
{
...
...
@@ -144,6 +146,9 @@ runtime_notewakeup(Note *n)
void
runtime_notesleep
(
Note
*
n
)
{
M
*
m
;
m
=
runtime_m
();
if
(
m
->
waitsema
==
0
)
m
->
waitsema
=
runtime_semacreate
();
if
(
!
runtime_casp
(
&
n
->
waitm
,
nil
,
m
))
{
// must be LOCKED (got wakeup)
...
...
@@ -158,6 +163,7 @@ runtime_notesleep(Note *n)
void
runtime_notetsleep
(
Note
*
n
,
int64
ns
)
{
M
*
m
;
M
*
mp
;
int64
deadline
,
now
;
...
...
@@ -166,6 +172,7 @@ runtime_notetsleep(Note *n, int64 ns)
return
;
}
m
=
runtime_m
();
if
(
m
->
waitsema
==
0
)
m
->
waitsema
=
runtime_semacreate
();
...
...
libgo/runtime/thread-sema.c
View file @
08ee945e
...
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "config.h"
#include "runtime.h"
#include <errno.h>
...
...
@@ -9,19 +10,43 @@
#include <time.h>
#include <semaphore.h>
/* If we don't have sem_timedwait, use pthread_cond_timedwait instead.
We don't always use condition variables because on some systems
pthread_mutex_lock and pthread_mutex_unlock must be called by the
same thread. That is never true of semaphores. */
struct
go_sem
{
sem_t
sem
;
#ifndef HAVE_SEM_TIMEDWAIT
int
timedwait
;
pthread_mutex_t
mutex
;
pthread_cond_t
cond
;
#endif
};
/* Create a semaphore. */
uintptr
runtime_semacreate
(
void
)
{
s
em_t
*
p
;
s
truct
go_sem
*
p
;
/* Call malloc rather than runtime_malloc. This will allocate space
on the C heap. We can't call runtime_malloc here because it
could cause a deadlock. */
p
=
malloc
(
sizeof
(
s
em_t
));
if
(
sem_init
(
p
,
0
,
0
)
!=
0
)
p
=
malloc
(
sizeof
(
s
truct
go_sem
));
if
(
sem_init
(
&
p
->
sem
,
0
,
0
)
!=
0
)
runtime_throw
(
"sem_init"
);
#ifndef HAVE_SEM_TIMEDWAIT
if
(
pthread_mutex_init
(
&
p
->
mutex
,
NULL
)
!=
0
)
runtime_throw
(
"pthread_mutex_init"
);
if
(
pthread_cond_init
(
&
p
->
cond
,
NULL
)
!=
0
)
runtime_throw
(
"pthread_cond_init"
);
#endif
return
(
uintptr
)
p
;
}
...
...
@@ -30,26 +55,56 @@ runtime_semacreate(void)
int32
runtime_semasleep
(
int64
ns
)
{
M
*
m
;
struct
go_sem
*
sem
;
int
r
;
m
=
runtime_m
();
sem
=
(
struct
go_sem
*
)
m
->
waitsema
;
if
(
ns
>=
0
)
{
int64
abs
;
struct
timespec
ts
;
int
err
;
abs
=
ns
+
runtime_nanotime
();
ts
.
tv_sec
=
abs
/
1000000000LL
;
ts
.
tv_nsec
=
abs
%
1000000000LL
;
err
=
0
;
ns
+=
runtime_nanotime
();
ts
.
tv_sec
=
ns
/
1000000000LL
;
ts
.
tv_nsec
=
ns
%
1000000000LL
;
r
=
sem_timedwait
((
sem_t
*
)
m
->
waitsema
,
&
ts
);
#ifdef HAVE_SEM_TIMEDWAIT
r
=
sem_timedwait
(
&
sem
->
sem
,
&
ts
);
if
(
r
!=
0
)
err
=
errno
;
#else
if
(
pthread_mutex_lock
(
&
sem
->
mutex
)
!=
0
)
runtime_throw
(
"pthread_mutex_lock"
);
while
((
r
=
sem_trywait
(
&
sem
->
sem
))
!=
0
)
{
if
(
errno
==
ETIMEDOUT
||
errno
==
EINTR
)
r
=
pthread_cond_timedwait
(
&
sem
->
cond
,
&
sem
->
mutex
,
&
ts
);
if
(
r
!=
0
)
{
err
=
r
;
break
;
}
}
if
(
pthread_mutex_unlock
(
&
sem
->
mutex
)
!=
0
)
runtime_throw
(
"pthread_mutex_unlock"
);
#endif
if
(
err
!=
0
)
{
if
(
err
==
ETIMEDOUT
||
err
==
EAGAIN
||
err
==
EINTR
)
return
-
1
;
runtime_throw
(
"sema_timedwait"
);
}
return
0
;
}
while
(
sem_wait
(
(
sem_t
*
)
m
->
waitsema
)
!=
0
)
while
(
sem_wait
(
&
sem
->
sem
)
!=
0
)
{
if
(
errno
==
EINTR
)
continue
;
...
...
@@ -64,8 +119,20 @@ runtime_semasleep (int64 ns)
void
runtime_semawakeup
(
M
*
mp
)
{
if
(
sem_post
((
sem_t
*
)
mp
->
waitsema
)
!=
0
)
struct
go_sem
*
sem
;
sem
=
(
struct
go_sem
*
)
mp
->
waitsema
;
if
(
sem_post
(
&
sem
->
sem
)
!=
0
)
runtime_throw
(
"sem_post"
);
#ifndef HAVE_SEM_TIMEDWAIT
if
(
pthread_mutex_lock
(
&
sem
->
mutex
)
!=
0
)
runtime_throw
(
"pthread_mutex_lock"
);
if
(
pthread_cond_broadcast
(
&
sem
->
cond
)
!=
0
)
runtime_throw
(
"pthread_cond_broadcast"
);
if
(
pthread_mutex_unlock
(
&
sem
->
mutex
)
!=
0
)
runtime_throw
(
"pthread_mutex_unlock"
);
#endif
}
void
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment