/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- **************************************************************************** * (C) 2004 Grzegorz Milos - University of Cambridge * Based on the implementation of the BVT scheduler by Rolf Neugebauer * and Mark Williamson (look in sched_bvt.c) **************************************************************************** * * File: common/sched_fair_bvt.c * Author: Grzegorz Milos * * Description: CPU scheduling * implements Fair Borrowed Virtual Time Scheduler. * FBVT is modification of BVT (see Duda & Cheriton SOSP'99) * which tries to allocate fair shares of processor even * when there is mix between CPU and I/O bound domains. * TODO - more information about the scheduler in TODO */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* For tracing - TODO - put all the defines in some common hearder file */ #define TRC_SCHED_FBVT_DO_SCHED 0x00020000 #define TRC_SCHED_FBVT_DO_SCHED_UPDATE 0x00020001 /* all per-domain BVT-specific scheduling info is stored here */ struct fbvt_dom_info { struct domain *domain; /* domain this info belongs to */ struct list_head run_list; /* runqueue pointers */ unsigned long mcu_advance; /* inverse of weight */ u32 avt; /* actual virtual time */ u32 evt; /* effective virtual time */ u32 time_slept; /* amount of time slept */ int warpback; /* warp? */ long warp; /* virtual time warp */ long warpl; /* warp limit */ long warpu; /* unwarp time requirement */ s_time_t warped; /* time it ran warped last time */ s_time_t uwarped; /* time it ran unwarped last time */ }; struct fbvt_cpu_info { spinlock_t run_lock; /* protects runqueue */ struct list_head runqueue; /* runqueue for this CPU */ unsigned long svt; /* XXX check this is unsigned long! */ u32 vtb; /* virtual time bonus */ u32 r_time; /* last time to run */ }; #define FBVT_INFO(p) ((struct fbvt_dom_info *)(p)->sched_priv) #define CPU_INFO(cpu) ((struct fbvt_cpu_info *)(schedule_data[cpu]).sched_priv) #define RUNLIST(p) ((struct list_head *)&(FBVT_INFO(p)->run_list)) #define RUNQUEUE(cpu) ((struct list_head *)&(CPU_INFO(cpu)->runqueue)) #define CPU_SVT(cpu) (CPU_INFO(cpu)->svt) #define LAST_VTB(cpu) (CPU_INFO(cpu)->vtb) #define R_TIME(cpu) (CPU_INFO(cpu)->r_time) #define MCU (s32)MICROSECS(100) /* Minimum unit */ #define MCU_ADVANCE 10 /* default weight */ #define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ static s32 ctx_allow = (s32)MILLISECS(5); /* context switch allowance */ static s32 max_vtb = (s32)MILLISECS(5); /* SLAB cache for struct fbvt_dom_info objects */ static xmem_cache_t *dom_info_cache; /* * Wrappers for run-queue management. Must be called with the run_lock * held. */ static inline void __add_to_runqueue_head(struct domain *d) { list_add(RUNLIST(d), RUNQUEUE(d->processor)); } static inline void __add_to_runqueue_tail(struct domain *d) { list_add_tail(RUNLIST(d), RUNQUEUE(d->processor)); } static inline void __del_from_runqueue(struct domain *d) { struct list_head *runlist = RUNLIST(d); list_del(runlist); runlist->next = NULL; } static inline int __task_on_runqueue(struct domain *d) { return (RUNLIST(d))->next != NULL; } /* * Calculate the effective virtual time for a domain. Take into account * warping limits */ static void __calc_evt(struct fbvt_dom_info *inf) { s_time_t now = NOW(); if ( inf->warpback ) { if ( ((now - inf->warped) < inf->warpl) && ((now - inf->uwarped) > inf->warpu) ) { /* allowed to warp */ inf->evt = inf->avt - inf->warp; } else { /* warped for too long -> unwarp */ inf->evt = inf->avt; inf->uwarped = now; inf->warpback = 0; } } else { inf->evt = inf->avt; } } /** * fbvt_alloc_task - allocate FBVT private structures for a task * @p: task to allocate private structures for * * Returns non-zero on failure. */ int fbvt_alloc_task(struct domain *p) { p->sched_priv = xmem_cache_alloc(dom_info_cache); if ( p->sched_priv == NULL ) return -1; return 0; } /* * Add and remove a domain */ void fbvt_add_task(struct domain *p) { struct fbvt_dom_info *inf = FBVT_INFO(p); ASSERT(inf != NULL); ASSERT(p != NULL); inf->mcu_advance = MCU_ADVANCE; inf->domain = p; if ( p->domain == IDLE_DOMAIN_ID ) { inf->avt = inf->evt = ~0U; } else { /* Set avt and evt to system virtual time. */ inf->avt = CPU_SVT(p->processor); inf->evt = CPU_SVT(p->processor); /* Set some default values here. */ inf->time_slept = 0; inf->warpback = 0; inf->warp = 0; inf->warpl = 0; inf->warpu = 0; } return; } int fbvt_init_idle_task(struct domain *p) { unsigned long flags; if(fbvt_alloc_task(p) < 0) return -1; fbvt_add_task(p); spin_lock_irqsave(&CPU_INFO(p->processor)->run_lock, flags); set_bit(DF_RUNNING, &p->flags); if ( !__task_on_runqueue(p) ) __add_to_runqueue_head(p); spin_unlock_irqrestore(&CPU_INFO(p->processor)->run_lock, flags); return 0; } static void fbvt_wake(struct domain *d) { unsigned long flags; struct fbvt_dom_info *inf = FBVT_INFO(d); struct domain *curr; s_time_t now, min_time; int cpu = d->processor; s32 io_warp; /* The runqueue accesses must be protected */ spin_lock_irqsave(&CPU_INFO(cpu)->run_lock, flags); /* If on the runqueue already then someone has done the wakeup work. */ if ( unlikely(__task_on_runqueue(d)) ) { spin_unlock_irqrestore(&CPU_INFO(cpu)->run_lock, flags); return; } __add_to_runqueue_head(d); now = NOW(); #if 0 /* * XXX KAF: This was
package com.trilead.ssh2;

import java.io.IOException;

import com.trilead.ssh2.sftp.ErrorCodes;


/**
 * Used in combination with the SFTPv3Client. This exception wraps
 * error messages sent by the SFTP server.
 * 
 * @author Christian Plattner, plattner@trilead.com
 * @version $Id: SFTPException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
 */

public class SFTPException extends IOException
{
	private static final long serialVersionUID = 578654644222421811L;

	private final String sftpErrorMessage;
	private final int sftpErrorCode;

	private static String constructMessage(String s, int errorCode)
	{
		String[] detail = ErrorCodes.getDescription(errorCode);

		if (detail == null)
			return s + " (UNKNOW SFTP ERROR CODE)";

		return s + " (" + detail[0] + ": " + detail[1] + ")";
	}

	SFTPException(String msg, int errorCode)
	{
		super(constructMessage(msg, errorCode));
		sftpErrorMessage = msg;
		sftpErrorCode = errorCode;
	}

	/**
	 * Get the error message sent by the server. Often, this
	 * message does not help a lot (e.g., "failure").
	 * 
	 * @return the plain string as sent by the server.
	 */
	public String getServerErrorMessage()
	{
		return sftpErrorMessage;
	}

	/**
	 * Get the error code sent by the server.
	 * 
	 * @return an error code as defined in the SFTP specs.
	 */
	public int getServerErrorCode()
	{
		return sftpErrorCode;
	}

	/**
	 * Get the symbolic name of the error code as given in the SFTP specs.
	 * 
	 * @return e.g., "SSH_FX_INVALID_FILENAME".
	 */
	public String getServerErrorCodeSymbol()
	{
		String[] detail = ErrorCodes.getDescription(sftpErrorCode);

		if (detail == null)
			return "UNKNOW SFTP ERROR CODE " + sftpErrorCode;

		return detail[0];
	}

	/**
	 * Get the description of the error code as given in the SFTP specs.
	 * 
	 * @return e.g., "The filename is not valid."
	 */
	public String getServerErrorCodeVerbose()
	{
		String[] detail = ErrorCodes.getDescription(sftpErrorCode);

		if (detail == null)
			return "The error code " + sftpErrorCode + " is unknown.";

		return detail[1];
	}
}
ructures. */ int fbvt_init_scheduler() { int i; for ( i = 0; i < NR_CPUS; i++ ) { schedule_data[i].sched_priv = xmalloc(sizeof(struct fbvt_cpu_info)); if ( schedule_data[i].sched_priv == NULL ) { printk("Failed to allocate FBVT scheduler per-CPU memory!\n"); return -1; } INIT_LIST_HEAD(RUNQUEUE(i)); spin_lock_init(&CPU_INFO(i)->run_lock); CPU_SVT(i) = 0; /* XXX do I really need to do this? */ } dom_info_cache = xmem_cache_create("FBVT dom info", sizeof(struct fbvt_dom_info), 0, 0, cache_constructor, NULL); if ( dom_info_cache == NULL ) { printk("FBVT: Failed to allocate domain info SLAB cache"); return -1; } return 0; } struct scheduler sched_fbvt_def = { .name = "Fair Borrowed Virtual Time", .opt_name = "fbvt", .sched_id = SCHED_FBVT, .init_scheduler = fbvt_init_scheduler, .init_idle_task = fbvt_init_idle_task, .alloc_task = fbvt_alloc_task, .add_task = fbvt_add_task, .free_task = fbvt_free_task, .do_block = fbvt_do_block, .do_schedule = fbvt_do_schedule, .control = fbvt_ctl, .adjdom = fbvt_adjdom, .dump_settings = fbvt_dump_settings, .dump_cpu_state = fbvt_dump_cpu_state, .sleep = fbvt_sleep, .wake = fbvt_wake, };