Skip to content

Commit

Permalink
Issue eclipse-omr#61: Introducing a new Port Library API for obtainin…
Browse files Browse the repository at this point in the history
…g open file count.

Signed-off-by: Sondhi Chakraborty <[email protected]>
  • Loading branch information
sonchakr committed Apr 6, 2016
1 parent b58fd61 commit b18a287
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 4 deletions.
175 changes: 174 additions & 1 deletion fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
#if !(defined(WIN32) || defined(WIN64))
#include <grp.h>
#include <errno.h>
#if defined(J9ZOS390)
#include <limits.h>
#else
#define __STDC_LIMIT_MACROS
#include <stdint.h> /* For INT64_MAX. */
#endif /* defined(J9ZOS390) */
#include <sys/resource.h> /* For RLIM_INFINITY */
#endif /* !(defined(WIN32) || defined(WIN64)) */

#if defined(J9ZOS390)
Expand All @@ -49,6 +56,13 @@
#define J9DIRECTORY_SEPARATOR_CHARACTER '/'
#endif

/* Under the standard compiler configuration, INT64_MAX is
* not available; instead, LONGLONG_MAX is defined by xLC.
*/
#if defined(J9ZOS390) && !defined(INT64_MAX)
#define INT64_MAX LONGLONG_MAX
#endif /* defined(J9ZOS390) && !defined(INT64_MAX) */

/**
* @brief Function takes an expected name for an executable and also the name that was actually
* found using the Port API. It then tries to match these, in a OS specific manner. For example,
Expand Down Expand Up @@ -872,7 +886,95 @@ TEST(PortSysinfoTest, sysinfo_test_sysinfo_set_limit_CORE_FLAGS)
}
#endif /* defined(AIXPPC) */

#endif /* !defined(WIN32) || !defined(WIN64) */
/**
* Test omrsysinfo_test_sysinfo_get_limit for resource OMRPORT_RESOURCE_FILE_DESCRIPTORS.
* API available on all Unix platforms.
*/
TEST(PortSysinfoTest, sysinfo_test_sysinfo_get_limit_FILE_DESCRIPTORS)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_test_sysinfo_get_limit_FILE_DESCRIPTORS";
uint32_t rc = 0;
uint64_t curLimit = 0;
uint64_t maxLimit = 0;

reportTestEntry(OMRPORTLIB, testName);
/* First, get the current (soft) limit on the resource nofiles. */
rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, &curLimit);
if (OMRPORT_LIMIT_UNLIMITED == rc) { /* Not an error, just that it is not configured. */
/* If the API reported this limit as set to "unlimited", the resource limit must be
* set to implementation-defined limit, RLIM_INFINITY.
*/
if (RLIM_INFINITY == curLimit) {
outputComment(OMRPORTLIB,
"omrsysinfo_get_limit(nofiles): soft limit=RLIM_INFINITY (unlimited).\n");
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): soft limit (unlimited), bad maximum reported %lld.\n",
((int64_t) curLimit));
reportTestExit(OMRPORTLIB, testName);
return;
}
} else if (OMRPORT_LIMIT_LIMITED == rc) {
if ((((int64_t) curLimit) > 0) && (((int64_t) curLimit) <= INT64_MAX)) {
outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles) soft limit: %lld.\n",
((int64_t) curLimit));
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles) failed: bad limit received!\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
} else { /* The port library failed! */
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): failed with error code=%d.\n",
omrerror_last_error_number());
reportTestExit(OMRPORTLIB, testName);
return;
}

/* Now, for the hard limit. */
rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS | OMRPORT_LIMIT_HARD, &maxLimit);
if (OMRPORT_LIMIT_UNLIMITED == rc) {
/* Not an error, just that it is not configured. Ok to compare!. */
if (RLIM_INFINITY == maxLimit) {
outputComment(OMRPORTLIB,
"omrsysinfo_get_limit(nofiles): hard limit = RLIM_INFINITY (unlimited).\n");
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): hard limit (unlimited), bad maximum reported %lld.\n",
((int64_t) curLimit));
reportTestExit(OMRPORTLIB, testName);
return;
}
} else if (OMRPORT_LIMIT_LIMITED == rc) {
if ((((int64_t) maxLimit) > 0) && (((int64_t) maxLimit) <= INT64_MAX)) {
outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles) hard limit: %lld.\n",
((int64_t) maxLimit));
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles) failed: bad limit received!\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
} else { /* The port library failed! */
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): failed with error code=%d.\n",
omrerror_last_error_number());
reportTestExit(OMRPORTLIB, testName);
return;
}

/* Ensure that the resource's current (soft) limit does not exceed the hard limit. */
if (curLimit > maxLimit) {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): current limit exceeds the hard limit.\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
reportTestExit(OMRPORTLIB, testName);
}
#endif /* !(defined(WIN32) || defined(WIN64)) */

