public void register(PeerControlInstance instance) { instanceWrapper wrapper = new instanceWrapper(instance); wrapper.setNextTick(latest_time + random.nextInt(SCHEDULE_PERIOD_MILLIS)); try { this_mon.enter(); Map<PeerControlInstance, instanceWrapper> new_map = new HashMap<PeerControlInstance, instanceWrapper>(instance_map); new_map.put(instance, wrapper); instance_map = new_map; pending_registrations.add(wrapper); registrations_changed = true; } finally { this_mon.exit(); } }
protected void schedule() { SystemTime.registerMonotonousConsumer( new SystemTime.TickConsumer() { public void consume(long time) { synchronized (PeerControlSchedulerBasic.this) { PeerControlSchedulerBasic.this.notify(); } } }); List<instanceWrapper> instances = new LinkedList<instanceWrapper>(); long tick_count = 0; long last_stats_time = SystemTime.getMonotonousTime(); while (true) { if (registrations_changed) { try { this_mon.enter(); Iterator<instanceWrapper> it = instances.iterator(); while (it.hasNext()) { if (it.next().isUnregistered()) { it.remove(); } } for (int i = 0; i < pending_registrations.size(); i++) { instances.add(pending_registrations.get(i)); } pending_registrations.clear(); registrations_changed = false; } finally { this_mon.exit(); } } latest_time = SystemTime.getMonotonousTime(); long current_schedule_count = schedule_count; for (instanceWrapper inst : instances) { long target = inst.getNextTick(); long diff = latest_time - target; if (diff >= 0) { tick_count++; inst.schedule(latest_time); schedule_count++; long new_target = target + SCHEDULE_PERIOD_MILLIS; if (new_target <= latest_time) { new_target = latest_time + (target % SCHEDULE_PERIOD_MILLIS); } inst.setNextTick(new_target); } } synchronized (this) { if (current_schedule_count == schedule_count) { wait_count++; try { long wait_start = SystemTime.getHighPrecisionCounter(); wait(SCHEDULE_PERIOD_MILLIS); long wait_time = SystemTime.getHighPrecisionCounter() - wait_start; total_wait_time += wait_time; } catch (Throwable e) { Debug.printStackTrace(e); } } else { yield_count++; Thread.yield(); } } long stats_diff = latest_time - last_stats_time; if (stats_diff > 10000) { // System.out.println( "stats: time = " + stats_diff + ", ticks = " + tick_count + ", inst = // " + instances.size()); last_stats_time = latest_time; tick_count = 0; } } }