aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/ose
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/sys/ose')
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys.h14
-rw-r--r--erts/emulator/sys/ose/erl_poll.c116
-rw-r--r--erts/emulator/sys/ose/sys.c49
3 files changed, 98 insertions, 81 deletions
diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h
index 8c72afa9a5..db8607b650 100644
--- a/erts/emulator/sys/ose/erl_ose_sys.h
+++ b/erts/emulator/sys/ose/erl_ose_sys.h
@@ -56,20 +56,6 @@
# include "sys/mman.h"
#endif
-typedef struct ErtsPollOseMsgList_ {
- struct ErtsPollOseMsgList_ *next;
- void *data;
-} ErtsPollOseMsgList;
-
-struct erts_sys_fd_type {
- SIGSELECT signo;
- int id;
- ErtsPollOseMsgList *imsgs;
- ErtsPollOseMsgList *omsgs;
- ethr_mutex mtx;
-};
-
-
/*
* Min number of async threads
*/
diff --git a/erts/emulator/sys/ose/erl_poll.c b/erts/emulator/sys/ose/erl_poll.c
index b1e256afc3..78dc275c06 100644
--- a/erts/emulator/sys/ose/erl_poll.c
+++ b/erts/emulator/sys/ose/erl_poll.c
@@ -103,7 +103,7 @@ typedef struct erts_sigsel_info_ ErtsSigSelInfo;
struct erts_sigsel_info_ {
ErtsSigSelInfo *next;
SIGSELECT signo;
- int (*decode)(OseSignal* sig, int* mode);
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig);
ErtsSigSelItem *fds;
};
@@ -131,8 +131,10 @@ static int max_fds = -1;
/* signal list prototypes */
static ErtsSigSelInfo *get_sigsel_info(ErtsPollSet ps, SIGSELECT signo);
static ErtsSigSelItem *get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd);
-static ErtsSigSelInfo *add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd, int (*decode)(OseSignal* sig, int* mode));
-static ErtsSigSelItem *add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd, int (*decode)(OseSignal* sig, int* mode));
+static ErtsSigSelInfo *add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig));
+static ErtsSigSelItem *add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd,
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig));
static int del_sigsel_info(ErtsPollSet ps, ErtsSigSelInfo *info);
static int del_sigsel_item(ErtsPollSet ps, ErtsSigSelItem *item);
static int update_sigsel(ErtsPollSet ps);
@@ -170,7 +172,7 @@ get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd) {
static ErtsSigSelInfo *
add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
- int (*decode)(OseSignal* sig, int* mode)) {
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig)) {
ErtsSigSelInfo *info = SEL_ALLOC(ERTS_ALC_T_POLLSET,
sizeof(ErtsSigSelInfo));
info->next = ps->info;
@@ -184,7 +186,7 @@ add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
static ErtsSigSelItem *
add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd,
- int (*decode)(OseSignal* sig, int* mode)) {
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig)) {
ErtsSigSelInfo *info = get_sigsel_info(ps,fd->signo);
ErtsSigSelItem *item = SEL_ALLOC(ERTS_ALC_T_POLLSET,
sizeof(ErtsSigSelItem));
@@ -394,8 +396,7 @@ void erts_poll_interrupt_timed(ErtsPollSet ps,int set,erts_short_time_t msec) {
}
ErtsPollEvents erts_poll_control(ErtsPollSet ps, ErtsSysFdType fd,
- ErtsPollEvents pe, int on, int* do_wake,
- int(*decode)(OseSignal* sig, int* mode)) {
+ ErtsPollEvents pe, int on, int* do_wake) {
ErtsSigSelItem *curr;
ErtsPollEvents new_events;
int old_sig_count;
@@ -406,11 +407,17 @@ ErtsPollEvents erts_poll_control(ErtsPollSet ps, ErtsSysFdType fd,
ERTS_POLLSET_LOCK(ps);
+ if (on && (pe & ERTS_POLL_EV_IN) && (pe & ERTS_POLL_EV_OUT)) {
+ /* Check to make sure both in and out are not used at the same time */
+ new_events = ERTS_POLL_EV_NVAL;
+ goto done;
+ }
+
curr = get_sigsel_item(ps, fd);
old_sig_count = ps->sig_count;
if (curr == NULL && on) {
- curr = add_sigsel_item(ps, fd, decode);
+ curr = add_sigsel_item(ps, fd, fd->resolve_signal);
} else if (curr == NULL && !on) {
new_events = ERTS_POLL_EV_NVAL;
goto done;
@@ -451,7 +458,7 @@ int erts_poll_wait(ErtsPollSet ps,
SysTimeval *utvp) {
int res = ETIMEDOUT, no_fds, currid = 0;
OSTIME timeout;
- OseSignal *sig;
+ union SIGNAL *sig;
// HARDTRACEF("%ux: In erts_poll_wait",ps);
if (ps->interrupt == (PROCESS)0)
ps->interrupt = current_process();
@@ -515,8 +522,7 @@ int erts_poll_wait(ErtsPollSet ps,
}
{
ErtsSigSelInfo *info = get_sigsel_info(ps, sig->sig_no);
- int mode = -1;
- struct erts_sys_fd_type fd = { sig->sig_no, info->decode(sig, &mode) };
+ struct erts_sys_fd_type fd = { sig->sig_no, info->decode(sig) };
ErtsSigSelItem *item = get_sigsel_item(ps, &fd);
ASSERT(sig);
@@ -546,38 +552,16 @@ int erts_poll_wait(ErtsPollSet ps,
erts_send_error_to_logger_nogl(dsbufp);
timeout = 0;
ASSERT(0);
- } else if (mode == -1 && item->events == (ERTS_POLL_EV_IN|ERTS_POLL_EV_OUT)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(
- dsbufp,
- "erts_poll_wait() failed: found ambigous signal id %d (signo %u) "
- "(curr_proc 0x%x /sender 0x%x)\n You have to give a specify a mode "
- "in the resolve_signal callback for this signal.\n",
- fd.id, fd.signo, current_process(), sender(&sig));
- erts_send_error_to_logger_nogl(dsbufp);
- timeout = 0;
- ASSERT(0);
- } else {
+ } else {
int i;
struct erts_sys_fd_type *fd = NULL;
ErtsPollOseMsgList *tl,*new;
- /* Figure out which mode to set and which queue to store
- the signal in */
- if (mode == -1)
- mode = item->events;
- else if (mode == 0)
- mode = ERTS_POLL_EV_IN;
- else if (mode == 1)
- mode = ERTS_POLL_EV_OUT;
- else
- abort();
-
/* Check if this fd has already been triggered by a previous signal */
for (i = 0; i < currid;i++) {
if (pr[i].fd == item->fd) {
fd = pr[i].fd;
- pr[i].events |= mode;
+ pr[i].events |= item->events;
break;
}
}
@@ -585,7 +569,7 @@ int erts_poll_wait(ErtsPollSet ps,
/* First time this fd is triggered */
if (fd == NULL) {
pr[currid].fd = item->fd;
- pr[currid].events = mode;
+ pr[currid].events = item->events;
fd = item->fd;
timeout = 0;
currid++;
@@ -597,16 +581,10 @@ int erts_poll_wait(ErtsPollSet ps,
new->data = sig;
ethr_mutex_lock(&fd->mtx);
- if (mode & ERTS_POLL_EV_IN)
- tl = fd->imsgs;
- else if (mode & ERTS_POLL_EV_OUT)
- tl = fd->omsgs;
+ tl = fd->msgs;
if (tl == NULL) {
- if (mode & ERTS_POLL_EV_IN)
- fd->imsgs = new;
- else if (mode & ERTS_POLL_EV_OUT)
- fd->omsgs = new;
+ fd->msgs = new;
} else {
while (tl->next != NULL)
tl = tl->next;
@@ -742,3 +720,53 @@ void erts_poll_init(void)
HARDTRACEF("Out %s", __FUNCTION__);
}
+
+
+/* OSE driver functions */
+
+union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent drv_ev) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ ethr_mutex_lock(&ev->mtx);
+ if (ev->msgs == NULL) {
+ ethr_mutex_unlock(&ev->mtx);
+ return NULL;
+ } else {
+ ErtsPollOseMsgList *msg = ev->msgs;
+ union SIGNAL *sig = (union SIGNAL*)msg->data;
+ ASSERT(msg->data);
+ ev->msgs = msg->next;
+ ethr_mutex_unlock(&ev->mtx);
+ erts_free(ERTS_ALC_T_FD_SIG_LIST,msg);
+ restore(sig);
+ return sig;
+ }
+}
+
+ErlDrvEvent
+erl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id,
+ ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig)) {
+ struct erts_sys_fd_type *ev = erts_alloc(ERTS_ALC_T_DRV_EV,
+ sizeof(struct erts_sys_fd_type));
+ ev->signo = signo;
+ ev->id = id;
+ ev->msgs = NULL;
+ ev->resolve_signal = resolve_signal;
+ ethr_mutex_init(&ev->mtx);
+ return (ErlDrvEvent)ev;
+}
+
+void erl_drv_ose_event_free(ErlDrvEvent drv_ev) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ ASSERT(ev->msgs == NULL);
+ ethr_mutex_destroy(&ev->mtx);
+ erts_free(ERTS_ALC_T_DRV_EV,ev);
+}
+
+void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo,
+ ErlDrvOseEventId *id) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ if (signo)
+ *signo = ev->signo;
+ if (id)
+ *id = ev->id;
+}
diff --git a/erts/emulator/sys/ose/sys.c b/erts/emulator/sys/ose/sys.c
index b786d19ecf..ad82e4587d 100644
--- a/erts/emulator/sys/ose/sys.c
+++ b/erts/emulator/sys/ose/sys.c
@@ -576,7 +576,7 @@ static void ready_output(ErlDrvData, ErlDrvEvent);
static void output(ErlDrvData, char*, ErlDrvSizeT);
static void outputv(ErlDrvData, ErlIOVec*);
static void stop_select(ErlDrvEvent, void*);
-static int resolve_signal(OseSignal* sig, int *mode) {
+static ErlDrvOseEventId resolve_signal(union SIGNAL* sig) {
return sig->sig_no == ERTS_SIGNAL_FD_DRV_ASYNC ? sig->sys_async.type : -1;
}
@@ -605,8 +605,7 @@ struct erl_drv_entry spawn_driver_entry = {
ERL_DRV_EXTENDED_MINOR_VERSION,
ERL_DRV_FLAG_USE_PORT_LOCKING,
NULL, NULL,
- stop_select,
- resolve_signal
+ stop_select
};
struct erl_drv_entry fd_driver_entry = {
NULL,
@@ -631,8 +630,7 @@ struct erl_drv_entry fd_driver_entry = {
0, /* ERL_DRV_FLAGs */
NULL, /* handle2 */
NULL, /* process_exit */
- stop_select,
- resolve_signal
+ stop_select
};
static int set_driver_data(ErlDrvPort port_num,
@@ -645,7 +643,7 @@ static int set_driver_data(ErlDrvPort port_num,
{
Port *prt;
ErtsSysReportExit *report_exit;
- OseSignal *sig;
+ union SIGNAL *sig;
/*erts_fprintf(stderr, " %s / pid %x / ofd %d / ifd %d\n",
__FUNCTION__, current_process(), ofd, ifd);*/
@@ -664,10 +662,12 @@ static int set_driver_data(ErlDrvPort port_num,
if (read_write & DO_READ)
report_exit->in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ifd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ifd,
+ resolve_signal);
if (read_write & DO_WRITE)
report_exit->out_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ofd,
+ resolve_signal);
report_exit_list = report_exit;
}
@@ -684,7 +684,8 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ifd].alive = 1;
driver_data[ifd].status = 0;
driver_data[ifd].in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ifd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ifd,
+ resolve_signal);
driver_data[ifd].in_proc = create_process(OS_PRI_PROC,"beam_fd_reader",
fd_reader_process, 0x800,
@@ -700,7 +701,8 @@ static int set_driver_data(ErlDrvPort port_num,
if (read_write & DO_WRITE) {
driver_data[ifd].ofd = ofd;
driver_data[ifd].out_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd,
+ resolve_signal);
driver_data[ifd].pdl = driver_pdl_create(port_num);
driver_data[ifd].out_proc =
create_process(OS_PRI_PROC,"beam_fd_writer",
@@ -729,7 +731,8 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ofd].alive = 1;
driver_data[ofd].status = 0;
driver_data[ofd].in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd,
+ resolve_signal);
driver_data[ofd].out_sig_descr = driver_data[ofd].in_sig_descr;
driver_data[ofd].out_proc =
create_process(OS_PRI_PROC, "beam_fd_writer",
@@ -783,7 +786,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num,
}
OS_PROCESS(fd_reader_process) {
- OseSignal *sig;
+ union SIGNAL *sig;
PROCESS parent;
int fd;
byte *read_buf;
@@ -844,7 +847,7 @@ OS_PROCESS(fd_reader_process) {
}
OS_PROCESS(fd_writer_process) {
- OseSignal *sig;
+ union SIGNAL *sig;
PROCESS parent;
int fd;
SIGSELECT sigsel[] = { 1, ERTS_SIGNAL_FD_DRV_CONFIG,
@@ -1105,7 +1108,7 @@ static void outputv(ErlDrvData e, ErlIOVec* ev)
driver_pdl_unlock(driver_data[fd].pdl);
}
else {
- OseSignal *sig;
+ union SIGNAL *sig;
/* fprintf(stderr,"0x%x: outputv, enq+sel\n", current_process()); */
driver_enqv(ix, ev, 0); /* n is the skip value */
driver_pdl_unlock(driver_data[fd].pdl);
@@ -1151,7 +1154,7 @@ static void output(ErlDrvData e, char* buf, ErlDrvSizeT len)
set_busy_port(ix, 1);
}
else {
- OseSignal *sig;
+ union SIGNAL *sig;
/* fprintf(stderr,"0x%x: output, enq+select\n", current_process()); */
#if 0
iv[0].iov_base = lbp;
@@ -1219,13 +1222,13 @@ static int port_inp_failure(ErlDrvPort port_num, ErlDrvEvent ready_fd, int res)
}
static int async_read(ErlDrvEvent fd, byte *buff, int size) {
- OseSignal *sigptr = erl_drv_ose_get_input_signal(fd);
+ union SIGNAL *sigptr = erl_drv_ose_get_signal(fd);
int res = sigptr->sys_async.res;
if (res > 0)
memcpy(buff,sigptr->sys_async.buff,sigptr->sys_async.res);
errno = sigptr->sys_async.errno_copy;
send(&sigptr,sender(&sigptr));
- ASSERT(erl_drv_ose_get_input_signal(fd) == NULL);
+ ASSERT(erl_drv_ose_get_signal(fd) == NULL);
return res;
}
@@ -1360,7 +1363,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
{
int fd = (int)(long)e;
ErlDrvPort ix = driver_data[fd].port_num;
- OseSignal *sigptr = erl_drv_ose_get_output_signal(ready_fd);
+ union SIGNAL *sigptr = erl_drv_ose_get_signal(ready_fd);
ssize_t n;
struct iovec* iv;
int vsize;
@@ -1374,7 +1377,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
driver_select(ix, ready_fd, ERL_DRV_WRITE, 0);
set_busy_port(ix, 0);
free_buf(&sigptr);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* 0; */
continue;
}
@@ -1384,7 +1387,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
if (errno == ERRNO_BLOCK || errno == EINTR) {
/* fprintf(stderr,"0x%x: ready_output, send to %x\n", current_process(),driver_data[fd].out_proc);*/
send(&sigptr,driver_data[fd].out_proc);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* 0; */
continue;
} else {
@@ -1393,7 +1396,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
free_buf(&sigptr);
driver_select(ix, ready_fd, ERL_DRV_WRITE, 0);
driver_failure_posix(ix, res);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* -1; */
continue;
}
@@ -1410,7 +1413,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
else
continue;
}
- sigptr = erl_drv_ose_get_output_signal(ready_fd);
+ sigptr = erl_drv_ose_get_signal(ready_fd);
}
return; /* 0; */
}
@@ -1752,7 +1755,7 @@ erts_sys_main_thread(void)
while (1) {
static const SIGSELECT sigsel[] = {0};
- OseSignal *msg = receive(sigsel);
+ union SIGNAL *msg = receive(sigsel);
fprintf(stderr,"Main thread got message %d from 0x%x!!\r\n",
msg->sig_no, sender(&msg));