public void unregister(PeerControlInstance instance) { try { this_mon.enter(); Map<PeerControlInstance, instanceWrapper> new_map = new HashMap<PeerControlInstance, instanceWrapper>(instance_map); instanceWrapper wrapper = new_map.remove(instance); if (wrapper == null) { Debug.out("instance wrapper not found"); return; } wrapper.unregister(); instance_map = new_map; registrations_changed = true; } finally { this_mon.exit(); } }
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; } } }
protected void schedule() { latest_time = SystemTime.getMonotonousTime(); SystemTime.registerMonotonousConsumer( new SystemTime.TickConsumer() { public void consume(long time) { synchronized (PeerControlSchedulerPrioritised.this) { latest_time = time; PeerControlSchedulerPrioritised.this.notify(); } } }); ArrayList instances = new ArrayList(); long latest_time_used = 0; int scheduledNext = 0; long currentScheduleStart = latest_time; long last_stats_time = latest_time; while (true) { if (registrations_changed) { try { this_mon.enter(); Iterator it = instances.iterator(); while (it.hasNext()) { if (((instanceWrapper) it.next()).isUnregistered()) { it.remove(); } } for (int i = 0; i < pending_registrations.size(); i++) instances.add(pending_registrations.get(i)); pending_registrations.clear(); // order instances by their priority (lowest number first) Collections.sort(instances); if (instances.size() > 0) { for (int i = 0; i < instances.size(); i++) ((instanceWrapper) instances.get(i)) .setScheduleOffset((SCHEDULE_PERIOD_MILLIS * i) / instances.size()); } scheduledNext = 0; currentScheduleStart = latest_time; registrations_changed = false; } finally { this_mon.exit(); } } tokenDispenser.update(latest_time); for (int i = scheduledNext; i < instances.size(); i++) { instanceWrapper inst = (instanceWrapper) instances.get(i); if (currentScheduleStart + inst.getScheduleOffset() > latest_time_used) break; // too early for next task, continue waiting if (i == 0 || !useWeights) tokenDispenser.refill(); // System.out.println("scheduling "+i+" time:"+latest_time); inst.schedule(); schedule_count++; scheduledNext++; if (scheduledNext >= instances.size()) { scheduledNext = 0; // try to run every task every SCHEDULE_PERIOD_MILLIS on average currentScheduleStart += SCHEDULE_PERIOD_MILLIS; // if tasks hog too much time then delay to prevent massive // catch-up-hammering if (latest_time_used - currentScheduleStart > SCHEDULE_PERIOD_MAX_CATCHUP) currentScheduleStart = latest_time_used + SCHEDULE_PERIOD_MILLIS; } } /* for (Iterator it=instances.iterator();it.hasNext();){ instanceWrapper inst = (instanceWrapper)it.next(); long target = inst.getNextTick(); long diff = target - latest_time_used; if ( diff <= 0 || diff > SCHEDULE_PERIOD_MILLIS ){ inst.schedule(); long new_target = target + SCHEDULE_PERIOD_MILLIS; diff = new_target - latest_time_used; if ( diff <= 0 || diff > SCHEDULE_PERIOD_MILLIS ) new_target = latest_time_used + SCHEDULE_PERIOD_MILLIS; inst.setNextTick( new_target ); } }*/ synchronized (this) { if (latest_time == latest_time_used) { wait_count++; try { long wait_start = SystemTime.getHighPrecisionCounter(); wait(); long wait_time = SystemTime.getHighPrecisionCounter() - wait_start; total_wait_time += wait_time; } catch (Throwable e) { Debug.printStackTrace(e); } } else { yield_count++; Thread.yield(); } latest_time_used = latest_time; } long stats_diff = latest_time_used - 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_used; } } }