/* Since the processor and memory usage port library APIs are not available on zOS (neither
* 31-bit not 64-bit) yet, so we exclude these tests from running on zOS. When the zOS
Expand Down Expand Up @@ -1845,4 +1947,75 @@ TEST(PortSysinfoTest, sysinfo_test_get_groups)
}
reportTestExit(OMRPORTLIB, testName);
}

#if defined(LINUX) || defined(AIXPPC)
/**
* Test omrsysinfo_test_get_open_file_count.
* Available only on Linux and AIX.
*/
TEST(PortSysinfoTest, sysinfo_test_get_open_file_count)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_test_get_open_file_count";
int32_t ret = 0;
uint64_t openCount = 0;
uint64_t curLimit = 0;
uint32_t rc = 0;

reportTestEntry(OMRPORTLIB, testName);
/* Get the number of files opened till this point. */
ret = omrsysinfo_get_open_file_count(&openCount);
if (ret < 0) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_open_file_count() failed.\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
outputComment(OMRPORTLIB, "omrsysinfo_get_open_file_count(): Files opened by this process=%lld\n",
openCount);

/* Now, get the current (soft) limit on the resource "nofiles". We check the current
* number of files opened, against this.
*/
rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, &curLimit);
if (OMRPORT_LIMIT_UNLIMITED == rc) {
/* Not really an error, just a sentinel. Comparisons can still work! */
if (RLIM_INFINITY == curLimit) {
outputComment(OMRPORTLIB,
"omrsysinfo_get_limit(nofiles): soft limit=RLIM_INFINITY (unlimited).\n");
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): soft limit (unlimited), bad maximum reported=%lld.\n",
((int64_t) curLimit));
reportTestExit(OMRPORTLIB, testName);
return;
}
} else if (OMRPORT_LIMIT_LIMITED == rc) {
/* Check that the limits received are sane, before comparing against files opened. */
if ((((int64_t) curLimit) > 0) && (((int64_t) curLimit) <= INT64_MAX)) {
outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles): soft limit=%lld.\n",
((int64_t) curLimit));
} else {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles) failed: bad limits received!\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
} else { /* The port library failed! */
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_limit(nofiles): failed with error code=%d.\n",
omrerror_last_error_number());
reportTestExit(OMRPORTLIB, testName);
return;
}
/* Sanity check: are more files reported as opened than the limit? */
if (((int64_t) openCount) > ((int64_t) curLimit)) {
outputErrorMessage(PORTTEST_ERROR_ARGS,
"omrsysinfo_get_open_file_count() failed: reports more files opened than allowed!\n");
reportTestExit(OMRPORTLIB, testName);
return;
}
reportTestExit(OMRPORTLIB, testName);
return;
}
#endif /* defined(LINUX) || defined(AIXPPC) */
#endif /* !(defined(WIN32) || defined(WIN64)) */
4 changes: 4 additions & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
#define OMRPORT_RESOURCE_ADDRESS_SPACE ((uintptr_t) 2)
#define OMRPORT_RESOURCE_CORE_FILE ((uintptr_t) 3)
#define OMRPORT_RESOURCE_CORE_FLAGS ((uintptr_t) 4)
#define OMRPORT_RESOURCE_FILE_DESCRIPTORS ((uintptr_t) 5)
/** @} */

/**
Expand Down Expand Up @@ -1323,6 +1324,8 @@ typedef struct OMRPortLibrary {
intptr_t (*sysinfo_get_tmp)(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen, BOOLEAN ignoreEnvVariable) ;
/** see @ref omrsysinfo.c::omrsysinfo_get_number_CPUs_by_type "omrsysinfo_get_number_CPUs_by_type"*/
void (*sysinfo_set_number_entitled_CPUs)(struct OMRPortLibrary *portLibrary, uintptr_t number) ;
/** see @ref omrsysinfo.c::omrsysinfo_get_open_file_count "omrsysinfo_get_open_file_count"*/
int32_t (*sysinfo_get_open_file_count)(struct OMRPortLibrary *portLibrary, uint64_t *count) ;
/** see @ref omrport.c::omrport_init_library "omrport_init_library"*/
int32_t (*port_init_library)(struct OMRPortLibrary *portLibrary, uintptr_t size) ;
/** see @ref omrport.c::omrport_startup_library "omrport_startup_library"*/
Expand Down Expand Up @@ -1745,6 +1748,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsysinfo_get_number_CPUs_by_type(param1) privateOmrPortLibrary->sysinfo_get_number_CPUs_by_type(privateOmrPortLibrary, (param1))
#define omrsysinfo_get_cwd(param1,param2) privateOmrPortLibrary->sysinfo_get_cwd(privateOmrPortLibrary, (param1), (param2))
#define omrsysinfo_get_tmp(param1,param2,param3) privateOmrPortLibrary->sysinfo_get_tmp(privateOmrPortLibrary, (param1), (param2), (param3))
#define omrsysinfo_get_open_file_count(param1) privateOmrPortLibrary->sysinfo_get_open_file_count(privateOmrPortLibrary, (param1))
#define omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary)
#define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary)
#define omrintrospect_set_suspend_signal_offset(param1) privateOmrPortLibrary->introspect_set_suspend_signal_offset(privateOmrPortLibrary, param1)
Expand Down
2 changes: 2 additions & 0 deletions include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
#define OMRPORT_ERROR_FILE_IO_PENDING (OMRPORT_ERROR_FILE_BASE-38)
#define OMRPORT_ERROR_FILE_READ_NO_BYTES_READ (OMRPORT_ERROR_FILE_BASE-39)
#define OMRPORT_ERROR_FILE_FAILED_TO_ALLOCATE_TLS (OMRPORT_ERROR_FILE_BASE-40)
#define OMRPORT_ERROR_FILE_TOO_MANY_OPEN_FILES (OMRPORT_ERROR_FILE_BASE-41)


