This is the mail archive of the ecos-discuss@sourceware.cygnus.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

eCos FP support suggestions.


Hello,

Here are my thoughts about floating point support implementation for
eCos. Your objections, comments and suggestions are welcome.

Support for three different configurations of FP context handling are
required:

1. All tasks are floating point.
2. Some tasks are floating point, immediate FP context switch.
3. Some tasks are floating point, lazy (deferred) FP context switch.

The following HAL macroses will be affected:
  HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ )
  HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_)
  HAL_THREAD_LOAD_CONTEXT(_tspptr_)

Additional arguments are required to pass information about FP
context. We may either add parameters to existing macroses and let
non-FP HALs ignore them, or define parallel set of macroses that will
contain the parameters and, if they are defined by HAL and FP support
is enabled, will be used by kernel instead of non-FP-aware macroses.
Don't know which way is better. The latter way is used below.

To illustrate the idea, HAL_THREAD_SWITCH_CONTEXT_EXTENDED macro is
described as well as changes to 'Cyg_Scheduler::unlock_inner()'.


HAL_THREAD_SWITCH_CONTEXT_EXTENDED arguments (current task is called
t1, next task is called t2):

CYG_ADDRESS t1_sp_ptr
  The same as in HAL_THREAD_SWITCH_CONTEXT.

CYG_ADDRESS t2_sp_ptr
  The same as in HAL_THREAD_SWITCH_CONTEXT.

cyg_bool    t1_is_fp
  'true' if space for FP is required in context of t1. Defines how
  much to move '*t1_sp_ptr'. Allows HAL to don't allocate space for FP
  for non-FP tasks. HAL is allowed to ignore this and always allocate
  space for FP in the context.

cyg_bool    t2_is_fp
  'true' if space for FP was allocated in context of t2. Defines how
  much to move '*t2_sp_ptr'. If HAL doesn't allocate space for FP for
  non-FP tasks, this provides information that allows HAL to don't
  store FP attribute in the task context. If HAL allocates space for
  FP even for non-FP tasks, this argument is useless.

CYG_ADDRESS save_fp_sp_ptr
  Address of stack pointer to save FP context. Could be equal to
  't1_sp_ptr' (!). Zero if we don't need to save FP context.

cyg_bool    load_fp
  If FP context should be actually loaded from t2.



Changes to 'Cyg_Scheduler::unlock_inner()'.

'fp_context_owner_thread' is pointer to the thread that owns current
FP context. It is static member of 'Cyg_Scheduler_Base' class
initialized to zero. It will be then set by 'Cyg_Scheduler::start()'
if first task to execute is FP, or later by first switch to task that
has FP context.

'is_fp' is boolean attribute - non-static const member of
'Cyg_HardwareThread' class. I'd suggest to initialize it by adding
another constructor to both 'Cyg_HardwareThread' and 'Cyg_Thread'
classes where 'is_fp' argument is inserted before 'stack_size' and
'stack_base'.

Current code from 'unlock_inner()':

  // Switch contexts
  HAL_THREAD_SWITCH_CONTEXT( &current->stack_ptr, &next->stack_ptr );

should be changed to:

  // Switch contexts

#if !defined(HAL_THREAD_SWITCH_CONTEXT_EXTENDED)

  HAL_THREAD_SWITCH_CONTEXT( &current->stack_ptr, &next->stack_ptr );

#else  // defined(HAL_THREAD_SWITCH_CONTEXT_EXTENDED)

#  if !defined(CYG_KERNEL_FP_SUPPORT)

  HAL_THREAD_SWITCH_CONTEXT_EXTENDED(
    &current->stack_ptr,
    &next->stack_ptr,
    false,
    false,
    0,
    false);

#  elif defined(CYGIMP_FP_LAZY_CONTEXT_SWITCH)

  Cyg_Thread* fp_context_owner = fp_context_owner_thread;
  cyg_bool load_fp = next->is_fp && next != fp_context_owner;
  if(load_fp)
    fp_context_owner_thread = next;
  HAL_THREAD_SWITCH_CONTEXT_EXTENDED(
    &current->stack_ptr,
    &next->stack_ptr,
    current->is_fp,
    next->is_fp,
    (fp_context_owner && next->is_fp) ? &fp_context_owner->stack_ptr : 0,
    load_fp);

#  elif defined(CYGIMP_FP_ALL_TASKS)

  HAL_THREAD_SWITCH_CONTEXT_EXTENDED(
    &current->stack_ptr,
    &next->stack_ptr,
    true,
    true,
    &current->stack_ptr,
    true);

#  else

  HAL_THREAD_SWITCH_CONTEXT_EXTENDED(
    &current->stack_ptr,
    &next->stack_ptr,
    current->is_fp,
    next->is_fp,
    current->is_fp ? &current->stack_ptr : 0,
    next->is_fp);

#  endif

#endif // defined(HAL_THREAD_SWITCH_CONTEXT_EXTENDED)


Well, seems to be enough for the first time.

Regards,
Sergei.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]