summaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
AgeCommit message (Expand)Author
2014-04-30timer: Prevent overflow in apply_slackJiri Bohac
2014-04-01Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/ke...Linus Torvalds
2014-03-20timer: Remove code redundancy while calling get_nohz_timer_target()Viresh Kumar
2014-03-20timer: Use variable head instead of &work_list in __run_timers()Viresh Kumar
2014-03-04timer: Make sure TIMER_FLAG_MASK bits are free in allocated baseViresh Kumar
2014-03-04timer: Check failure of timer_cpu_notify() before calling init_timer_stats()Viresh Kumar
2014-02-28Merge branch 'timers.2014.02.25a' of git://git.kernel.org/pub/scm/linux/kerne...Thomas Gleixner
2014-02-25timers: Make internal_add_timer() update ->next_timer if ->active_timers == 0Oleg Nesterov
2014-02-25timers: Reduce future __run_timers() latency for first add to empty listPaul E. McKenney
2014-02-25timers: Reduce future __run_timers() latency for newly emptied listPaul E. McKenney
2014-02-25timers: Reduce __run_timers() latency for empty listPaul E. McKenney
2014-02-25timers: Track total number of timers in listPaul E. McKenney
2014-02-14timer: Spare IPI when deferrable timer is queued on idle remote targetsViresh Kumar
2014-02-13asmlinkage: Make jiffies visibleAndi Kleen
2013-11-19timer: Convert kmalloc_node(...GFP_ZERO...) to kzalloc_node(...)Joe Perches
2013-09-25sched: Introduce preempt_count accessor functionsPeter Zijlstra
2013-07-14kernel: delete __cpuinit usage from all core kernel filesPaul Gortmaker
2013-06-28timer: Fix jiffies wrap behavior of round_jiffies_common()Bart Van Assche
2013-05-15Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/...Linus Torvalds
2013-05-14timer: Don't reinitialize the cpu base lock during CPU_UP_PREPARETirupathi Reddy
2013-05-05Merge branch 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/ke...Linus Torvalds
2013-04-30kernel/timer.c: move some non timer related syscalls to kernel/sys.cStephen Rothwell
2013-04-30kernel/timer.c: convert compat_sys_sysinfo to COMPAT_SYSCALL_DEFINEStephen Rothwell
2013-04-30kernel/compat.c: make do_sysinfo() staticStephen Rothwell
2013-04-03nohz: Rename CONFIG_NO_HZ to CONFIG_NO_HZ_COMMONFrederic Weisbecker
2013-03-21nohz: Wake up full dynticks CPUs when a timer gets enqueuedFrederic Weisbecker
2013-02-19Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/ker...Linus Torvalds
2013-02-07sched: Move sched.h sysctl bits into separate headerClark Williams
2012-11-18printk: Wake up klogd using irq_workFrederic Weisbecker
2012-10-09timers: Fix endless looping between cascade() and internal_add_timer()Hildner, Christian
2012-10-09Merge branch 'fortglx/3.7/time' of git://git.linaro.org/people/jstultz/linux ...Thomas Gleixner
2012-08-21timer: Implement TIMER_IRQSAFETejun Heo
2012-08-21timer: Clean up timer initializersTejun Heo
2012-08-21timer: Generalize timer->base flags handlingTejun Heo
2012-08-19alpha: take a bunch of syscalls into osf_sys.cAl Viro
2012-06-06timers: Improve get_next_timer_interrupt()Thomas Gleixner
2012-06-06timers: Add accounting of non deferrable timersThomas Gleixner
2012-06-06timers: Consolidate base->next_timer updateThomas Gleixner
2012-06-06timers: Create detach_if_pending() and use itThomas Gleixner
2012-05-23Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebi...Linus Torvalds
2012-05-22Merge branch 'for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wqLinus Torvalds
2012-05-15lockdep: fix oops in processing workqueuePeter Zijlstra
2012-05-03userns: Convert setting and getting uid and gid system calls to use kuid and ...Eric W. Biederman
2012-04-26timer: Fix mod_timer_pinned() header commentPaul E. McKenney
2012-01-06Merge branch 'core-debugobjects-for-linus' of git://git.kernel.org/pub/scm/li...Linus Torvalds
2011-12-09sys_getppid: add missing rcu_dereferenceMandeep Singh Baines
2011-11-23timer: Use debugobjects to catch deletion of uninitialized timersChristine Chan
2011-11-23timer: Setup uninitialized timer with a stub callbackStephen Boyd
2011-10-31kernel: Map most files to use export.h instead of module.hPaul Gortmaker
2011-06-03timers: Consider slack value in mod_timer()Sebastian Andrzej Siewior
std::sync::Arc; use std::sync::RwLock; use anyhow::Context; use anyhow::Error; use anyhow::Result; use anyhow::anyhow; use diesel::PgConnection; use futures::FutureExt; use indicatif::ProgressBar; use itertools::Itertools; use tokio::stream::StreamExt; use tokio::sync::mpsc::UnboundedReceiver; use tokio::sync::mpsc::UnboundedSender; use uuid::Uuid; use crate::endpoint::Endpoint; use crate::endpoint::EndpointConfiguration; use crate::filestore::StagingStore; use crate::job::RunnableJob; use crate::log::LogItem; use crate::util::progress::ProgressBars; pub struct EndpointScheduler { endpoints: Vec<Arc<RwLock<Endpoint>>>, staging_store: Arc<RwLock<StagingStore>>, db: Arc<PgConnection>, progressbars: ProgressBars, multibar: indicatif::MultiProgress, submit: crate::db::models::Submit, } impl EndpointScheduler { pub async fn setup(endpoints: Vec<EndpointConfiguration>, staging_store: Arc<RwLock<StagingStore>>, db: Arc<PgConnection>, progressbars: ProgressBars, submit: crate::db::models::Submit) -> Result<Self> { let endpoints = Self::setup_endpoints(endpoints).await?; Ok(EndpointScheduler { endpoints, staging_store, db, progressbars, multibar: indicatif::MultiProgress::new(), submit, }) } async fn setup_endpoints(endpoints: Vec<EndpointConfiguration>) -> Result<Vec<Arc<RwLock<Endpoint>>>> { let unordered = futures::stream::FuturesUnordered::new(); for cfg in endpoints.into_iter() { unordered.push({ Endpoint::setup(cfg) .map(|r_ep| { r_ep.map(RwLock::new) .map(Arc::new) }) }); } unordered.collect().await } /// Schedule a Job /// /// # Warning /// /// This function blocks as long as there is no free endpoint available! pub async fn schedule_job(&self, job: RunnableJob) -> Result<JobHandle> { let endpoint = self.select_free_endpoint().await?; Ok(JobHandle { bar: self.multibar.add(self.progressbars.job_bar(job.uuid())), endpoint, job, staging_store: self.staging_store.clone(), db: self.db.clone(), submit: self.submit.clone(), }) } async fn select_free_endpoint(&self) -> Result<Arc<RwLock<Endpoint>>> { loop { let unordered = futures::stream::FuturesUnordered::new(); for ep in self.endpoints.iter().cloned() { unordered.push(async move { let wl = ep.write().map_err(|_| anyhow!("Lock poisoned"))?; wl.number_of_running_containers().await.map(|u| (u, ep.clone())) }); } let endpoints = unordered.collect::<Result<Vec<_>>>().await?; if let Some(endpoint) = endpoints .iter() .sorted_by(|tpla, tplb| tpla.0.cmp(&tplb.0)) .map(|tpl| tpl.1.clone()) .next() { return Ok(endpoint) } } } } pub struct JobHandle { endpoint: Arc<RwLock<Endpoint>>, job: RunnableJob, bar: ProgressBar, db: Arc<PgConnection>, staging_store: Arc<RwLock<StagingStore>>, submit: crate::db::models::Submit, } impl std::fmt::Debug for JobHandle { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { write!(f, "JobHandle ( job: {} )", self.job.uuid()) } } impl JobHandle { pub async fn run(self) -> Result<Vec<PathBuf>> { use crate::db::models as dbmodels; let (log_sender, log_receiver) = tokio::sync::mpsc::unbounded_channel::<LogItem>(); let ep = self.endpoint .read() .map_err(|_| anyhow!("Lock poisoned"))?; let endpoint = dbmodels::Endpoint::create_or_fetch(&self.db, ep.name())?; let package = dbmodels::Package::create_or_fetch(&self.db, self.job.package())?; let image = dbmodels::Image::create_or_fetch(&self.db, self.job.image())?; let job_id = self.job.uuid().clone(); trace!("Running on Job {} on Endpoint {}", job_id, ep.name()); let res = ep .run_job(self.job, log_sender, self.staging_store); let logres = LogReceiver { job_id, log_receiver, bar: self.bar, db: self.db.clone(), }.join(); let (res, logres) = tokio::join!(res, logres); trace!("Found result for job {}: {:?}", job_id, res); let log = logres.with_context(|| anyhow!("Collecting logs for job on '{}'", ep.name()))?; let (paths, container_hash, script) = res.with_context(|| anyhow!("Running job on '{}'", ep.name()))?; dbmodels::Job::create(&self.db, &job_id, &self.submit, &endpoint, &package, &image, &container_hash, &script, &log)?; Ok(paths) } } struct LogReceiver { job_id: Uuid, log_receiver: UnboundedReceiver<LogItem>, bar: ProgressBar, db: Arc<PgConnection>, } impl LogReceiver { async fn join(mut self) -> Result<String> { use resiter::Map; let mut success = None; let mut accu = vec![]; while let Some(logitem) = self.log_receiver.recv().await { match logitem { LogItem::Line(ref l) => { // ignore }, LogItem::Progress(u) => { self.bar.set_position(u as u64); }, LogItem::CurrentPhase(ref phasename) => { self.bar.set_message(&format!("{} Phase: {}", self.job_id, phasename)); }, LogItem::State(Ok(ref s)) => { self.bar.set_message(&format!("{} State Ok: {}", self.job_id, s)); success = Some(true); }, LogItem::State(Err(ref e)) => { self.bar.set_message(&format!("{} State Err: {}", self.job_id, e)); success = Some(false); }, } accu.push(logitem); } match success { Some(true) => self.bar.finish_with_message(&format!("{} finished successfully", self.job_id)), Some(false) => self.bar.finish_with_message(&format!("{} finished with error", self.job_id)), None => self.bar.finish_with_message(&format!("{} finished", self.job_id)), } Ok({ accu.into_iter() .map(|ll| ll.display()) .map_ok(|d| d.to_string()) .collect::<Result<Vec<String>>>()? .join("\n") }) } }