00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT! -*- c++ -*- 00002 00003 #ifndef virq_h 00004 #define virq_h 00005 00006 #include "observer.h" 00007 #include "irq.h" 00008 00009 // 00010 // INTERFACE definition follows 00011 // 00012 00013 00014 class Virq : public Irq, public Observer 00015 { 00016 private: 00017 Virq(); 00018 Virq(Virq&); 00019 00020 public: 00021 explicit inline Virq(unsigned irqnum); 00022 00030 inline bool alloc(Receiver *t, bool /*ack_in_kernel*/); 00031 00037 inline bool free(Receiver *t); 00038 00044 inline void hit(); 00045 00046 inline void notify(); 00047 00048 void acknowledge(); 00049 }; 00050 00051 // 00052 // IMPLEMENTATION includes follow (for use by inline functions) 00053 // 00054 00055 00056 #include "config.h" 00057 #include "kdb_ke.h" 00058 #include "atomic.h" 00059 #include "receiver.h" 00060 00061 // 00062 // IMPLEMENTATION of inline functions (and needed classes) 00063 // 00064 00065 00066 00067 00068 inline Virq::Virq(unsigned irqnum) 00069 : Irq(irqnum) 00070 { 00071 } 00072 00073 00082 inline bool 00083 Virq::alloc(Receiver *t, bool /*ack_in_kernel*/) 00084 { 00085 bool ret = cas (&_irq_thread, static_cast<Receiver*>(0), t); 00086 00087 if (ret) 00088 { 00089 _ack_in_kernel = 0; 00090 _queued = 0; 00091 } 00092 00093 return ret; 00094 } 00095 00096 00103 inline bool 00104 Virq::free(Receiver *t) 00105 { 00106 bool ret = cas (&_irq_thread, t, static_cast<Receiver*>(0)); 00107 00108 if (ret) 00109 { 00110 sender_dequeue(t->sender_list()); 00111 } 00112 00113 return ret; 00114 } 00115 00116 00123 inline void 00124 Virq::hit() 00125 { 00126 // We're entered holding the kernel lock, which also means irqs are 00127 // disabled on this CPU (XXX always correct?). We never enable irqs 00128 // in this stack frame (except maybe in a nonnested invocation of 00129 // switch_exec() -> switchin_context()) -- they will be re-enabled 00130 // once we return from it (iret in entry.S:all_irqs) or we switch to 00131 // a different thread. 00132 if (_irq_thread == (void*)-1) /* debugger attached to IRQ */ 00133 { 00134 #if defined(CONFIG_JDB) 00135 kdb_ke("IRQ ENTRY"); 00136 #endif 00137 return; 00138 } 00139 00140 if (! _irq_thread) 00141 return; 00142 00143 if (_queued++ == 0) // increase hit counter 00144 { 00145 set_receiver (_irq_thread); 00146 sender_enqueue(_irq_thread->sender_list()); 00147 00148 // if the thread is waiting for this interrupt, make it ready; 00149 // this will cause it to run irq->receiver_ready(), which 00150 // handles the rest 00151 00152 // XXX careful! This code may run in midst of an ipc_send_regs 00153 // operation (or similar)! 00154 00155 if (_irq_thread->sender_ok (this)) 00156 { 00157 // we don't need to manipulate the state in a safe way 00158 // because we are still running with interrupts turned off 00159 _irq_thread->state_change_dirty(~Thread_busy, Thread_ready); 00160 00161 _irq_thread->ready_enqueue(); 00162 } 00163 } 00164 } 00165 00166 00167 00168 inline void 00169 Virq::notify() 00170 { 00171 hit(); 00172 } 00173 00174 #endif // virq_h