RFR: 8087322: Implement a Semaphore utility class
Kim Barrett
kim.barrett at oracle.com
Wed Jun 24 20:28:39 UTC 2015
On Jun 24, 2015, at 6:59 AM, Stefan Karlsson <stefan.karlsson at oracle.com> wrote:
>
> Hi all,
>
> Updated webrev:
> http://cr.openjdk.java.net/~stefank/8087322/webrev.04
Structurally fine. (Stefan would be rightly annoyed with me if I said
otherwise after all the offline discussions we've had.) There's some
nastiness that results from pre-existing problems in the os_xxx.cpp
files, but cleaning that up is another collection of tasks.
A few easy bugs, some stylistic comments that can be accepted or
declined, but nothing requiring large amounts of rework.
------------------------------------------------------------------------------
src/os/bsd/vm/os_bsd.cpp
1971 OSXSemaphore::OSXSemaphore(uint value) : _semaphore(0) {
I think that initializer for _semaphore isn't right. _semaphore is a
(OSX) semaphore_t. I think that initializer only accidentally
compiles at all.
------------------------------------------------------------------------------
src/os/bsd/vm/semaphore_bsd.hpp
28 #include "memory/allocation.hpp"
29
30 #include <semaphore.h>
31
32 #ifndef __APPLE__
33 # include "semaphore_posix.hpp"
34 #else
35 // OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
36
37 class OSXSemaphore : public CHeapObj<mtInternal>{
This only needs "memory/allocation.hpp" in the Apple case.
This doesn't need <semaphore.h> in the non-Apple case.
In the Apple case, I think the correct include is <mach/semaphore.h>
rather than <semaphore.h>. I'm not sure why <semaphore.h> is working
at all.
------------------------------------------------------------------------------
src/os/posix/vm/os_posix.cpp
1021 #define check_with_errno(check_type, cond, msg) \
1022 do { \
1023 int err = errno; \
1024 check_type(cond, err_msg("%s; error='%s' (errno=%d)", msg, strerror(err), err)); \
1025 } while (false)
1026
1027 #define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg)
1028 #define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
We already have assert_status in debug.hpp. It might be better to add
a corresponding guarantee_status there, and use those here.
Also, these macros are only used inside the #ifndef __APPLE__ block.
And welcome to the dark side. (Higher order macros!)
------------------------------------------------------------------------------
src/os/posix/vm/os_posix.cpp
1053 while ((ret = sem_wait(&_semaphore)) == -1 && errno == EINTR) {
I would probably instead use
(ret = sem_wait(&_semaphore)) != 0
e.g. while !successful.
------------------------------------------------------------------------------
src/os/posix/vm/os_posix.cpp
1059 bool PosixSemaphore::trywait() {
1060 bool succeeded = sem_trywait(&_semaphore) == 0;
1061
1062 assert_with_errno(succeeded || errno == EAGAIN, "trywait failed");
1063
1064 return succeeded;
1065 }
sem_trywait can also fail with EINTR.
------------------------------------------------------------------------------
src/os/posix/vm/os_posix.cpp
1072 } else if (errno == EINTR) {
1073 continue;
1074 } else if (errno == ETIMEDOUT) {
I think ETIMEDOUT should be tested before EINTR. ETIMEDOUT is the
more interesting and performance relevant case.
------------------------------------------------------------------------------
src/os/windows/vm/os_windows.cpp
1905 WindowsSemaphore::~WindowsSemaphore() {
1906 if (_semaphore != NULL) {
1907 ::CloseHandle(_semaphore);
1908 }
I don't think the NULL check is needed here.
------------------------------------------------------------------------------
src/os/bsd/vm/semaphore_bsd.hpp
56 static jlong currenttime();
This function is an implementation detail of the timedwait function,
and could be a file-scoped static near its caller, rather than having
external linkage.
[The PosixSemaphore class is different in this respect, because there
we need to choose between platform-specific definitions of
create_timespec that will be in a different file from the reference,
so external linkage is required. That situation doesn't apply for
OSXSemaphore.]
------------------------------------------------------------------------------
src/os/windows/vm/semaphore_windows.hpp
30 #include <WinBase.h>
I think <windef.h> is sufficient here, and is purportedly smaller.
The .cpp file likely needs more, but is already including <windows.h>.
Also, it looks like we prefer the lowercase form on Windows, even
though the file system is case-insensitive.
------------------------------------------------------------------------------
src/os/windows/vm/semaphore_windows.hpp
43 void signal(uint count = 0);
Default count of 0 is inconsistent with corresponding classes for
other platforms.
------------------------------------------------------------------------------
src/share/vm/runtime/semaphore.cpp
30 Semaphore::Semaphore(uint value) : _impl(value) {}
31 Semaphore::~Semaphore() {}
32 void Semaphore::signal(uint count) { _impl.signal(count); }
33 void Semaphore::wait() { _impl.wait(); }
I'm not sure why these forwarding definitions are out of line in the
.cpp file, rather than inline in the header. After all, we've now
gone to some trouble to have the wrapped platform-specific
implementation class provide at least that set of operations.
------------------------------------------------------------------------------
More information about the hotspot-dev
mailing list