// Send length bytes to dest and wait for a specific reply (and matching sequence nr) int wkcomm_send_and_wait_for_reply(wkcomm_address_t dest, uint8_t command, uint8_t *payload, uint8_t length, uint16_t wait_msec, uint8_t *reply_commands, uint8_t number_of_reply_commands, wkcomm_received_msg **reply) { // Set global variables to wait for the required message types wkcomm_wait_reply_commands = reply_commands; wkcomm_wait_reply_number_of_commands = number_of_reply_commands; wkcomm_received_reply.command = 0; // command will be != 0 once a reply has been received. // Need to store the current sequence nr because other messages might be sent while // waiting for the reply, so we can't use wkcomm_last_seqnr to check the incoming replies. wkcomm_wait_reply_seqnr = ++wkcomm_last_seqnr; // Do the send, and store the seqnr so wkcomm_handle_message can check for a match int8_t retval = wkcomm_do_send(dest, command, payload, length, wkcomm_last_seqnr); if (retval != 0) return retval; // Something went wrong during send. dj_time_t deadline = dj_timer_getTimeMillis() + wait_msec; do { wkcomm_poll(NULL); if (wkcomm_received_reply.command != 0) { // Reply received *reply = &wkcomm_received_reply; wkcomm_wait_reply_number_of_commands = 0; return WKCOMM_SEND_OK; } } while(deadline > dj_timer_getTimeMillis()); return WKCOMM_SEND_ERR_NO_REPLY; }
bool wkpf_get_next_wuobject_to_update(wuobject_t **virtual_wuobject) { if (wuobjects_list == NULL) return false; wuobject_t *wuobject; if (wkpf_get_wuobject_by_index(last_updated_wuobject_index, &wuobject) == WKPF_ERR_WUOBJECT_NOT_FOUND) { // Could happen if objects were deleted wuobject = wuobjects_list; last_updated_wuobject_index = 0; } uint16_t current_index = last_updated_wuobject_index; // wuobject is now pointing to the last updated object do { // Find the first next object that needs to be updated, or the same if there's no other. // Find next object wuobject = wuobject->next; current_index++; if (wuobject == NULL) { wuobject = wuobjects_list; // Wrap around to the first object. current_index = 0; } // Does it need to be updated? if ((wuobject->next_scheduled_update > 0 && wuobject->next_scheduled_update < dj_timer_getTimeMillis()) || wuobject->need_to_call_update) { // Update this object // Clear the flag if it was set wuobject->need_to_call_update = false; // If update has to be called because it's scheduled, schedule the next call if (wuobject->next_scheduled_update > 0 && wuobject->next_scheduled_update < dj_timer_getTimeMillis()) wkpf_schedule_next_update_for_wuobject(wuobject); if (WKPF_IS_NATIVE_WUOBJECT(wuobject)) { // For native wuobjects: call update() directly // Mark wuobject as safe just in case the wuclass does something to trigger GC dj_mem_addSafePointer((void**)&wuobject); DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE: Update native wuobject at port %x\n", wuobject->port_number); wuobject->wuclass->update(wuobject); dj_mem_removeSafePointer((void**)&wuobject); } else { // For virtual wuobject: return it so WKPF.select() can return it to Java *virtual_wuobject = wuobject; last_updated_wuobject_index = current_index; DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE: Update virtual wuobject at port %x\n", wuobject->port_number); return true; } } } while(current_index != last_updated_wuobject_index); return false; // No Java wuobjects need to be updated }
void wkpf_schedule_next_update_for_wuobject(wuobject_t *wuobject) { for (int i=0; i<wuobject->wuclass->number_of_properties; i++) { if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[i]) == WKPF_PROPERTY_TYPE_REFRESH_RATE) { wkpf_refresh_rate_t refresh_rate; wkpf_internal_read_property_refresh_rate(wuobject, i, &refresh_rate); if (refresh_rate == 0) // 0 means turned off wuobject->next_scheduled_update = 0; else wuobject->next_scheduled_update = dj_timer_getTimeMillis() + refresh_rate; DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE: Scheduled next update for object at port %d. Refresh rate:%d Current time:%lu Next update at:%lu\n", wuobject->port_number, refresh_rate, (unsigned long)dj_timer_getTimeMillis(), (unsigned long)wuobject->next_scheduled_update); return; } } }
/** * Wakes threads that are sleeping or blocked. * @param vm the virtual machine context */ void dj_vm_wakeThreads(dj_vm *vm) { dj_thread *thread = vm->threads; dj_monitor * monitor; dj_time_t time = dj_timer_getTimeMillis(); while (thread!=NULL) { // wake sleeping threads if (thread->status==THREADSTATUS_SLEEPING) if (thread->scheduleTime <= time) thread->status=THREADSTATUS_RUNNING; // wake waiting threads that timed out if (thread->status==THREADSTATUS_WAITING_FOR_MONITOR) if ((thread->scheduleTime!=0)&&((int32_t)thread->scheduleTime <= (int32_t)time)) { thread->status=THREADSTATUS_RUNNING; thread->monitorObject=NULL; } // wake blocked threads if (thread->status==THREADSTATUS_BLOCKED_FOR_MONITOR) { monitor = dj_vm_getMonitor(vm, thread->monitorObject); if (monitor->count==0) { monitor->waiting_threads--; monitor->count = 1; monitor->owner = thread; thread->status = THREADSTATUS_RUNNING; } } thread = thread->next; } }
dj_time_t dj_vm_getVMSleepTime(dj_vm * vm) { dj_time_t scheduleTime, time, ret=-1; dj_thread *thread = vm->threads; time = dj_timer_getTimeMillis(); while (thread!=NULL) { if (thread->status==THREADSTATUS_RUNNING) ret = 0; if (thread->status==THREADSTATUS_SLEEPING) { scheduleTime = thread->scheduleTime - time; if (scheduleTime<0) scheduleTime = 0; if (ret==-1||ret>scheduleTime) ret = scheduleTime; } thread = thread->next; } return ret; }
// int javax.darjeeling.Darjeeling.getTime() void javax_darjeeling_Darjeeling_int_getTime() { dj_exec_stackPushInt(dj_timer_getTimeMillis()); }