SlideShare a Scribd company logo
1 of 41
Download to read offline
あるコンテキストスイッチの話
えとみ なるあき
OSC名古屋
Kernel/VM探検隊@北陸
お約束
※ コンテキストスイッチのやりかたはいくつか方法(setjmp,longjmpなど)が
あると思いますが、 setjmp,longjmpなどは今回は扱いません。
※ MPカーネルも扱いません...(頭が追いついていないので(´・ω・`))
※ wikipediaのコンテキストスイッチの項目をあらかじめ読んでおくと、
よりいっそう楽しめる内容になっております。
※ trapb命令は覚えておくと良いキーワードです。
※ exception_return()でFPUをON/OFしているというのは重要です。
※ ぴょんぴょんも重要キーワードです。
※ 予習→実装という流れでお話は進みます!
ソースコードはおまけです!
資料のCPUはalphaですがarm、 mips、powerpc
全て実装が違います。
この資料を読んで概念を身につけたあとに、
一人でも自分の好きなCPUの実装を調べた方がいらっしゃったら嬉しいです
これまでのあらすじ
※ ある日のNetBSD/alpha currentでtopをすると
Floating point exceptionでcore dumpする
という事件が発生した!
※ PR-48782でgccのバグだと勘違いして主張してみた!(libmのコンパイルオプションが変更されてた)
“ I think that this case is -mieee-with-inexact option bug.”
※ とりあえず変更はrevretされたので自分でも独自調査
“I think that trapb instruction incompatible with fpu_state_load().”と返答し
へぼパッチを投げる
“lazy FPU context switch”って何?調べてみました!
※ その後、いろいろやりとりして、topのバグでもなく、gccのバグでもなく
カーネルのlazy FPU context switchのコードがバグっていたという結論がでた!
まずコンテキストスイッチとは何なのか?
コンテキストスイッチ (context switch) とは、
複数のプロセスが1つのCPUを共有できるように、
CPUの状態(コンテキスト)を保存したり復元したりする過程のことである。
コンテキストスイッチはマルチタスクオペレーティングシステムに不可欠な機能である。
通常コンテキストスイッチは多くの計算機処理を必要とするため、
オペレーティングシステムの設計においてはコンテキストスイッチを最適化することが重要である。
コンテキストスイッチでは、実行中のプロセスの状態を何らかの方法で保存し、
後にそのプロセスを再開する際にその状態を復元して、
正常に実行を継続できるようにしなければならない。
プロセスの状態には、そのプロセスが使用し得る全てのレジスタ(特にプログラムカウンタ)や、
プロセスの実行に必要となるオペレーティングシステム固有の情報が含まれる。
wikipediaより
ぴょんぴょん
つまりOSのなかでプロセスがぴょんぴょんしている訳ですね!
mi_switch()
ご注文はどのLWPですか?
描いてみた
sh
mi_switch syslog
mi_switch mikutter(ruby)
mi_switch mlterm
shmi_switch
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチするとき、
実行中のプロセスの状態を「どこ」に保存しているのか?
PCB(Process control block)
PCB is 何?
Alphaの浮動小数点レジスタは
64bit X 32本+ FPUコントロールレジスタ
swpctx命令でコンテキストされる
/src/sys/arch/alpha/include/alpha_cpu.h src/sys/arch/alpha/include/pcb.h
src/sys/arch/alpha/include/reg.h
予習として描いてみた(ポルナレフもビックリっーか…)
mikutterのプロセス
mltermのプロセス
CPU
実行中のmikutterから
mltermにスイッチ
不思議な力で
次の実行プロセスは
mltermに決定
mikutterプロセスのPCBに
CPUのレジスタとか保存
mltermプロセスのPCBの内容
をCPUにロード
『The WORLD』 オレだけの時間だぜ
CPU
実行中のmltermから
mikutterにスイッチ
不思議な力で
次の実行プロセスは
mikutterに決定
mltermプロセスのPCBに
CPUのレジスタとか保存
mikutterプロセスのPCBの内容
をCPUにロード
『時』は動き出す….
では実装
(コンテキストスイッチをするところ)
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
/sys/kern/kern_synch.c l
newl
lの情報(PC等)が
lのPCBに保存される
newlの情報(PC等)が
newlのPCBからロードされる
mi_switchが
カーネル内のどこから
呼ばれるか?がミソ
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
別のLWPにコンテキストスイッチする関数
/sys/kern/kern_synch.c
/*
* struct lwp *cpu_switchto(struct lwp *current, struct lwp *next)
* Switch to the specified next LWP
* Arguments:
* a0 'struct lwp *' of the LWP to switch from
* a1 'struct lwp *' of the LWP to switch to
*/
LEAF(cpu_switchto, 0)
LDGP(pv)
beq a0, 1f
/*
* do an inline savectx(), to save old context
*/
ldq a2, L_PCB(a0)
/* NOTE: ksp is stored by the swpctx */
stq s0, PCB_CONTEXT+(0 * 8)(a2) /* store s0 - s6 */
stq s1, PCB_CONTEXT+(1 * 8)(a2)
/sys/arch/alpha/alpha/locore.s
ここまでのおさらい
     ※ OSのなかではプロセスがぴょんぴょんしている
     ※ 違うプロセスに移る時にプロセスの状態を保存する
     ※ 違うプロセスから復帰する時にプロセスの状態を復元する
     ※ 保存する状態はCPUのレジスタとプロセスの情報
     ※ 保存する場所をPCBという
lazy FPU context switchのFPUとは?
Macintosh IIciよりMC68882
FPU(Floating Point Unit、浮動小数点(演算処理)装置)とは、
浮動小数点演算を専門に行う処理装置のこと。
コンピュータの周辺機器のようなアーキテクチャのものもあれば、
CPUと一体化したコプロセッサのようなアーキテクチャのものもある。
wikipediaより
※ FPUは浮動小数点専用のレジスタを持つ
※ でも、どんなプログラムもFPUを使うとは限らない…
※ コンテキストスイッチではCPUのレジスタを保存復帰する
※ FPUのレジスタはサイズがでかい、かつ数が多いので保存復帰が超重い…
lazy FPU context switchとは?
\  __  /
_ (m) _  ピコーン
   |ミ|
/ `´  \
  ( ゚∀゚)
 ノヽノ |
  < <
FPUを使うときだけFPUの内容を
コンテキストスイッチしよう!
つまり、Lazy context switchとは
プロセス切替時に FPUのレジスタを復帰させるのではなく、
プロセス切替後に FPUが使われた時点で初めて復帰させることで
FPUを使わない場合のコンテキストスイッチを軽くする技!なのです!
ΩΩΩ<な、なんだってー!?
PCUとは?
Per CPU Unit (PCU) is an interface to manage synchronization of any per-
CPU context (unit) tied to an LWP context. Typical use of PCU is for
”lazy-switch” synchronization of the FPU state.  NetBSD Kernel Developer's Manual PCU(9)
NetBSDでLazy context switchの対象となるCPU
※ Alpha FPUは1個
※ ARM FPUは1個
※ MIPS FPUは2個(FPUとDSP)
※ PowerPC FPUは2個(FPUとAltiVec/SPE)
※ FPUを無効化出来るCPU
※ 無効化状態でFPUを使おうとすると浮動小数点無効フォルトが発生するCPU
PCUを理解するためのお約束
※ すべてのLWPはFPUが無効の状態で作成される
struct lwp {
/* Scheduling and overall state. */
……….
#if PCU_UNIT_COUNT > 0
struct cpu_info * volatile l_pcu_cpu[PCU_UNIT_COUNT];
uint32_t l_pcu_valid;
#endif
………….
/sys/sys/lwp.h
struct cpu_data {
/*
* The first section is likely to be touched by other CPUs -
* it is cache hot.
*/
lwp_t *cpu_biglock_wanted; /* LWP spinning on biglock */
………..
struct lwp * volatile cpu_pcu_curlwp[PCU_UNIT_COUNT];
……….
/sys/sys/cpu_data.h
← FPUを使用している(た)
LWPのアドレス
← FPUを使用している(た)
  CPU構造体のアドレス
予習として描いてみた
exec
setreg
fpu_state_release
PCBのFPUを保存する領域
を初期化
~MDLWP_FPACTIVEで
FPU無効化フラグを立てる
exception_return FPUが使えなくなる
(*^-゚)vィェィ♪
では実装
(プロセスが作成される所まで)
execve_runproc
/sys/kern/kern_exec.c
static int
execve_runproc(struct lwp *l, struct execve_data * restrict data,
bool no_local_exec_lock, bool is_spawn)
{
struct exec_package * const epp = &data->ed_pack;
int error = 0;
struct proc *p;
……….
/*
* Set initial SP at the top of the stack.
*
* Note that on machines where stack grows up (e.g. hppa), SP points to
* the end of arg/env strings. Userland guesses the address of argc
* via ps_strings::ps_argvstr.
*/
/* Setup new registers and do misc. setup. */
(*epp->ep_esch->es_emul->e_setregs)(l, epp, (vaddr_t)newstack);
if (epp->ep_esch->es_setregs)
(*epp->ep_esch->es_setregs)(l, epp, (vaddr_t)newstack);
……….
/* Discard all PCU state; need to start fresh */
pcu_discard_all(l);
まずはPCBの初期化から
setregs
ユーザープロセスがプログラムを
実行できるようにスタックの設定、
レジスタの初期化を行う
/sys/arch/alpha/alpha/machdep.c
/*
* Set registers on exec.
*/
void
setregs(register struct lwp *l, struct exec_package *pack, vaddr_t stack)
{
struct trapframe *tfp = l->l_md.md_tf;
struct pcb *pcb;
……….
pcb = lwp_getpcb(l);
memset(&pcb->pcb_fp, 0, sizeof(pcb->pcb_fp));
alpha_pal_wrusp(stack);
tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET;
tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3;
tfp->tf_regs[FRAME_A0] = stack; /* a0 = sp */
tfp->tf_regs[FRAME_A1] = 0; /* a1 = rtld cleanup */
tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */
tfp->tf_regs[FRAME_A3] = l->l_proc->p_psstrp; /* a3 = ps_strings */
tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */
←PCBのFPUを保存する領域
を初期化する
execve_runproc
sys/kern/kern_exec.c
static int
execve_runproc(struct lwp *l, struct execve_data * restrict data,
bool no_local_exec_lock, bool is_spawn)
{
struct exec_package * const epp = &data->ed_pack;
int error = 0;
struct proc *p;
……….
/*
* Set initial SP at the top of the stack.
*
* Note that on machines where stack grows up (e.g. hppa), SP points to
* the end of arg/env strings. Userland guesses the address of argc
* via ps_strings::ps_argvstr.
*/
/* Setup new registers and do misc. setup. */
(*epp->ep_esch->es_emul->e_setregs)(l, epp, (vaddr_t)newstack);
if (epp->ep_esch->es_setregs)
(*epp->ep_esch->es_setregs)(l, epp, (vaddr_t)newstack);
……….
/* Discard all PCU state; need to start fresh */
pcu_discard_all(l);
次はFPUの無効化
/sys/kern/subr_pcu.c
FPUを無効化する
const pcu_ops_t fpu_ops = {
.pcu_id = PCU_FPU,
.pcu_state_load = fpu_state_load,
.pcu_state_save = fpu_state_save,
.pcu_state_release = fpu_state_release,
};
const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
[PCU_FPU] = &fpu_ops,
};
/*
* pcu_discard_all: discard PCU state of the given LWP.
*
* Used by exec and LWP exit.
*/
void
pcu_discard_all(lwp_t *l)
{
const uint32_t pcu_valid = l->l_pcu_valid;
if (__predict_true(pcu_valid == 0)) {
/* PCUs are not in use. */
return;
}
for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
if ((pcu_valid & (1U << id)) == 0) {
continue;
}
if (__predict_true(l->l_pcu_cpu[id] == NULL)) {
continue;
}
const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
pcu_lwp_op(pcu, l, PCU_CMD_RELEASE);
}
l->l_pcu_valid = 0;
}
/src/sys/arch/alpha/alpha/machdep.c
親LWPがFPUを使っていたら、
FPUを無効化するために
pcu_lwp_op()内で
pcu_ops_t構造体経由で
fpu_state_release()を呼びます
FPUを無効化する
/*
* Release the FPU.
*/
void
fpu_state_release(struct lwp *l)
{
l->l_md.md_flags &= ~MDLWP_FPACTIVE;
}
/src/sys/arch/alpha/alpha/fp_complete.c
#define MDLWP_FP_C 0x007ffffe /* Extended FP_C Quadword bits */
#define MDLWP_FPACTIVE __BIT(63) /* FPU is active on LWP's PCU CPU */
/src/sys/arch/alpha/include/proc.h
←フラグをセットします
この時点ではまだFPUは無効ではありません!
フラグをセットしただけです。
/*
* exception_return: return from trap, exception, or syscall
*/
IMPORT(ssir, 8)
LEAF(exception_return, 1) /* XXX should be NESTED */
br pv, 1f
……….
/* GET_CPUINFO clobbers v0, t0, t8...t11. */
3: GET_CPUINFO
/* check for AST */
ldq t1, CPU_INFO_CURLWP(v0)
ldl t3, L_MD_ASTPENDING(t1) /* AST pending? */
bne t3, 7f /* yes */
/* no: headed back to user space */
/* Enable the FPU based on whether MDLWP_FPACTIVE is set. */
4: ldq t2, L_MD_FLAGS(t1)
cmplt t2, zero, a0
call_pal PAL_OSF1_wrfen
FPUを無効化した状態でプロセスの作成を完了する
trap()/systemcall()を終了するときに
exception_return()でFPUを
有効化したり無効化したりします
/sys/arch/alpha/alpha/locore.s FENに1を立てるとFPUがON
次にFPUを使ってみる
……….
$main..ng:
lda $30,-64($30)
.cfi_def_cfa_offset 64
stq $26,0($30)
stq $15,8($30)
……….
stl $1,48($15)
ldah $1,$LC0($29) !gprelhigh
ldt $f10,$LC0($1) !gprellow
……….
divt/sui $f12,$f11,$f10
trapb
stt $f10,32($15)
……….
FPUが無効化された状態で
LWPが作成されました!
次はFPUを使ってみましょう!
予習として描いてみた
FPUが使えない状態でLWP作成
浮動小数点命令を発効
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
※ 自分用のPCBに保存してあるFPUのレジスタの内容をFPUにロード
※ exception_return()でFPU有効化
trap()
では実装
(FPUがロードされる所まで)
浮動小数点命令を実行すると、浮動小数点無効フォルトが発生する
/sys/arch/alpha/alpha/trap.c 浮動小数点命令を実行出来るように
fpu_load(pcu_load)を呼びます
/*
* Trap is called from locore to handle most types of processor traps.
* System calls are broken out for efficiency and ASTs are broken out
* to make the code a bit cleaner and more representative of the
* Alpha architecture.
*/
/*ARGSUSED*/
void
trap(const u_long a0, const u_long a1, const u_long a2, const u_long entry,
struct trapframe *framep)
{
struct lwp *l;
struct proc *p;
struct pcb *pcb;
……….
case ALPHA_KENTRY_IF:
/*
* These are always fatal in kernel, and should
never
* happen. (Debugger entry is handled in XentIF.)
……….
case ALPHA_IF_CODE_FEN:
fpu_load();
goto out;
static inline void
fpu_load(void)
{
pcu_load(&fpu_ops);
}
static inline void
fpu_save(void)
{
pcu_save(&fpu_ops);
}
static inline void
fpu_discard(bool valid_p)
{
pcu_discard(&fpu_ops, valid_p);
}
FPUをsave/releaseする
もし、このLWPがFPU(CPU)の
実行権限を取得する「以前」に
別のLWPがFPUを使っていたら
FPUのレジスタをセーブ、リリース
/*
* pcu_load: load/initialize the PCU state of current LWP on current CPU.
*/
void
pcu_load(const pcu_ops_t *pcu)
{
lwp_t *oncpu_lwp, * const l = curlwp;
const u_int id = pcu->pcu_id;
struct cpu_info *ci, *curci;
int s;
……….
/* Save the PCU state on the current CPU, if there is any. */
if ((oncpu_lwp = curci->ci_pcu_curlwp[id]) != NULL) {
pcu_do_op(pcu, oncpu_lwp, PCU_CMD_SAVE | PCU_CMD_RELEASE);
}
……….
/*
* Finally, load the state for this LWP on this CPU. Indicate to
* the load function whether PCU state was valid before this call.
*/
const bool valid = ((1U << id) & l->l_pcu_valid) != 0;
pcu->pcu_state_load(l, valid ? PCU_VALID : 0);
curci->ci_pcu_curlwp[id] = l;
l->l_pcu_cpu[id] = curci;
l->l_pcu_valid |= (1U << id);
splx(s);
}
/sys/kern/subr_pcu.c
FPUをsave/releaseする
/*
* pcu_do_op: save/release PCU state on the current CPU.
*
* => Must be called at IPL_PCU or from the interrupt.
*/
static inline void
pcu_do_op(const pcu_ops_t *pcu, lwp_t * const l, const int flags)
{
struct cpu_info * const ci = curcpu();
const u_int id = pcu->pcu_id;
KASSERT(l->l_pcu_cpu[id] == ci);
if (flags & PCU_CMD_SAVE) {
pcu->pcu_state_save(l);
}
if (flags & PCU_CMD_RELEASE) {
pcu->pcu_state_release(l);
ci->ci_pcu_curlwp[id] = NULL;
l->l_pcu_cpu[id] = NULL;
}
}
/sys/kern/subr_pcu.c
← save/releaseをするから
  割り込まれたくない?
    ∧ ∧___
   /(*゚ー゚) /\
 /| ̄∪∪ ̄|\/
   |  FPU |/
     ̄ ̄ ̄ ̄
  ∧ ∧
 (*゚ー゚)
 |つ ⊂
∼O‐つ
FPUを使いたいのにスイッチ以前のLWPの情報が残ってる….
FPUレジスタの内容を以前のLWPのPCBに保存しないと…
FPUのレジスタの内容だけスイッチ時に
PCBに退避されてないのねん
FPUをsaveする
/*
* Save the FPU state.
*/
void
fpu_state_save(struct lwp *l)
{
struct pcb * const pcb = lwp_getpcb(l);
alpha_pal_wrfen(1);
savefpstate(&pcb->pcb_fp);
alpha_pal_wrfen(0);
}
/*
* savefpstate: Save a process's floating point state.
*
* Arguments:
* a0 'struct fpstate *' to save into
*/
LEAF(savefpstate, 1)
LDGP(pv)
/* save all of the FP registers */
lda t1, FPREG_FPR_REGS(a0) /* get address of FP reg. save area */
stt $f0, (0 * 8)(t1) /* save first register, using hw name */
stt $f1, (1 * 8)(t1) /* etc. */
……….
/*
* Then save the FPCR; note that the necessary 'trapb's are taken
* care of on kernel entry and exit.
*/
mf_fpcr ft0
stt ft0, FPREG_FPR_CR(a0) /* store to FPCR save area */
RET
END(savefpstate)
※alpha_pal_wrfenはfpuを有効にする関数
(引数1で有効、引数0で無効)
一時的にFPUにアクセスするので有効にします
/sys/arch/alpha/alpha/fp_complete.c /sys/arch/alpha/alpha/locore.s
FPUをloadする
※ 現在のLWPのPCB領域に保存してある
FPUレジスタの内容をFPUにロード
※ CPU構造体に現在のLWPのアドレス
LWP構造体に現在のCPU構造体のアドレス
何個目のFPUを使用しているか
をセット
/*
* pcu_load: load/initialize the PCU state of current LWP on current CPU.
*/
void
pcu_load(const pcu_ops_t *pcu)
{
lwp_t *oncpu_lwp, * const l = curlwp;
const u_int id = pcu->pcu_id;
struct cpu_info *ci, *curci;
int s;
……….
/* Save the PCU state on the current CPU, if there is any. */
if ((oncpu_lwp = curci->ci_pcu_curlwp[id]) != NULL) {
pcu_do_op(pcu, oncpu_lwp, PCU_CMD_SAVE | PCU_CMD_RELEASE);
}
……….
/*
* Finally, load the state for this LWP on this CPU. Indicate to
* the load function whether PCU state was valid before this call.
*/
const bool valid = ((1U << id) & l->l_pcu_valid) != 0;
pcu->pcu_state_load(l, valid ? PCU_VALID : 0);
curci->ci_pcu_curlwp[id] = l;
l->l_pcu_cpu[id] = curci;
l->l_pcu_valid |= (1U << id);
splx(s);
}
/sys/kern/subr_pcu.c
FPUをloadする
/*
* Load the float-point context for the current lwp.
*/
void
fpu_state_load(struct lwp *l, u_int flags)
{
struct pcb * const pcb = lwp_getpcb(l);
……….
if ((flags & PCU_VALID) == 0) {
atomic_inc_ulong(&fpevent_use.ev_count);
} else {
atomic_inc_ulong(&fpevent_reuse.ev_count);
}
alpha_pal_wrfen(1);
restorefpstate(&pcb->pcb_fp);
alpha_pal_wrfen(0);
l->l_md.md_flags |= MDLWP_FPACTIVE;
}
※alpha_pal_wrfenはfpuを有効にする関数
(引数1で有効、引数0で無効)
一時的にFPUにアクセスするので有効にします
/sys/arch/alpha/alpha/fp_complete.c /sys/arch/alpha/alpha/locore.s
/*
* restorefpstate: Restore a process's floating point state.
*
* Arguments:
* a0 'struct fpstate *' to restore from
*/
LEAF(restorefpstate, 1)
LDGP(pv)
/*
* Restore the FPCR; note that the necessary 'trapb's are taken care of
* on kernel entry and exit.
*/
ldt ft0, FPREG_FPR_CR(a0) /* load from FPCR save area */
mt_fpcr ft0
/* Restore all of the FP registers. */
lda t1, FPREG_FPR_REGS(a0)/* get address of FP reg. save area */
ldt $f0, (0 * 8)(t1) /* restore first reg., using hw name */
ldt $f1, (1 * 8)(t1) /* etc. */
……….
ldt $f28, (28 * 8)(t1)
ldt $f29, (29 * 8)(t1)
ldt $f30, (30 * 8)(t1)
RET
END(restorefpstate)
ここまでのおさらい
   ※ すべてのLWPはFPUが無効の状態で作成される
   ※ FPUが無効の状態で浮動小数点命令を実行すると
浮動小数点無効フォルトが発生する
   ※ (もしコンテキストスイッチ以前のLWPがFPUを使っていたら)
FPUのレジスタをセーブ、リリースする
∧ ∧  。
(*゚ー゚) /
  | ⊃⊃
∼|   |
  U~U
では応用編へ
予習として描いてみた
FPUが使えない状態でLWP作成
浮動小数点命令を発効
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
※ 自分用のPCBに保存してあるFPUのレジスタの内容をFPUにロード
※ exception_return()でFPU有効化
mi_switch syslog
mi_switch top
浮動小数点命令を発効
浮動小数点命令
普通の命令
trap()
コンテキストスイッチ
pcu_switchpoint()
でFPU無効化マーク
コンテキストスイッチ
pcu_switchpoint()
でFPU無効化マーク
trap()
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
このタイミングでFPUを保存
CPUのコンテキストスイッチと
FPUのコンテキストスイッチが一致しない
では実装
(コンテキストスイッチされるところ)
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
/sys/kern/kern_synch.c l
newl
lの情報(PC等)が
lのPCBに保存される
newlの情報(PC等)が
newlのPCBからロードされる
mi_switchが
カーネル内のどこから
呼ばれるか?がミソ
pcu_switchpoint
/*
* pcu_switchpoint: release PCU state if the LWP is being run on another CPU.
* This routine is called on each context switch by by mi_switch().
*/
void
pcu_switchpoint(lwp_t *l)
{
const uint32_t pcu_valid = l->l_pcu_valid;
int s;
KASSERTMSG(l == curlwp, "l %p != curlwp %p", l, curlwp);
if (__predict_true(pcu_valid == 0)) {
/* PCUs are not in use. */
return;
}
s = splpcu();
for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
if ((pcu_valid & (1U << id)) == 0) {
continue;
}
struct cpu_info * const pcu_ci = l->l_pcu_cpu[id];
if (pcu_ci == NULL || pcu_ci == l->l_cpu) {
continue;
}
const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
pcu->pcu_state_release(l);
}
splx(s);
}
コンテキストスイッチ以前のLWPが
FPUを使っていたら
FPU無効化フラグを立てる
trap()/systemcall()(exception_return)が呼
ばれてもFPUは有効にならない
/sys/kern/subr_pcu.c
おしまい
で、trapb命令は?
※ trapb命令を実行すると特殊なtrapが発生するが、
その処理内で無条件にfpu_load()を呼んでいた!
※ つまり、fpu_load()の二度掛けをしていた
  → それまでの演算結果の破棄….
※ trapb命令は結構面白い命令なのでどっかで発表したいです…
fpu_load()は容量用法を守って正しくお使いください
参考文献 & お世話になった方
OSの一般的な知識
BSDカーネルの設計と実装 -FreeBSD詳解-
Solarisインターナル ―カーネル構造のすべて
Lion’s Commentary on UNIX
はじめてのOSコードリーディング UNIX V6で学ぶカーネルのしくみ
Alphaについて
Alpha Architecture Reference Manual Fourth Edition
Alpha 21264 Microprocessor Hardware Reference Manual
lazy FPU context switchについて
NetBSD Documentation: How lazy FPU context switch works
http://www.netbsd.org/docs/kernel/lazyfpu.html
NetBSD ドキュメンテーション: どのように lazy FPU コンテキストスイッチは動作するのか
http://www.jp.netbsd.org/ja/docs/kernel/lazyfpu.html
夜でもアッサム
http://assam-at-night.blogspot.jp/2006/06/lazy-fpu-context-switchnetbsd.html
お世話になった方&ファボって元気づけてくれた方
Izumi Tsutsui ‫‏‬@tsutsuii
Jun Ebihara ‫‏‬@ebijun、oshimaya ‫‏‬@oshimyja、Kenji Aoyama ‫‏‬@ao_kenji、ご注文はOSvですか? @syuu1228
NONAKA Kimihiro ‫‏‬@nonakap、Hiroshi Tokuda ‫‏‬@tokudahiroshi、 伊織ん@へら ‫‏‬@ioriveur
波打際のだよもんさん ‫‏‬@daemon1995、まあぼ@cub ‫‏‬@marbocub じとめすきー @lycoris_blog
※イカ先生 @impreza_gf8さんにはAlpha Station XP1000を譲っていただきました!
※ mltermはarakiken @arakikenさんの高性能ターミナルエミュレータです! ※ mikutterはおさわり大臣@toshi_aさんの高性能ておくれtwitterクライアントです!

More Related Content

What's hot

Usb接続するアプリを開発した時に試行錯誤した事
Usb接続するアプリを開発した時に試行錯誤した事Usb接続するアプリを開発した時に試行錯誤した事
Usb接続するアプリを開発した時に試行錯誤した事Masataka Kono
 
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまでtechgamecollege
 
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~モノビット エンジン
 
自宅サーバ仮想化
自宅サーバ仮想化自宅サーバ仮想化
自宅サーバ仮想化anubis_369
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
究極のゲーム用通信プロトコル “WebRTC”
究極のゲーム用通信プロトコル “WebRTC”究極のゲーム用通信プロトコル “WebRTC”
究極のゲーム用通信プロトコル “WebRTC”Ryosuke Otsuya
 
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」IIJ
 
UEFI時代のブートローダ
UEFI時代のブートローダUEFI時代のブートローダ
UEFI時代のブートローダTakuya ASADA
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方OpenStack超入門シリーズ いまさら聞けないSwiftの使い方
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方Toru Makabe
 
VPP事始め
VPP事始めVPP事始め
VPP事始めnpsg
 
GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)Wataru NOGUCHI
 
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろうサーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろうDaisuke Masubuchi
 
BuildKitによる高速でセキュアなイメージビルド (LT)
BuildKitによる高速でセキュアなイメージビルド (LT)BuildKitによる高速でセキュアなイメージビルド (LT)
BuildKitによる高速でセキュアなイメージビルド (LT)Akihiro Suda
 
閉域網接続の技術入門
閉域網接続の技術入門閉域網接続の技術入門
閉域網接続の技術入門Masayuki Kobayashi
 
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~UnityTechnologiesJapan002
 
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】WESEEKWESEEK
 

What's hot (20)

WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介
 
Usb接続するアプリを開発した時に試行錯誤した事
Usb接続するアプリを開発した時に試行錯誤した事Usb接続するアプリを開発した時に試行錯誤した事
Usb接続するアプリを開発した時に試行錯誤した事
 
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
 
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
 
自宅サーバ仮想化
自宅サーバ仮想化自宅サーバ仮想化
自宅サーバ仮想化
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
UE4でマルチプレイヤーゲームを作ろう
UE4でマルチプレイヤーゲームを作ろうUE4でマルチプレイヤーゲームを作ろう
UE4でマルチプレイヤーゲームを作ろう
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
究極のゲーム用通信プロトコル “WebRTC”
究極のゲーム用通信プロトコル “WebRTC”究極のゲーム用通信プロトコル “WebRTC”
究極のゲーム用通信プロトコル “WebRTC”
 
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」
余ったPCをルータに変える、ソフトウェアルータ「SEIL/x86」
 
UEFI時代のブートローダ
UEFI時代のブートローダUEFI時代のブートローダ
UEFI時代のブートローダ
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方OpenStack超入門シリーズ いまさら聞けないSwiftの使い方
OpenStack超入門シリーズ いまさら聞けないSwiftの使い方
 
VPP事始め
VPP事始めVPP事始め
VPP事始め
 
GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)
 
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろうサーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
 
BuildKitによる高速でセキュアなイメージビルド (LT)
BuildKitによる高速でセキュアなイメージビルド (LT)BuildKitによる高速でセキュアなイメージビルド (LT)
BuildKitによる高速でセキュアなイメージビルド (LT)
 
閉域網接続の技術入門
閉域網接続の技術入門閉域網接続の技術入門
閉域網接続の技術入門
 
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
 
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】
もう知らずにはいられないGitOpsをArgoCDで学ぶ【WESEEK Tech Conf #3】
 

Viewers also liked

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史知教 本間
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!道化師 堂華
 
Redis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedRedis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedToshiki Inami
 
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例leverages_event
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 InstancesBrendan Gregg
 
Nginx勉強会
Nginx勉強会Nginx勉強会
Nginx勉強会Yuji Otani
 

Viewers also liked (8)

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!
 
Redis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedRedis & Redis HA design with Keepalived
Redis & Redis HA design with Keepalived
 
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
 
nginxの紹介
nginxの紹介nginxの紹介
nginxの紹介
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 Instances
 
Nginx勉強会
Nginx勉強会Nginx勉強会
Nginx勉強会
 

Similar to あるコンテキストスイッチの話

リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズKazuhiro Takahashi
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介MITSUNARI Shigeo
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1Etsuji Nakai
 
ちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをKenichiro MATOHARA
 
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2Computational Materials Science Initiative
 
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)智啓 出川
 
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来Preferred Networks
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側do_aki
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 sandai
 
Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Masaru Oki
 
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)Naoto MATSUMOTO
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu YamamotoInsight Technology, Inc.
 
最近の身の回りの電力事情
最近の身の回りの電力事情最近の身の回りの電力事情
最近の身の回りの電力事情Kenichiro MATOHARA
 

Similar to あるコンテキストスイッチの話 (20)

リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズ
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
 
Opnfv handson apex intro
Opnfv handson apex introOpnfv handson apex intro
Opnfv handson apex intro
 
ちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxを
 
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
 
Minix smp
Minix smpMinix smp
Minix smp
 
What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
 
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
 
不揮発WALバッファ
不揮発WALバッファ不揮発WALバッファ
不揮発WALバッファ
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門
 
Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編
 
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto
 
最近の身の回りの電力事情
最近の身の回りの電力事情最近の身の回りの電力事情
最近の身の回りの電力事情
 

More from nullnilaki

あるブートローダの話
あるブートローダの話あるブートローダの話
あるブートローダの話nullnilaki
 
最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話nullnilaki
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話nullnilaki
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~nullnilaki
 
あるクリスマスの話
あるクリスマスの話あるクリスマスの話
あるクリスマスの話nullnilaki
 
あるmmapの話
あるmmapの話あるmmapの話
あるmmapの話nullnilaki
 
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 DEC_6600,DEC_TITAN Implementation of NetBSD(仮) DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)nullnilaki
 

More from nullnilaki (7)

あるブートローダの話
あるブートローダの話あるブートローダの話
あるブートローダの話
 
最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
 
あるクリスマスの話
あるクリスマスの話あるクリスマスの話
あるクリスマスの話
 
あるmmapの話
あるmmapの話あるmmapの話
あるmmapの話
 
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 DEC_6600,DEC_TITAN Implementation of NetBSD(仮) DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 

Recently uploaded

デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 

Recently uploaded (12)

デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 

あるコンテキストスイッチの話