Ejemplo n.º 1
0
// Big function that handles the array preamble. We first read and
// expand the preamble, then loop over all characters, then check
// that it ends correctly. If main_fct is false, we are in a multicolumn.
// In this case, the array preamble should specify only material
// for one cell. We read the content C of the cell, and push back
// the {UCV} list (where U and V the optional <u> and <v> parts.
// braces are added because cells are assumed to be typeset in a group.
void NewArray::run(Xid ID, bool main_fct)
{
  id = ID;
  if(!main_fct) {
    Istring x = P->nT_next_arg();
    id.add_attribute(the_names[np_cols], x);
  }
  preamble = P->mac_arg();
  token_ns::expand_star(preamble);
  token_ns::expand_nct(preamble);
  if(main_fct) AI = &P->the_stack.new_array_info(id);
  u_list.clear();
  v_list.clear();
  ac_cell_no = 0;
  last_ch_class = chc_start;
  first_bar = true;
  bool seen = false;
  cur_h_pos = np_c_center;
  if(P->tracing_commands()) the_log << "array preamble parse: ";
  for(;;) {
    if(preamble.empty()) break;
    if(ac_next()) continue;
    test_pach();
    if(P->tracing_commands()) the_log << dump_slot();
    switch(ch_class) {
    case chc_cell:
      if(main_fct) ac_maybe_finish();  // finish previous
      else ac_maybe_finish_multi(seen);
      attribs.push_back(np_halign,cur_h_pos,false);  // set attributes
      cur_h_pos = np_c_center; // add a default
      current_list.clear();
      break;
    case chc_bar: 
      if(ch_num==chn_c) {
	if(last_ch_class==chc_start)
	  attribs.push_back(np_leftborder,np_true);
	else if(last_ch_class==chc_bar) {}
	else 
	  attribs.push_back(np_rightborder,np_true,false);
      }
      current_list.clear();
      break;
    case chc_v:  // got a <v>list, add it
      if(!have_token_list)
	v_list.push_front(current_token);
      else 
	v_list.splice(v_list.begin(),current_list);
      break;
    case chc_u: // got a <u>list, add it.
      if(!have_token_list)
	u_list.push_front(current_token);
      else
	u_list.splice(u_list.begin(),current_list);
      break;
    case chc_start: // preamble empty
      break;
    case chc_inter:
      current_list.clear();
      break;
    case chc_pre_bar:
      if(last_ch_class==chc_cell) break;
      else if(last_ch_class==chc_bar) break;
      else if(last_ch_class==chc_v) break;
      else if(last_ch_class==chc_u)
	P->parse_error("illegal ! or @");
      break;
    case chc_pre_inter:
      if(last_ch_class==chc_u)
	P->parse_error("illegal ! or @");
      break;
    case chc_pre_v:
      if(last_ch_class ==chc_cell) break;
      if(last_ch_class==chc_v) break;
      P->parse_error("unexpected less-than sign");
      ch_class = chc_pre_bar;
      break;
    case chc_pre_u:
    case chc_pre_cell:
      if(main_fct) ac_maybe_finish(); else ac_maybe_finish_multi(seen);
      break;
    }
    last_ch_class = ch_class;
  }
  switch(last_ch_class) {
  case chc_cell:
  case chc_bar:
  case chc_v:
  case chc_u:
  case chc_start:
  case chc_inter: break;
  default: {
    static Buffer B;
    B.reset();
    B << "Array preamble: argument missing for " << char_for_error;
    P->parse_error(B.c_str());
  }
  }
  if(P->tracing_commands()) the_log << "\n";
  if(main_fct) {
    ac_maybe_finish();
    return;
  }  else ac_maybe_finish_multi(seen);
  // Case of \multicolumn, 
  id.add_attribute(attribs);
  attribs.reset();
  TokenList cell = P->mac_arg();
  cell.splice(cell.begin(),u_list);
  cell.splice(cell.end(),v_list);
  u_list.clear();
  v_list.clear();
  P->brace_me(cell);
  P->back_input(cell);

}
Ejemplo n.º 2
0
//-----------------------------------------
// eCos HW scheduling thread
//-----------------------------------------
void reconos_hw_scheduler(cyg_addrword_t data) {

    cyg_bool_t retval;
    rthread_attr_t *t_r;            // thread to reconfigure
    rthread_attr_t *t_y;            // yielding thread
    reconos_slot_t *s_f;            // free slot
    reconos_bitstream_t *t_r_bit;   // bitstream for t_r in s_f
#ifdef UPBFUN_RECONOS_CHECK_HWTHREAD_SIGNATURE
    uint32 signature;               // hardware thread signature
    volatile int z;                 // counter to delay DCR access
#endif

#ifdef UPBDBG_RECONOS_DEBUG
    diag_printf("hw_sched: created\n");
#endif

    // loop forever
    for (;;) {  
        // wait for signal (reschedule request)
        retval = cyg_semaphore_wait( &reconos_hwsched_semaphore );
        CYG_ASSERT(retval, "cyg_semaphore_wait returned false");

#ifdef UPBDBG_RECONOS_DEBUG
        diag_printf("hw_sched: wakeup\n");
#endif

        // lock scheduling mutex
        if (!cyg_mutex_lock(&reconos_hwsched_mutex)) {
            CYG_FAIL("mutex lock failed, aborting thread\n");
        } else {

#ifdef UPBDBG_RECONOS_DEBUG
            {
                int i;
                for (i = 0; i < NUM_OSIFS; i++) {
                    dump_slot( &reconos_slots[i] );
                }
            }
#endif
            // find thread t_r that wants to run (FIXME: no priorities or
            // queuing!)
            t_r = reconos_hwthread_list;
            while ( t_r != NULL && ((t_r->flags & RTHREAD_ATTR_RECONFIGURE) == 0) ) {
                t_r = t_r->next;
            }
            if (t_r == NULL) {
                // no hw threads to reconfigure, nothing to do
#ifdef UPBDBG_RECONOS_DEBUG
                diag_printf("hw_sched: no threads to reconfigure\n");
#endif
                // clear all yield requests!
                while (num_global_yield_requests) {
                    pop_yield_request();
                }
            } else {
#ifdef UPBDBG_RECONOS_DEBUG
                diag_printf("hw_sched: found thread @ 0x%08X to reconfigure\n", (uint32)t_r);
#endif

                CYG_ASSERT( t_r->flags & RTHREAD_ATTR_IS_DYNAMIC, "trying to load a static thread" );

                // find free slot s_f
                s_f = find_free_slot( t_r );

                if ( s_f == NULL ) { // no free slot
                    // try to find thread that yields in a slot we have a
                    // bitstream for
#ifdef UPBDBG_RECONOS_DEBUG
                    diag_printf("hw_sched: no free slots\n");
#endif
                    t_y = reconos_hwthread_list;
                    while ( t_y != NULL &&
                            ( ( (t_y->flags & RTHREAD_ATTR_YIELDS ) == 0) || ( get_bit_for_slot( t_r, t_y->slot ) == NULL ) )
                          ) {
                        t_y = t_y->next;
                    }
                    if (t_y == NULL) {  // no yielding thread
#ifdef UPBDBG_RECONOS_DEBUG
                        diag_printf("hw_sched: no yielding threads, sending yield requests to slots\n");
#endif
                        // ask all slots to yield 
                        // FIXME: this will also ask slots that t_r possibly
                        // doesn't have a bitstream for
                        push_yield_request();
                    } else { // if found
                        CYG_ASSERT( t_y->flags & RTHREAD_ATTR_IS_DYNAMIC, "trying to replace a static thread" );
                        CYG_ASSERT( t_y->slot, "trying to replace a not-resident thread" );
#ifdef UPBDBG_RECONOS_DEBUG
                        diag_printf("hw_sched: found yielding thread @ 0x%08X in slot %d\n", (uint32)t_y, t_y->slot->num);
#endif
                        // use t_y's slot as s_f
                        s_f = t_y->slot;
                        // clear yield flag of t_y
                        t_y->flags = t_y->flags & ~RTHREAD_ATTR_YIELDS;
                        // remove t_y from s_f
                        s_f->thread = NULL;
                        t_y->slot = NULL;
                        s_f->state = FREE;
                    }
                } else {
#ifdef UPBDBG_RECONOS_DEBUG
                    diag_printf("hw_sched: found free slot %d\n", s_f->num);
#endif
                }

                if ( s_f != NULL) {     // if we found a free slot
                    // one way or the other

                    // get bitstream for t_r in s_f
                    t_r_bit = get_bit_for_slot( t_r, s_f );

                    CYG_ASSERT( t_r_bit, "no bitstream" );
                    CYG_ASSERT( s_f->state == FREE || s_f->thread->flags & RTHREAD_ATTR_IS_DYNAMIC, "slot not free or present thread is static" );

#ifdef UPBDBG_RECONOS_DEBUG
                    diag_printf("hw_sched: configuring thread @ 0x%08X into slot %d using bitstream '%s'\n", (uint32)t_r, s_f->num, t_r_bit->filename);
#endif

                    // configure t_r into s_f
                    // NOTE: we don't need to synchronize this with the
                    // slot's mutex, since the slot is yielding and will
                    // not perform any hardware operations while the
                    // scheduling mutex is locked
                    // disable bus macros (just in case)
                    osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_DISABLE);
#ifdef UPBHWR_VIRTEX4_ICAP
                    icap_load( t_r_bit->data, t_r_bit->size );
#endif
#ifdef UPBFUN_RECONOS_ECAP_NET
					ecap_load( t_r_bit );
#endif
#ifdef UPBFUN_RECONOS_CHECK_HWTHREAD_SIGNATURE
					// reset thread, enable busmacros, reset again (to 
					// retrieve signature), read signature, and disable
					// busmacros
					osif_reset( s_f );
                    cyg_thread_delay(1);
					osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_ENABLE);
                    // cyg_thread_delay(1);
					osif_reset( s_f );
                    cyg_thread_delay(1);
					osif_read_hwthread_signature(s_f, &signature);
                    // cyg_thread_delay(1);
                    // osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_DISABLE);
                    // cyg_thread_delay(1);
#ifdef UPBDBG_RECONOS_DEBUG
					diag_printf("hw_sched: read signature: 0x%08X, expected: 0x%08X.\n", signature, t_r->circuit->signature);
#endif
					// check whether the signatures match
					CYG_ASSERT(signature == t_r->circuit->signature, "hwthread signatures don't match");
#endif
                    // assign thread to slot and set slot state to READY
                    s_f->thread = t_r;
                    t_r->slot = s_f;
                    s_f->state = READY;
                    // clear t_r's RECONFIGURE bit
                    t_r->flags = t_r->flags & ~RTHREAD_ATTR_RECONFIGURE;
                    // wake any threads waiting for a scheduling change
                    cyg_cond_broadcast( &reconos_hwsched_condvar );
                    // clear one yield request
                    pop_yield_request();
                }
            }

#ifdef UPBDBG_RECONOS_DEBUG
            diag_printf("hw_sched: done\n");
#endif
            // unlock scheduling mutex
            cyg_mutex_unlock(&reconos_hwsched_mutex);

        }   // if (mutex_lock)

    } // for (;;)
}