1/** 2 * \file 3 * \brief Kernel control block declarations. 4 */ 5 6/* 7 * Copyright (c) 2014, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <kernel.h> 16#include <kcb.h> 17#include <dispatch.h> 18#include <systime.h> 19 20// this is used to pin a kcb for critical sections 21bool kcb_sched_suspended = false; 22 23void kcb_add(struct kcb* new_kcb) 24{ 25 if (kcb_current->next) { 26 // Insert new KCB in ring 27 assert(kcb_current->prev); 28 29 new_kcb->next = kcb_current->next; 30 new_kcb->prev = kcb_current; 31 new_kcb->next->prev = new_kcb; 32 new_kcb->prev->next = new_kcb; 33 } else { 34 // Only one KCB currently dispatching 35 kcb_current->next = kcb_current->prev = new_kcb; 36 new_kcb->next = new_kcb->prev = kcb_current; 37 } 38} 39 40errval_t kcb_remove(struct kcb *to_remove) 41{ 42 if (to_remove == kcb_current) { 43 if (to_remove->next->next == to_remove) { 44 assert(to_remove->next->prev == to_remove); 45 to_remove->next->next = to_remove->next->prev = NULL; 46 } 47 else { 48 to_remove->prev->next = to_remove->next; 49 to_remove->next->prev = to_remove->prev; 50 } 51 52 // intentionally leaving to_remove->next alone 53 // so switch_kcb doesn't break 54 to_remove->prev = NULL; 55 to_remove->kernel_off = systime_now(); 56 57 return SYS_ERR_OK; 58 } 59 60 // This probably failes atm. 61 for (struct kcb* k = kcb_current->next; k != kcb_current; k = k->next) { 62 if (k == to_remove) { 63 // remove KCB from ring 64 k->prev->next = k->next; 65 k->next->prev = k->prev; 66 67 // Clear ring to disable switching mechanism 68 if (k->next->next == k->next) { 69 k->next->next = k->next->prev = NULL; 70 } 71 72 // Clear next and prev of removed kcb 73 k->next = k->prev = NULL; 74 75 // Update kernel_off & break out if we're done 76 k->kernel_off = systime_now(); 77 return SYS_ERR_OK; 78 } 79 } 80 81 return SYS_ERR_KCB_NOT_FOUND; 82} 83 84void kcb_update_core_id(struct kcb *kcb) 85{ 86#ifdef CONFIG_SCHEDULER_RBED 87 for (struct dcb *d = kcb->queue_head; d; d = d->next) { 88 printk(LOG_NOTE, "[sched] updating current core id to %d for %s\n", 89 my_core_id, get_disp_name(d)); 90 struct dispatcher_shared_generic *disp = 91 get_dispatcher_shared_generic(d->disp); 92 disp->curr_core_id = my_core_id; 93 } 94#elif CONFIG_SCHEDULER_RR 95#error NYI! 96#else 97#error must define scheduler policy in Config.hs 98#endif 99 // do it for dcbs in wakeup queue 100 for (struct dcb *d = kcb->wakeup_queue_head; d; d=d->wakeup_next) { 101 printk(LOG_NOTE, "[wakeup] updating current core id to %d for %s\n", 102 my_core_id, get_disp_name(d)); 103 struct dispatcher_shared_generic *disp = 104 get_dispatcher_shared_generic(d->disp); 105 disp->curr_core_id = my_core_id; 106 } 107 108 for (int i = 0; i < NDISPATCH; i++) { 109 struct capability *cap = &kcb->irq_dispatch[i].cap; 110 if (cap->type == ObjType_EndPointLMP) { 111 printk(LOG_NOTE, "[irq] updating current core id to %d for %s\n", 112 my_core_id, get_disp_name(cap->u.endpointlmp.listener)); 113 struct dispatcher_shared_generic *disp = 114 get_dispatcher_shared_generic(cap->u.endpointlmp.listener->disp); 115 disp->curr_core_id = my_core_id; 116 } 117 } 118} 119