summaryrefslogtreecommitdiff
path: root/Utilities/cmlibuv/src/unix/os390.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibuv/src/unix/os390.c')
-rw-r--r--Utilities/cmlibuv/src/unix/os390.c175
1 files changed, 162 insertions, 13 deletions
diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c
index 2ba5abf35..081438e8e 100644
--- a/Utilities/cmlibuv/src/unix/os390.c
+++ b/Utilities/cmlibuv/src/unix/os390.c
@@ -25,6 +25,9 @@
#include <utmpx.h>
#include <unistd.h>
#include <sys/ps.h>
+#include <builtins.h>
+#include <termios.h>
+#include <sys/msg.h>
#if defined(__clang__)
#include "csrsic.h"
#else
@@ -32,6 +35,7 @@
#endif
#define CVT_PTR 0x10
+#define PSA_PTR 0x00
#define CSD_OFFSET 0x294
/*
@@ -69,6 +73,18 @@
/* CPC model length from the CSRSI Service. */
#define CPCMODEL_LENGTH 16
+/* Pointer to the home (current) ASCB. */
+#define PSAAOLD 0x224
+
+/* Pointer to rsm address space block extension. */
+#define ASCBRSME 0x16C
+
+/*
+ NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE.
+ It does not include 2G frames.
+*/
+#define RAXFMCT 0x2C
+
/* Thread Entry constants */
#define PGTH_CURRENT 1
#define PGTH_LEN 26
@@ -76,6 +92,9 @@
#pragma linkage(BPX4GTH, OS)
#pragma linkage(BPX1GTH, OS)
+/* TOD Clock resolution in nanoseconds */
+#define TOD_RES 4.096
+
typedef unsigned data_area_ptr_assign_type;
typedef union {
@@ -100,7 +119,7 @@ void uv_loadavg(double avg[3]) {
int uv__platform_loop_init(uv_loop_t* loop) {
uv__os390_epoll* ep;
- ep = epoll_create1(UV__EPOLL_CLOEXEC);
+ ep = epoll_create1(0);
loop->ep = ep;
if (ep == NULL)
return -errno;
@@ -118,9 +137,10 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
uint64_t uv__hrtime(uv_clocktype_t type) {
- struct timeval time;
- gettimeofday(&time, NULL);
- return (uint64_t) time.tv_sec * 1e9 + time.tv_usec * 1e3;
+ unsigned long long timestamp;
+ __stckf(&timestamp);
+ /* Convert to nanoseconds */
+ return timestamp / TOD_RES;
}
@@ -337,13 +357,17 @@ uint64_t uv_get_total_memory(void) {
int uv_resident_set_memory(size_t* rss) {
- W_PSPROC buf;
+ char* psa;
+ char* ascb;
+ char* rax;
+ size_t nframes;
- memset(&buf, 0, sizeof(buf));
- if (w_getpsent(0, &buf, sizeof(W_PSPROC)) == -1)
- return -EINVAL;
+ psa = PSA_PTR;
+ ascb = *(char* __ptr32 *)(psa + PSAAOLD);
+ rax = *(char* __ptr32 *)(ascb + ASCBRSME);
+ nframes = *(unsigned int*)(rax + RAXFMCT);
- *rss = buf.ps_size;
+ *rss = nframes * sysconf(_SC_PAGESIZE);
return 0;
}
@@ -364,7 +388,6 @@ int uv_uptime(double* uptime) {
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv_cpu_info_t* cpu_info;
- int result;
int idx;
siv1v2 info;
data_area_ptr cvt = {0};
@@ -663,11 +686,124 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
return 0;
}
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ uv_fs_event_stop(handle);
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+ return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
+ const char* filename, unsigned int flags) {
+ uv__os390_epoll* ep;
+ _RFIS reg_struct;
+ char* path;
+ int rc;
+
+ if (uv__is_active(handle))
+ return -EINVAL;
+
+ ep = handle->loop->ep;
+ assert(ep->msg_queue != -1);
+
+ reg_struct.__rfis_cmd = _RFIS_REG;
+ reg_struct.__rfis_qid = ep->msg_queue;
+ reg_struct.__rfis_type = 1;
+ memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle));
+
+ path = uv__strdup(filename);
+ if (path == NULL)
+ return -ENOMEM;
+
+ rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
+ if (rc != 0)
+ return -errno;
+
+ uv__handle_start(handle);
+ handle->path = path;
+ handle->cb = cb;
+ memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok,
+ sizeof(handle->rfis_rftok));
+
+ return 0;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ uv__os390_epoll* ep;
+ _RFIS reg_struct;
+ int rc;
+
+ if (!uv__is_active(handle))
+ return 0;
+
+ ep = handle->loop->ep;
+ assert(ep->msg_queue != -1);
+
+ reg_struct.__rfis_cmd = _RFIS_UNREG;
+ reg_struct.__rfis_qid = ep->msg_queue;
+ reg_struct.__rfis_type = 1;
+ memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
+ sizeof(handle->rfis_rftok));
+
+ /*
+ * This call will take "/" as the path argument in case we
+ * don't care to supply the correct path. The system will simply
+ * ignore it.
+ */
+ rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
+ if (rc != 0 && errno != EALREADY && errno != ENOENT)
+ abort();
+
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+static int os390_message_queue_handler(uv__os390_epoll* ep) {
+ uv_fs_event_t* handle;
+ int msglen;
+ int events;
+ _RFIM msg;
+
+ if (ep->msg_queue == -1)
+ return 0;
+
+ msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT);
+
+ if (msglen == -1 && errno == ENOMSG)
+ return 0;
+
+ if (msglen == -1)
+ abort();
+
+ events = 0;
+ if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE)
+ events = UV_CHANGE;
+ else if (msg.__rfim_event == _RFIM_RENAME)
+ events = UV_RENAME;
+ else
+ /* Some event that we are not interested in. */
+ return 0;
+
+ handle = *(uv_fs_event_t**)(msg.__rfim_utok);
+ handle->cb(handle, uv__basename_r(handle->path), events, 0);
+ return 1;
+}
+
+
void uv__io_poll(uv_loop_t* loop, int timeout) {
static const int max_safe_timeout = 1789569;
struct epoll_event events[1024];
struct epoll_event* pe;
struct epoll_event e;
+ uv__os390_epoll* ep;
int real_timeout;
QUEUE* q;
uv__io_t* w;
@@ -745,9 +881,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
SAVE_ERRNO(uv__update_time(loop));
if (nfds == 0) {
assert(timeout != -1);
- timeout = real_timeout - timeout;
- if (timeout > 0)
+
+ if (timeout > 0) {
+ timeout = real_timeout - timeout;
continue;
+ }
return;
}
@@ -779,6 +917,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (fd == -1)
continue;
+ ep = loop->ep;
+ if (fd == ep->msg_queue) {
+ os390_message_queue_handler(ep);
+ continue;
+ }
+
assert(fd >= 0);
assert((unsigned) fd < loop->nwatchers);
@@ -843,7 +987,12 @@ void uv__set_process_title(const char* title) {
}
int uv__io_fork(uv_loop_t* loop) {
- uv__platform_loop_delete(loop);
+ /*
+ Nullify the msg queue but don't close it because
+ it is still being used by the parent.
+ */
+ loop->ep = NULL;
+ uv__platform_loop_delete(loop);
return uv__platform_loop_init(loop);
}