diff options
-rw-r--r-- | erts/emulator/beam/erl_driver.h | 21 | ||||
-rwxr-xr-x | erts/emulator/beam/global.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/io.c | 3 | ||||
-rw-r--r-- | erts/emulator/drivers/ose/ose_signal_drv.c | 41 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.c | 99 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_poll.h | 20 | ||||
-rw-r--r-- | erts/emulator/sys/ose/erl_ose_sys.h | 14 | ||||
-rw-r--r-- | erts/emulator/sys/ose/erl_poll.c | 116 | ||||
-rw-r--r-- | erts/emulator/sys/ose/sys.c | 49 |
9 files changed, 158 insertions, 208 deletions
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index 9ede2982de..a15b0e17f5 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -272,14 +272,6 @@ typedef struct ErlDrvRWLock_ ErlDrvRWLock; typedef int ErlDrvTSDKey; /* - * Potential OSE signals - */ -#ifdef __OSE__ -typedef union SIGNAL OseSignal; -#endif - - -/* * */ typedef struct erl_drv_port_data_lock * ErlDrvPDL; @@ -353,9 +345,6 @@ typedef struct erl_drv_entry { /* Called on behalf of driver_select when it is safe to release 'event'. A typical unix driver would call close(event) */ -#ifdef __OSE__ - int (*resolve_signal)(OseSignal* sig, int* mode); -#endif /* When adding entries here, dont forget to pad in obsolete/driver.h */ } ErlDrvEntry; @@ -691,11 +680,13 @@ EXTERN int erl_drv_putenv(char *key, char *value); EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size); #ifdef __OSE__ -EXTERN OseSignal *erl_drv_ose_get_output_signal(ErlDrvEvent ev); -EXTERN OseSignal *erl_drv_ose_get_input_signal(ErlDrvEvent ev); -EXTERN ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig,int id); +typedef ErlDrvUInt ErlDrvOseEventId; +EXTERN union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent ev); +EXTERN ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig,ErlDrvOseEventId id, + ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig)); EXTERN void erl_drv_ose_event_free(ErlDrvEvent ev); -EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig,int *id); +EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig, + ErlDrvOseEventId *id); #endif #endif /* !ERL_DRIVER_TYPES_ONLY */ diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 5a97ac5892..8fcb95d0e2 100755 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -160,9 +160,6 @@ struct erts_driver_t_ { void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data); /* Might be NULL */ void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor); void (*stop_select)(ErlDrvEvent event, void*); /* Might be NULL */ -#ifdef __OSE__ - int (*resolve_signal)(OseSignal* sig, int* mode); -#endif }; extern erts_driver_t *driver_list; diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 09681f167d..cd5060ebb3 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -7342,9 +7342,6 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) drv->stop_select = de->stop_select; else drv->stop_select = no_stop_select_callback; -#ifdef __OSE__ - drv->resolve_signal = de->resolve_signal; -#endif if (!de->init) return 0; diff --git a/erts/emulator/drivers/ose/ose_signal_drv.c b/erts/emulator/drivers/ose/ose_signal_drv.c index c1d861cc5a..46890a1503 100644 --- a/erts/emulator/drivers/ose/ose_signal_drv.c +++ b/erts/emulator/drivers/ose/ose_signal_drv.c @@ -392,6 +392,19 @@ static int drv_init(void) { return 0; } +/* Signal resolution callback */ +static ErlDrvOseEventId resolve_signal(union SIGNAL* osig) { + union SIGNAL *sig = osig; + if (sig->signo == ERTS_SIGNAL_OSE_DRV_HUNT || + sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) { + return sig->async.spid; + } + DEBUGP("%p: Got signal %d sent to %p from 0x%p\n", + current_process(),sig->signo,addressee(&sig),sender(&sig)); + return addressee(&sig); +} + + /** * Start routine for the driver **/ @@ -488,11 +501,13 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) DEBUGP("0x%x: open\n",ctxt->spid); ctxt->perm_events[1] = - erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid); + erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid, + resolve_signal); driver_select(ctxt->port,ctxt->perm_events[1],ERL_DRV_READ|ERL_DRV_USE,1); ctxt->perm_events[0] = - erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_HUNT,(int)ctxt->spid); + erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_HUNT,(int)ctxt->spid, + resolve_signal); driver_select(ctxt->port,ctxt->perm_events[0],ERL_DRV_READ|ERL_DRV_USE,1); start(ctxt->spid); @@ -669,7 +684,8 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) EV_GET_UINT32(ev,&signo,&p,&q); } else if (signo < tmp_signo || !ctxt->events) { /* New signal to select on */ - events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid); + events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid, + resolve_signal); driver_select(ctxt->port,events[i++],ERL_DRV_READ|ERL_DRV_USE,1); EV_GET_UINT32(ev,&signo,&p,&q); } else { @@ -708,7 +724,7 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) static void ready_input(ErlDrvData driver_data, ErlDrvEvent event) { driver_context_t *ctxt = (driver_context_t *)driver_data; - union SIGNAL *sig = erl_drv_ose_get_input_signal(event); + union SIGNAL *sig = erl_drv_ose_get_signal(event); while (sig != NULL) { @@ -800,7 +816,7 @@ static void ready_input(ErlDrvData driver_data, ErlDrvEvent event) } free_buf(&sig); - sig = erl_drv_ose_get_input_signal(event); + sig = erl_drv_ose_get_signal(event); } } @@ -858,17 +874,6 @@ static void stop_select(ErlDrvEvent event, void *reserved) erl_drv_ose_event_free(event); } -static int resolve_signal(OseSignal* osig, int *mode) { - union SIGNAL *sig = osig; - if (sig->signo == ERTS_SIGNAL_OSE_DRV_HUNT || - sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) { - return sig->async.spid; - } - DEBUGP("%p: Got signal %d sent to %p from 0x%p\n", - current_process(),sig->signo,addressee(&sig),sender(&sig)); - return addressee(&sig); -} - /** * Setup the driver entry for the Erlang runtime **/ @@ -884,6 +889,6 @@ ErlDrvEntry ose_signal_driver_entry = { .major_version = ERL_DRV_EXTENDED_MAJOR_VERSION, .minor_version = ERL_DRV_EXTENDED_MINOR_VERSION, .driver_flags = ERL_DRV_FLAG_USE_PORT_LOCKING, - .stop_select = stop_select, - .resolve_signal = resolve_signal + .stop_select = stop_select }; + diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index dab056e2df..245841a768 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -79,11 +79,7 @@ typedef char EventStateFlags; #define ERTS_CIO_POLL_INIT ERTS_POLL_EXPORT(erts_poll_init) #define ERTS_CIO_POLL_INFO ERTS_POLL_EXPORT(erts_poll_info) -#ifdef __OSE__ -#define GET_FD(fd) fd->id -#else #define GET_FD(fd) fd -#endif static struct pollset_info { @@ -442,11 +438,7 @@ deselect(ErtsDrvEventState *state, int mode) } } - state->events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, rm_events, 0, &do_wake -#ifdef __OSE__ - ,NULL -#endif - ); + state->events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, rm_events, 0, &do_wake); if (!(state->events)) { switch (state->type) { @@ -595,11 +587,7 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, wake_poller = 1; } - new_events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, ctl_events, on, &wake_poller -#ifdef __OSE__ - ,prt->drv_ptr->resolve_signal -#endif - ); + new_events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, ctl_events, on, &wake_poller); if (new_events & (ERTS_POLL_EV_ERR|ERTS_POLL_EV_NVAL)) { if (state->type == ERTS_EV_TYPE_DRV_SEL && !state->events) { @@ -984,9 +972,6 @@ print_select_op(erts_dsprintf_buf_t *dsbufp, mode & ERL_DRV_WRITE ? " ERL_DRV_WRITE" : "", mode & ERL_DRV_USE ? " ERL_DRV_USE" : "", mode & (ERL_DRV_USE_NO_CALLBACK & ~ERL_DRV_USE) ? "_NO_CALLBACK" : "", -#ifdef __OSE__ - fd->signo, -#endif on); print_driver_name(dsbufp, pp != ERTS_INVALID_ERL_DRV_PORT ? pp->common.id : NIL); erts_dsprintf(dsbufp, "driver %T ", pp != ERTS_INVALID_ERL_DRV_PORT ? pp->common.id : NIL); @@ -1417,20 +1402,26 @@ stale_drv_select(Eterm id, ErtsDrvEventState *state, int mode) } #ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS + #ifdef __OSE__ static SafeHashValue drv_ev_state_hash(void *des) { - SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd; - return val ^ (val >> 8); /* Good enough for aligned pointer values? */ + ErtsSysFdType fd = ((ErtsDrvEventState *) des)->fd; + /* We use hash on signo ^ id in order for steal to happen when the + same signo + fd is selected on by two different ports */ + SafeHashValue val = (SafeHashValue)(fd->signo ^ fd->id); + return val ^ (val >> 8); } static int drv_ev_state_cmp(void *des1, void *des2) { - return ( ((((ErtsDrvEventState *) des1)->fd->id == ((ErtsDrvEventState *) des2)->fd->id) - && (((ErtsDrvEventState *) des1)->fd->signo == ((ErtsDrvEventState *) des2)->fd->signo)) - ? 0 : 1); + ErtsSysFdType fd1 = ((ErtsDrvEventState *) des1)->fd; + ErtsSysFdType fd2 = ((ErtsDrvEventState *) des2)->fd; + if (fd1->signo == fd2->signo && fd1->id == fd2->id) + return 0; + return 1; } -#else +#else /* !__OSE__ && !ERTS_SYS_CONTINOUS_FD_NUMBERS i.e. probably windows */ static SafeHashValue drv_ev_state_hash(void *des) { SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd; @@ -1473,69 +1464,7 @@ static void drv_ev_state_free(void *des) erts_smp_spin_unlock(&state_prealloc_lock); } #endif -#ifdef __OSE__ -OseSignal *erl_drv_ose_get_input_signal(ErlDrvEvent drv_ev) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - ethr_mutex_lock(&ev->mtx); - if (ev->imsgs == NULL) { - ethr_mutex_unlock(&ev->mtx); - return NULL; - } else { - ErtsPollOseMsgList *msg = ev->imsgs; - OseSignal *sig = (OseSignal*)msg->data; - ASSERT(msg->data); - ev->imsgs = msg->next; - ethr_mutex_unlock(&ev->mtx); - erts_free(ERTS_ALC_T_FD_SIG_LIST,msg); - restore(sig); - return sig; - } -} - -OseSignal *erl_drv_ose_get_output_signal(ErlDrvEvent drv_ev) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - ethr_mutex_lock(&ev->mtx); - if (ev->omsgs == NULL) { - ethr_mutex_unlock(&ev->mtx); - return NULL; - } else { - ErtsPollOseMsgList *msg = ev->omsgs; - OseSignal *sig = (OseSignal*)msg->data; - ASSERT(msg->data); - ev->omsgs = 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, int id) { - 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->imsgs = NULL; - ev->omsgs = NULL; - 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; - ethr_mutex_destroy(&ev->mtx); - erts_free(ERTS_ALC_T_DRV_EV,ev); -} - -void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo, int *id) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - if (signo) - *signo = ev->signo; - if (id) - *id = ev->id; -} - -#endif void ERTS_CIO_EXPORT(erts_init_check_io)(void) { diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h index e1ea8fb207..ce8dcd3f90 100644 --- a/erts/emulator/sys/common/erl_poll.h +++ b/erts/emulator/sys/common/erl_poll.h @@ -106,6 +106,23 @@ typedef Uint32 ErtsPollEvents; #define ERTS_POLL_EV_ERR 4 #define ERTS_POLL_EV_NVAL 8 +#ifdef __OSE__ + +typedef struct ErtsPollOseMsgList_ { + struct ErtsPollOseMsgList_ *next; + union SIGNAL *data; +} ErtsPollOseMsgList; + +struct erts_sys_fd_type { + SIGSELECT signo; + ErlDrvOseEventId id; + ErtsPollOseMsgList *msgs; + ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig); + ethr_mutex mtx; +}; + +#endif + #elif ERTS_POLL_USE_EPOLL /* --- epoll ------------------------------- */ #include <sys/epoll.h> @@ -229,9 +246,6 @@ ErtsPollEvents ERTS_POLL_EXPORT(erts_poll_control)(ErtsPollSet, ErtsPollEvents, int on, int* wake_poller -#ifdef __OSE__ - ,int (*decode)(OseSignal* sig, int* mode) -#endif ); void ERTS_POLL_EXPORT(erts_poll_controlv)(ErtsPollSet, ErtsPollControlEntry [], 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)); |