/** @} */
Expand Down Expand Up @@ -265,6 +266,7 @@
#define OMRPORT_ERROR_SYSINFO_ERROR_EINVAL (OMRPORT_ERROR_SYSINFO_BASE-13)
#define OMRPORT_ERROR_SYSINFO_ERROR_EFAULT (OMRPORT_ERROR_SYSINFO_BASE-14)
#define OMRPORT_ERROR_SYSINFO_PROCESSOR_COUNT_UNSTABLE (OMRPORT_ERROR_SYSINFO_BASE-15)
#define OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED (OMRPORT_ERROR_SYSINFO_BASE-16)

/**
* @name Port library initialization return codes
Expand Down
1 change: 1 addition & 0 deletions port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ static OMRPortLibrary MasterPortLibraryTable = {
omrsysinfo_get_cwd, /* sysinfo_get_cwd */
omrsysinfo_get_tmp, /* sysinfo_get_tmp */
omrsysinfo_set_number_entitled_CPUs, /* sysinfo_set_number_entitled_CPUs */
omrsysinfo_get_open_file_count, /* sysinfo_get_open_file_count */
omrport_init_library, /* port_init_library */
omrport_startup_library, /* port_startup_library */
omrport_create_library, /* port_create_library */
Expand Down
8 changes: 8 additions & 0 deletions port/common/omrport.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -929,3 +929,11 @@ TraceException=Trc_PRT_cuda_initDeviceData_fail2 Group=cuda Level=1 NoEnv Overhe

TraceException=Trc_PRT_cuda_reset_fail1 Group=cuda Level=1 NoEnv Overhead=1 Template="omrcuda resetDevices: failed to %s current device, error=%d"
TraceException=Trc_PRT_cuda_reset_fail2 Group=cuda Level=1 NoEnv Overhead=1 Template="omrcuda resetDevices: failed to reset device=%u, error=%d"

TraceEntry=Trc_PRT_sysinfo_get_open_file_count_Entry Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count: Entry."
TraceException=Trc_PRT_sysinfo_get_open_file_count_invalidArgRecvd Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count received invalid argument: %s."
TraceException=Trc_PRT_sysinfo_get_open_file_count_failedOpeningProcFS Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count failed opening /proc = %d."
TraceException=Trc_PRT_sysinfo_get_open_file_count_failedReadingProcFS Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count failed reading /proc = %d."
TraceEvent=Trc_PRT_sysinfo_get_open_file_count_fileCount Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count files opened by this process=%llu."
TraceExit=Trc_PRT_sysinfo_get_open_file_count_Exit Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count: Return = %d."

22 changes: 21 additions & 1 deletion port/common/omrsysinfo.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
*
* (c) Copyright IBM Corp. 1991, 2015
* (c) Copyright IBM Corp. 1991, 2016
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 and
Expand Down Expand Up @@ -413,6 +413,8 @@ omrsysinfo_get_groupname(struct OMRPortLibrary *portLibrary, char *buffer, uintp
* Operating system specific core information
* On AIX limit is set to the sys_parm fullcore value
* Not defined on other operating systems
* OMRPORT_RESOURCE_FILE_DESCRIPTORS
* Gets the maximum number of file descriptors that can opened in a process.
*
* resourceID may be bit-wise or'ed with one of:
* OMRPORT_LIMIT_SOFT
Expand Down Expand Up @@ -718,3 +720,21 @@ omrsysinfo_get_tmp(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufL
{
return -1;
}

/**
* Returns the number of files opened in the current process or an error, in
* case of failure.
*
* @param[in] portLibrary instance of port library
* @param[out] count The number of files in opened state in the process.
*
* @return Returns 0 on success or a negative value for failure, setting the
* last error. If OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED is returned,
* last error is not set, as it simply indicates unavailability of the API.
*/
int32_t
omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count)
{
return OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED;
}

3 changes: 2 additions & 1 deletion port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,12 @@ extern J9_CFUNC intptr_t
omrsysinfo_get_CPU_utilization(struct OMRPortLibrary *portLibrary, struct J9SysinfoCPUTime *cpuTime);
extern J9_CFUNC void
omrsysinfo_set_number_entitled_CPUs(struct OMRPortLibrary *portLibrary, uintptr_t number);

extern J9_CFUNC intptr_t
omrsysinfo_get_cwd(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen);
extern J9_CFUNC intptr_t
omrsysinfo_get_tmp(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen, BOOLEAN ignoreEnvVariable);
extern J9_CFUNC int32_t
omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count);

/* J9SourceJ9Signal*/
extern J9_CFUNC int32_t
Expand Down
Loading

0 comments on commit b18a287

Please sign in to comment.