void do_irq (context_t context) { int flags; hw_save_flags_and_cli (flags); #if 1 irq_nesting_counter ++; if (hw_irq_ctrl [context.irqnr].ack) hw_ack_irq (context.irqnr); #endif if (irq_handler_table [context.irqnr]) (*irq_handler_table [context.irqnr]) (&context); else default_irq_handler (&context); #if 1 if (hw_irq_ctrl [context.irqnr].end) hw_end_irq (context.irqnr); irq_nesting_counter --; #endif hw_restore_flags (flags); if (irq_nesting_counter == SCHED_PENDING) { scheduling (); } do_signals(); }
int main() { Job job1 = {1, 2, 0, 1}; Job job2 = {2, 1, 0, 0}; Job job3 = {3, 1, 0, 3}; Job job4 = {4, 3, 0, 4}; Job jobs[] = {job1, job2, job3, job4}; printf("Before:\n"); printf_jobs(jobs, 4); scheduling(jobs, 4); printf("After:\n"); printf_jobs(jobs, 4); }
asmlinkage int pthread_join_sys (pthread_t thread, void **value_ptr) { int flags, c_state; pthread_t old_thread; if (!thread || thread -> magic_number != PTHREAD_MAGIC_NUMBER) { SET_ERRNO (ESRCH); return -1; } if (GET_THREAD_DETACH_STATE(thread)) { SET_ERRNO (EINVAL); return -1; } hw_save_flags_and_cli (flags); c_state = GET_THREAD_STATE (thread); while (c_state != FINISHED_THREAD) { thread -> joining_thread = current_thread; //printf("suspend_thread current_thread 0x%x thread 0x%x\n", (unsigned long)current_thread, (unsigned long)thread); old_thread = current_thread; suspend_thread (current_thread); //printf("current_thread 0x%x join 0x%x c_state %d flags %d\n", (unsigned long)current_thread, (unsigned long)thread, c_state, flags); scheduling (); //ret_may_switch(current_thread, old_thread); //printf("current_thread 0x%x join 0x%x c_state %d flags %d\n", (unsigned long)current_thread, (unsigned long)thread, c_state, flags); c_state = GET_THREAD_STATE (thread); if (GET_THREAD_DETACH_STATE(thread)) { hw_restore_flags (flags); SET_ERRNO (EINVAL); return -1; } } if (value_ptr) *value_ptr = thread -> exit_value; //printf("thread 0x%x exit_value 0x%x\n", (unsigned long)current_thread, thread->exit_value); delete_pthread_struct (thread); hw_restore_flags (flags); return 0; }
void* reschedule (void* ptr) { struct timespec ts; Scheduler* sched = (Scheduler*) (ptr); while (1) { pthread_mutex_lock (&mutex3); scheduling (sched); //Calls the scheduling algorithm function at regular interval //usleep(SCHED_PERIOD*QUANTUM); if (clock_gettime(CLOCK_REALTIME, &ts) == -1) printf("clock_gettime"); ts.tv_sec+=2; pthread_cond_timedwait (&cond,&mutex3,&ts); //if (pthread_cond_timedwait (&cond,&mutex3,&ts) == 110)printf ("TIMEOUT SCHEDULER\n"); //else printf ("\tIO CALL EXIT\n"); pthread_mutex_unlock (&mutex3); } }
asmlinkage int pthread_detach_sys (pthread_t thread) { int flags; if (!thread || thread -> magic_number != PTHREAD_MAGIC_NUMBER) { SET_ERRNO (ESRCH); return -1; } if (GET_THREAD_DETACH_STATE(thread)) { SET_ERRNO (EINVAL); return -1; } hw_save_flags_and_cli (flags); SET_THREAD_DETACH_STATE(thread, 1); activate_thread (current_thread -> joining_thread); current_thread -> joining_thread = 0; hw_restore_flags (flags); scheduling (); return 0; }
asmlinkage int pthread_create_sys (pthread_t *thread, const pthread_attr_t *attr, void *(*startup)(void *), void *(*start_routine)(void *), void *args) { int flags; hw_save_flags_and_cli (flags); // Check policy & prio if (attr) { if (attr->policy != SCHED_FIFO) { SET_ERRNO(EINVAL); return -1; } else { if (attr -> sched_param.sched_priority > MIN_SCHED_PRIORITY || attr -> sched_param.sched_priority < MAX_SCHED_PRIORITY) { SET_ERRNO(EINVAL); return -1; } } } // Creating the pthread structure if (!(*thread = create_pthread_struct ())) { SET_ERRNO (EAGAIN); hw_restore_flags (flags); return -1; } /* * Configuring the new thread either with attr (if not NULL) * or with the default values */ if (attr) { (*thread) -> sched_param = attr -> sched_param; (*thread) -> stack_info.stack_size = attr -> stack_size; (*thread) -> stack_info.stack_bottom = attr -> stack_addr; SET_THREAD_DETACH_STATE((*thread), attr -> detachstate); SET_THREAD_POLICY ((*thread), attr -> policy); } else { (*thread) -> sched_param.sched_priority = MIN_SCHED_PRIORITY; (*thread) -> stack_info.stack_size = STACK_SIZE; (*thread) -> stack_info.stack_bottom = 0; SET_THREAD_DETACH_STATE((*thread), 0); SET_THREAD_POLICY ((*thread), SCHED_FIFO); } if (!((*thread) -> stack_info.stack_bottom)) { // Creating the thread stack if (alloc_stack (&(*thread) -> stack_info) < 0) { SET_ERRNO (EAGAIN); hw_restore_flags (flags); return -1; } } // This is arhictecture dependent (*thread) -> stack = setup_stack ((*thread)->stack_info.stack_bottom + (*thread)->stack_info.stack_size / sizeof (int), startup, start_routine, args); activate_thread (*thread); pthread_t tmp = *thread; printf("pthred_create_sys thread 0x%x state:%d\n", (unsigned long)tmp, GET_THREAD_STATE(tmp)); // no error at all hw_restore_flags (flags); // Calling the scheduler scheduling (); return 0; }
BOOST_FIXTURE_TEST_CASE( advertising_scheduled, advertising ) { BOOST_CHECK_GT( scheduling().size(), 0 ); }
int Decoder_LDPC_IEEE_802_11ad::Run() { unsigned int pchk_satisfied; unsigned int iter = 0; bool next_iter_is_last_iter = false; bool last_iter = false; decoding_successful().Write(false); num_modified_systematic_bits().Write(0); if(param_list_.config_modified()) Init(); // Read the channel values and store them in app_ram_. Init_APP_RAM(is_IRA_code_, input_bits_llr(), app_ram_); do { // Perform one ldpc decoder iteration. switch(scheduling()) { case LAYERED: pchk_satisfied = Decode_Layered(app_ram_, msg_ram_, iter); break; case TWO_PHASE: pchk_satisfied = Decode_Two_Phase(app_ram_, msg_ram_, iter, app_parity_check()); break; default: pchk_satisfied = 0; Msg(ERROR, instance_name(), "Selected scheduling not supported for these codes!"); break; } /* * Read the app_ram_ and store APP values in output_bits_llr_app() and * hard decoded bits in output_bits buffer. */ Read_APP_RAM(app_ram_, iter, output_bits_llr_app(), output_bits()); // Check whether all parity checks were satisfied in the previous iteration. last_iter = next_iter_is_last_iter; // Are all parity checks satisfied? if (pchk_satisfied == num_check_nodes_) { decoding_successful().Write(true); next_iter_is_last_iter = true; // Do one more iteration, as it is done in hardware! } // Store the number of flipped bits if (iter != 0) { flipped_bits(iter)().Write(Calc_Flipped_Bits(iter, output_bits())); } // Increase iteration counter. iter++; mean_iterations(iter)().Write(iter); /* * Abort conditions: * 1) maximum number of iterations is reached * 2) all parity checks are satisfied: Since the hardware performs one more * iteration after all parity checks are satisfied, we delay the stopping * in the software as well. */ } while (iter < num_iterations() && last_iter == false); // Write the number of unsatisfied parity checks. num_unsatisfied_parity_checks().Write(num_check_nodes_ - pchk_satisfied); // Set number of used iterations in output buffer. iterations_performed().Write(iter); // Get statistic about modified bits. num_modified_systematic_bits().Write(Calc_Modified_Systematic_Bits(iter, input_bits_llr(), output_bits())); // Fill the output buffer and the status port for the remaining iterations. for(unsigned int i = iter; i < num_iterations(); i++) { mean_iterations(i + 1)().Write(iter); output_bits_llr_app()[i] = output_bits_llr_app()[iter - 1]; output_bits()[i] = output_bits()[iter - 1]; } return 0; }
void Codegen_C::make_code() { // a clone of the whole hierarchy ++Inst::cur_op_id; Vec<Expr> out, created; for( Expr inst : fresh ) out << cloned( inst, created ); // simplifications // e.g. ReplBits offset in bytes if possible // slices that do not change the size for( Expr &e : created ) e->codegen_simplification( created, out ); update_created( created, out ); // display if necessary if ( disp_inst_graph ) Inst::display_graph( out ); // scheduling (and creation of IfInst) Inst *beg = scheduling( out ); update_created( created, out ); // display if necessary if ( disp_inst_graph_wo_phi ) Inst::display_graph( out ); // get reg constraints struct GetConstraint : Inst::Visitor { virtual bool operator()( Inst *inst ) { inst->get_constraints(); return true; } }; GetConstraint gc; beg->visit_sched( gc, true ); // // DisplayConstraints dv; // beg->visit_sched( dv ); // assign (missing) out_reg struct AssignOutReg : Inst::Visitor { virtual bool operator()( Inst *inst ) { if ( inst->out_reg or not inst->need_a_register() ) return true; // make a new reg CppOutReg *out_reg = cc->new_out_reg( inst->type() ); // assign out_reg + constraint propagation () Vec<InstAndPort> assigned_ports; if ( not assign_port_rec( assigned_ports, inst, -1, out_reg ) ) { std::cerr << "base constraint cannot be fullfilled !\n"; return false; } // edges and optionnal constraints int num_edge = 0; // , num_optionnal_constraint = 0; while ( true ) { // there's an edge for propagation ? if ( num_edge < assigned_ports.size() ) { InstAndPort port = assigned_ports[ num_edge++ ]; if ( port.is_an_output() ) { // sort parents by apparition order struct SortBySchedNum { bool operator()( const Inst::Parent &a, const Inst::Parent &b ) const { return a.inst->sched_num < b.inst->sched_num; } }; port.inst->update_sched_num(); std::sort( port.inst->par.begin(), port.inst->par.end(), SortBySchedNum() ); // try to propagate the reg through each output edge CppOutReg *reg = port.inst->out_reg; for( Inst::Parent &p : port.inst->par ) { // std::cout << " " << *port.inst << " -> " << *p.inst << std::endl; for( Inst *inst = port.inst; ; inst = inst->next_sched ) { // target is reached ? if ( inst == p.inst ) { // assign input port, or insert a copy instruction if ( not assign_port_rec( assigned_ports, p.inst, p.ninp, reg ) ) insert_copy_inst_before( assigned_ports, inst, p ); break; } // if there a conflict if ( not inst->used_reg_ok_for( reg, port.inst ) ) { // add a copy inst insert_copy_inst_before( assigned_ports, inst, p ); break; } // -> say that here, reg should be the output of port.inst (and nothing else) inst->add_used_reg( reg, port.inst ); } } } else { CppOutReg *reg = port.inst->inp_reg[ port.ninp() ]; if ( Inst *dst = port.inst->inp[ port.ninp() ].inst ) { // std::cout << " " << *port.inst << " <- " << *dst << " " << reg << std::endl; for( Inst *inst = port.inst->prev_sched; ; inst = inst->prev_sched ) { if ( not inst ) { PRINT( *port.inst ); PRINT( *dst ); ERROR( "..." ); } // target is reached ? if ( inst == dst ) { Inst *beg_reg = dst; // assign output port, or insert a copy instruction if ( not assign_port_rec( assigned_ports, dst, -1, reg ) ) { insert_copy_inst_after( assigned_ports, dst, port ); beg_reg = dst->next_sched; // reg will be used starting from the copy inst } // -> register the use of reg as output of beg_reg for( Inst *d = beg_reg; d != port.inst; d = d->next_sched ) inst->add_used_reg( reg, beg_reg ); break; } // if there is a conflict if ( not inst->used_reg_ok_for( reg, dst ) ) { // add a copy inst insert_copy_inst_after( assigned_ports, inst, port ); // -> register the use of reg as output of beg_reg for( Inst *c = inst->next_sched, *d = c; d != port.inst; d = d->next_sched ) inst->add_used_reg( reg, c ); break; } } } } continue; } // constraint that would be good to fullfill // if ( num_optionnal_constraint < assigned_ports.size() ) { // InstAndPort port = assigned_ports[ num_optionnal_constraint++ ]; // for( std::pair<const Inst::PortConstraint,int> &c : port.inst->same_out ) // if ( c.second != Inst::COMPULSORY and c.first.src_ninp == port.ninp_constraint() ) // assign_port_rec( assigned_ports, c.first.dst_inst, c.first.dst_ninp, out_reg ); // continue; // } // nothing to propagate break; } return true; } Codegen_C *cc; }; AssignOutReg aor; aor.cc = this; beg->visit_sched( aor, true ); // display if necessary // if ( disp_inst_graph_wo_phi ) { // beg->update_sched_num(); // Inst::display_graph( out ); // } // specify where the registers have to be declared for( int n = 0; n < out_regs.size(); ++n ) { CppOutReg *reg = &out_regs[ n ]; Inst *anc = reg->common_provenance_ancestor(); anc->reg_to_decl << reg; } // write the code for( Inst *inst = beg; inst; inst = inst->next_sched ) write( inst ); }
Inst *Codegen_C::scheduling( Vec<Expr> out ) { // update inst->when for( Expr inst : out ) inst->update_when( BoolOpSeq( True() ) ); // get the front ++Inst::cur_op_id; Vec<Expr> front; for( Expr inst : out ) get_front( front, inst ); ++Inst::cur_op_id; for( Expr inst : front ) inst->op_id = Inst::cur_op_id; // go to the roots Inst *beg = 0, *end; ++Inst::cur_op_id; while ( front.size() ) { // try to find an instruction with the same condition set or an inst that is not going to write anything Inst *inst = 0; for( int i = 0; i < front.size(); ++i ) { if ( front[ i ]->when->always( false ) ) { front.remove_unordered( i-- ); continue; } if ( front[ i ]->when->always( true ) ) { inst = front[ i ].inst; front.remove_unordered( i ); break; } } // if not possible to do more without a condition if ( not inst ) { if ( not front.size() ) break; // try to find the best condition to move forward std::map<BoolOpSeq,int> possible_conditions; for( int i = 0; i < front.size(); ++i ) { Vec<BoolOpSeq> pc = front[ i ]->when->common_terms(); PRINT( *front[ i ]->when ); PRINT( pc.size() ); for( int c = 0; c < pc.size(); ++c ) std::cout << " " << pc[ c ]; std::cout << "\n"; for( BoolOpSeq &item : pc ) ++possible_conditions[ item ]; } int best_score = -1; BoolOpSeq best_item; for( const std::pair<BoolOpSeq,int> &p : possible_conditions ) { if ( best_score < p.second ) { best_score = p.second; best_item = p.first; } } // start the input list with the conditions std::map<Inst *,OutCondFront> outputs; // inst to replace -> replacement values + IfOut pos std::map<Expr,int> inputs; std::set<Expr> deps; inputs[ best_item.expr() ] = 0; // get a front of instructions that must be done under the condition `cond` Vec<Expr> ok_we_inp = extract_inst_that_must_be_done_if( outputs, inputs, deps, front, best_item , 1 ); Vec<Expr> ko_we_inp = extract_inst_that_must_be_done_if( outputs, inputs, deps, front, not best_item, 0 ); // for( std::pair<Expr,int> i : inputs ) // std::cout << " inp=" << *i.first << " num=" << i.second << std::endl; // for( std::pair<Inst *,OutCondFront> o : outputs ) // std::cout << " to_be_repl=" << *o.first << "\n ok=" << o.second.inp[ 1 ] << "\n ko=" << o.second.inp[ 0 ] << "\n num=" << o.second.num_in_outputs << std::endl; Expr if_inp_ok = make_if_inp( inputs, deps, ok_we_inp ); Expr if_inp_ko = make_if_inp( inputs, deps, ko_we_inp ); Expr if_out_ok = make_if_out( outputs, 1 ); Expr if_out_ko = make_if_out( outputs, 0 ); // complete the If instruction Vec<Expr> inp( Size(), inputs.size() ); for( std::pair<Expr,int> i : inputs ) inp[ i.second ] = i.first; Expr if_expr = if_inst( inp, if_inp_ok, if_inp_ko, if_out_ok, if_out_ko ); *if_expr->when = BoolOpSeq( True() ); // use the outputs of the if instruction Vec<Expr> if_out_sel( Size(), outputs.size() ); for( int i = 0; i < if_out_sel.size(); ++i ) { if_out_sel[ i ] = get_nout( if_expr, i ); *if_out_sel[ i ]->when = BoolOpSeq( True() ); } for( std::pair<Inst *,OutCondFront> o : outputs ) for( Inst::Parent &p : o.first->par ) if ( p.ninp >= 0 ) p.inst->mod_inp( if_out_sel[ o.second.num_in_outputs ], p.ninp ); else p.inst->mod_dep( if_out_sel[ o.second.num_in_outputs ], o.first ); // add dep to the if instruction for( Expr d : deps ) if_expr->add_dep( d ); // push if_expr in the front // if_expr->op_id = Inst::cur_op_id - 1; // front << if_expr; inst = if_expr.inst; } // register inst->op_id = Inst::cur_op_id; // say that it's done if ( not beg ) { beg = inst; end = inst; } else { end->next_sched = inst; inst->prev_sched = end; end = inst; } // update the front for( Inst::Parent &p : inst->par ) { if ( ready_to_be_scheduled( p.inst ) ) { p.inst->op_id = Inst::cur_op_id - 1; // -> in the front front << p.inst; } } } // delayed operation (ext blocks) for( Inst *inst = beg; inst; inst = inst->next_sched ) { // schedule sub block (ext instructions) for( int ind = 0; ind < inst->ext_disp_size(); ++ind ) { Inst *ext_beg = scheduling( inst->ext[ ind ] ); ext_beg->par_ext_sched = inst; inst->ext_sched << ext_beg; } // add internal break or continue if necessary // CC_SeqItemBlock *b[ s ]; // for( int i = 0; i < s; ++i ) // b[ i ] = ne->ext[ i ].ptr(); // ne->expr->add_break_and_continue_internal( b ); } return beg; }