/* * Routine: host_set_exception_ports [kernel call] * Purpose: * Sets the host exception port, flavor and * behavior for the exception types specified by the mask. * There will be one send right per exception per valid * port. * Conditions: * Nothing locked. If successful, consumes * the supplied send right. * Returns: * KERN_SUCCESS Changed the special port. * KERN_INVALID_ARGUMENT The host_priv is not valid, * Illegal mask bit set. * Illegal exception behavior */ kern_return_t host_set_exception_ports( host_priv_t host_priv, exception_mask_t exception_mask, ipc_port_t new_port, exception_behavior_t new_behavior, thread_state_flavor_t new_flavor) { register int i; ipc_port_t old_port[EXC_TYPES_COUNT]; if (host_priv == HOST_PRIV_NULL) { return KERN_INVALID_ARGUMENT; } assert(host_priv == &realhost); if (exception_mask & ~EXC_MASK_VALID) { return KERN_INVALID_ARGUMENT; } if (IP_VALID(new_port)) { switch (new_behavior & ~MACH_EXCEPTION_CODES) { case EXCEPTION_DEFAULT: case EXCEPTION_STATE: case EXCEPTION_STATE_IDENTITY: break; default: return KERN_INVALID_ARGUMENT; } } /* Cannot easily check "new_flavor", but that just means that * the flavor in the generated exception message might be garbage: * GIGO */ host_lock(host_priv); for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) { if (exception_mask & (1 << i)) { old_port[i] = host_priv->exc_actions[i].port; host_priv->exc_actions[i].port = ipc_port_copy_send(new_port); host_priv->exc_actions[i].behavior = new_behavior; host_priv->exc_actions[i].flavor = new_flavor; } else old_port[i] = IP_NULL; }/* for */ /* * Consume send rights without any lock held. */ host_unlock(host_priv); for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) if (IP_VALID(old_port[i])) ipc_port_release_send(old_port[i]); if (IP_VALID(new_port)) /* consume send right */ ipc_port_release_send(new_port); return KERN_SUCCESS; }
/* * Routine: host_get_exception_ports [kernel call] * Purpose: * Clones a send right for each of the host's exception * ports specified in the mask and returns the behaviour * and flavor of said port. * * Returns upto [in} CountCnt elements. * * Conditions: * Nothing locked. * Returns: * KERN_SUCCESS Extracted a send right. * KERN_INVALID_ARGUMENT Invalid host_priv specified, * Invalid special port, * Illegal mask bit set. * KERN_FAILURE The thread is dead. */ kern_return_t host_get_exception_ports( host_priv_t host_priv, exception_mask_t exception_mask, exception_mask_array_t masks, mach_msg_type_number_t * CountCnt, exception_port_array_t ports, exception_behavior_array_t behaviors, thread_state_flavor_array_t flavors ) { register int i, j, count; if (host_priv == HOST_PRIV_NULL) return KERN_INVALID_ARGUMENT; if (exception_mask & ~EXC_MASK_ALL) { return KERN_INVALID_ARGUMENT; } assert (host_priv == &realhost); host_lock(host_priv); count = 0; for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) { if (exception_mask & (1 << i)) { for (j = 0; j < count; j++) { /* * search for an identical entry, if found * set corresponding mask for this exception. */ if (host_priv->exc_actions[i].port == ports[j] && host_priv->exc_actions[i].behavior == behaviors[j] && host_priv->exc_actions[i].flavor == flavors[j]) { masks[j] |= (1 << i); break; } }/* for */ if (j == count) { masks[j] = (1 << i); ports[j] = ipc_port_copy_send(host_priv->exc_actions[i].port); behaviors[j] = host_priv->exc_actions[i].behavior; flavors[j] = host_priv->exc_actions[i].flavor; count++; if (count > *CountCnt) { break; } } } }/* for */ host_unlock(host_priv); *CountCnt = count; return KERN_SUCCESS; }
static guint _worker_processNode(Worker* worker, Host* node, SimulationTime barrier) { /* update cache, reset clocks */ worker->cached_node = node; worker->clock_last = SIMTIME_INVALID; worker->clock_now = SIMTIME_INVALID; worker->clock_barrier = barrier; /* lock the node */ host_lock(worker->cached_node); EventQueue* eventq = host_getEvents(worker->cached_node); Event* nextEvent = eventqueue_peek(eventq); /* process all events in the nodes local queue */ guint nEventsProcessed = 0; while(nextEvent && (shadowevent_getTime(nextEvent) < worker->clock_barrier)) { worker->cached_event = eventqueue_pop(eventq); /* make sure we don't jump backward in time */ worker->clock_now = shadowevent_getTime(worker->cached_event); if(worker->clock_last != SIMTIME_INVALID) { utility_assert(worker->clock_now >= worker->clock_last); } /* do the local task */ gboolean complete = shadowevent_run(worker->cached_event); /* update times */ worker->clock_last = worker->clock_now; worker->clock_now = SIMTIME_INVALID; /* finished event can now be destroyed */ if(complete) { shadowevent_free(worker->cached_event); nEventsProcessed++; } /* get the next event, or NULL will tell us to break */ nextEvent = eventqueue_peek(eventq); } /* unlock, clear cache */ host_unlock(worker->cached_node); worker->cached_node = NULL; worker->cached_event = NULL; return nEventsProcessed; }
/* * Kernel interface for setting a special port. */ kern_return_t kernel_set_special_port( host_priv_t host_priv, int id, ipc_port_t port) { ipc_port_t old_port; host_lock(host_priv); old_port = host_priv->special[id]; host_priv->special[id] = port; host_unlock(host_priv); if (IP_VALID(old_port)) ipc_port_release_send(old_port); return KERN_SUCCESS; }
kern_return_t host_get_special_port( host_priv_t host_priv, __unused int node, int id, ipc_port_t *portp) { ipc_port_t port; if (host_priv == HOST_PRIV_NULL || id == HOST_SECURITY_PORT || id > HOST_MAX_SPECIAL_PORT || id < 0) return KERN_INVALID_ARGUMENT; host_lock(host_priv); port = realhost.special[id]; *portp = ipc_port_copy_send(port); host_unlock(host_priv); return KERN_SUCCESS; }
/* Message disaptcher - executed on i860 thread, safe to call i860 methods */ bool i860_cpu_device::handle_msgs() { host_lock(&m_port_lock); int msg = m_port; m_port = 0; host_unlock(&m_port_lock); if(ConfigureParams.Dimension.bI860Thread && msg & MSG_I860_KILL) return false; if(msg & MSG_I860_RESET) reset(); else if(msg & MSG_INTR) intr(); if(msg & MSG_DISPLAY_BLANK) nd_set_blank_state(ND_DISPLAY, host_blank_state(ND_SLOT, ND_DISPLAY)); if(msg & MSG_VIDEO_BLANK) nd_set_blank_state(ND_VIDEO, host_blank_state(ND_SLOT, ND_VIDEO)); if(msg & MSG_DBG_BREAK) debugger('d', "BREAK at pc=%08X", m_pc); return true; }
void i860_cpu_device::send_msg(int msg) { host_lock(&m_port_lock); m_port |= msg; host_unlock(&m_port_lock); }
kern_return_t host_swap_exception_ports( host_priv_t host_priv, exception_mask_t exception_mask, ipc_port_t new_port, exception_behavior_t new_behavior, thread_state_flavor_t new_flavor, exception_mask_array_t masks, mach_msg_type_number_t * CountCnt, exception_port_array_t ports, exception_behavior_array_t behaviors, thread_state_flavor_array_t flavors ) { unsigned int i, j, count; ipc_port_t old_port[EXC_TYPES_COUNT]; if (host_priv == HOST_PRIV_NULL) return KERN_INVALID_ARGUMENT; if (exception_mask & ~EXC_MASK_VALID) { return KERN_INVALID_ARGUMENT; } if (IP_VALID(new_port)) { switch (new_behavior) { case EXCEPTION_DEFAULT: case EXCEPTION_STATE: case EXCEPTION_STATE_IDENTITY: break; default: return KERN_INVALID_ARGUMENT; } } /* Cannot easily check "new_flavor", but that just means that * the flavor in the generated exception message might be garbage: * GIGO */ host_lock(host_priv); assert(EXC_TYPES_COUNT > FIRST_EXCEPTION); for (count=0, i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT && count < *CountCnt; i++) { if (exception_mask & (1 << i)) { for (j = 0; j < count; j++) { /* * search for an identical entry, if found * set corresponding mask for this exception. */ if (host_priv->exc_actions[i].port == ports[j] && host_priv->exc_actions[i].behavior == behaviors[j] && host_priv->exc_actions[i].flavor == flavors[j]) { masks[j] |= (1 << i); break; } }/* for */ if (j == count) { masks[j] = (1 << i); ports[j] = ipc_port_copy_send(host_priv->exc_actions[i].port); behaviors[j] = host_priv->exc_actions[i].behavior; flavors[j] = host_priv->exc_actions[i].flavor; count++; } old_port[i] = host_priv->exc_actions[i].port; host_priv->exc_actions[i].port = ipc_port_copy_send(new_port); host_priv->exc_actions[i].behavior = new_behavior; host_priv->exc_actions[i].flavor = new_flavor; } else old_port[i] = IP_NULL; }/* for */ host_unlock(host_priv); /* * Consume send rights without any lock held. */ while (--i >= FIRST_EXCEPTION) { if (IP_VALID(old_port[i])) ipc_port_release_send(old_port[i]); } if (IP_VALID(new_port)) /* consume send right */ ipc_port_release_send(new_port); *CountCnt = count; return KERN_SUCCESS; }