Hello, we are trying to describe the rtems formatting style using clang-format ( http://clang.llvm.org/docs/ClangFormatStyleOptions.html). To see whether it can be done, we used ratemonperiod.c as an example and tried to set up a .clang-format file to describe the formatting. In the mail added the .clang configuration file and a ratemonperiodWKCustom_Commented.c, which is ratemonperiod.c with the configuration in .clang-format applied.
With the .clang-format file in the folder with the source files, it can be tried out with: clang-format -style=file original_source.c > formatted_source.c There are several problems in ratemonperiodWKCustom_Commented.c using clang-format: 1. In line 30-32, we can see that the "*" of the pointers are not aligned to the right. This is not supported yet it clang-format (see https://stackoverflow.com/questions/38392889/clang-format-align-asterisk-of-pointer-declaration-with-variable-name ). 2. In line 32, the ")" at the end of the parameter list needs to be in a new row, but this doesn't seem to be supported in clang-format. 4. In line 44: If the function call is split into multiple rows, the ");" should always be in a new row. 5. Also in line 44, when a function call is split into multiple rows. The parameters can all be in separate rows, but clang-format always puts all the parameters in one row when they fit. 6. In line 80, clang-format does not stick to the column limit of 80. The line is 81 long. I have tried to configure a strict 80 column rule with the penalties, but there are still lines with 81 characters. 7. In line 127, I can't turn off the break after the function return type in this case. 8. In line 127, the parameter is not in a new line, but in rtems we would need every parameter of a function definition to always be in seperate line. Line 182, 279 have the same problem. 8. Lines 323, 330, 335, 348: It should be possible to specify that the functions arguments can be in seperate rows. We have also asked the clang community how much effort it would take to implement these points. Best, Mikail
.clang-format
Description: Binary data
/** * @file * * @brief Rate Monotonic Support * @ingroup ClassicRateMon */ /* * COPYRIGHT (c) 1989-2010. * On-Line Applications Research Corporation (OAR). * Copyright (c) 2016 embedded brains GmbH. * COPYRIGHT (c) 2016 Kuan-Hsun Chen. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #if HAVE_CONFIG_H #include "config.h" #endif #include <rtems/rtems/ratemonimpl.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/todimpl.h> bool _Rate_monotonic_Get_status( const Rate_monotonic_Control *the_period, Timestamp_Control *wall_since_last_period, Timestamp_Control *cpu_since_last_period ) { Timestamp_Control uptime; Thread_Control *owning_thread = the_period->owner; Timestamp_Control used; /* * Determine elapsed wall time since period initiated. */ _TOD_Get_uptime( &uptime ); _Timestamp_Subtract( &the_period->time_period_initiated, &uptime, wall_since_last_period ); /* * Determine cpu usage since period initiated. */ _Thread_Get_CPU_time_used( owning_thread, &used ); /* * The cpu usage info was reset while executing. Can't * determine a status. */ if ( _Timestamp_Less_than( &used, &the_period->cpu_usage_period_initiated ) ) return false; /* used = current cpu usage - cpu usage at start of period */ _Timestamp_Subtract( &the_period->cpu_usage_period_initiated, &used, cpu_since_last_period ); return true; } static void _Rate_monotonic_Release_postponed_job( Rate_monotonic_Control *the_period, Thread_Control *owner, rtems_interval next_length, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; --the_period->postponed_jobs; _Scheduler_Release_job( owner, &the_period->Priority, the_period->latest_deadline, &queue_context ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_direct( cpu_self ); } static void _Rate_monotonic_Release_job( Rate_monotonic_Control *the_period, Thread_Control *owner, rtems_interval next_length, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; uint64_t deadline; cpu_self = _Thread_Dispatch_disable_critical( lock_context ); deadline = _Watchdog_Per_CPU_insert_ticks( &the_period->Timer, cpu_self, next_length ); _Scheduler_Release_job( owner, &the_period->Priority, deadline, &queue_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); } void _Rate_monotonic_Restart( Rate_monotonic_Control *the_period, Thread_Control *owner, ISR_lock_Context *lock_context ) { /* * Set the starting point and the CPU time used for the statistics. */ _TOD_Get_uptime( &the_period->time_period_initiated ); _Thread_Get_CPU_time_used( owner, &the_period->cpu_usage_period_initiated ); _Rate_monotonic_Release_job( the_period, owner, the_period->next_length, lock_context ); } static void _Rate_monotonic_Update_statistics( Rate_monotonic_Control *the_period ) { Timestamp_Control executed; Timestamp_Control since_last_period; Rate_monotonic_Statistics *stats; bool valid_status; /* * Assume we are only called in states where it is appropriate * to update the statistics. This should only be RATE_MONOTONIC_ACTIVE * and RATE_MONOTONIC_EXPIRED. */ /* * Update the counts. */ stats = &the_period->Statistics; stats->count++; if ( the_period->state == RATE_MONOTONIC_EXPIRED ) stats->missed_count++; /* * Grab status for time statistics. */ valid_status = _Rate_monotonic_Get_status( the_period, &since_last_period, &executed ); if (!valid_status) return; /* * Update CPU time */ _Timestamp_Add_to( &stats->total_cpu_time, &executed ); if ( _Timestamp_Less_than( &executed, &stats->min_cpu_time ) ) stats->min_cpu_time = executed; if ( _Timestamp_Greater_than( &executed, &stats->max_cpu_time ) ) stats->max_cpu_time = executed; /* * Update Wall time */ _Timestamp_Add_to( &stats->total_wall_time, &since_last_period ); if ( _Timestamp_Less_than( &since_last_period, &stats->min_wall_time ) ) stats->min_wall_time = since_last_period; if ( _Timestamp_Greater_than( &since_last_period, &stats->max_wall_time ) ) stats->max_wall_time = since_last_period; } static rtems_status_code _Rate_monotonic_Get_status_for_state( rtems_rate_monotonic_period_states state ) { switch ( state ) { case RATE_MONOTONIC_INACTIVE: return RTEMS_NOT_DEFINED; case RATE_MONOTONIC_EXPIRED: return RTEMS_TIMEOUT; default: _Assert( state == RATE_MONOTONIC_ACTIVE ); return RTEMS_SUCCESSFUL; } } static rtems_status_code _Rate_monotonic_Activate( Rate_monotonic_Control *the_period, rtems_interval length, Thread_Control *executing, ISR_lock_Context *lock_context ) { the_period->postponed_jobs = 0; the_period->state = RATE_MONOTONIC_ACTIVE; the_period->next_length = length; _Rate_monotonic_Restart( the_period, executing, lock_context ); return RTEMS_SUCCESSFUL; } static rtems_status_code _Rate_monotonic_Block_while_active( Rate_monotonic_Control *the_period, rtems_interval length, Thread_Control *executing, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; bool success; /* * Update statistics from the concluding period. */ _Rate_monotonic_Update_statistics( the_period ); /* * This tells the _Rate_monotonic_Timeout that this task is * in the process of blocking on the period and that we * may be changing the length of the next period. */ the_period->next_length = length; executing->Wait.return_argument = the_period; _Thread_Wait_flags_set( executing, RATE_MONOTONIC_INTEND_TO_BLOCK ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Set_state( executing, STATES_WAITING_FOR_PERIOD ); success = _Thread_Wait_flags_try_change_acquire( executing, RATE_MONOTONIC_INTEND_TO_BLOCK, RATE_MONOTONIC_BLOCKED ); if ( !success ) { _Assert( _Thread_Wait_flags_get( executing ) == RATE_MONOTONIC_READY_AGAIN ); _Thread_Unblock( executing ); } _Thread_Dispatch_direct( cpu_self ); return RTEMS_SUCCESSFUL; } /* * There are two possible cases: one is that the previous deadline is missed, * The other is that the number of postponed jobs is not 0, but the current * deadline is still not expired, i.e., state = RATE_MONOTONIC_ACTIVE. */ static rtems_status_code _Rate_monotonic_Block_while_expired( Rate_monotonic_Control *the_period, rtems_interval length, Thread_Control *executing, ISR_lock_Context *lock_context ) { /* * No matter the just finished jobs in time or not, * they are actually missing their deadlines already. */ the_period->state = RATE_MONOTONIC_EXPIRED; /* * Update statistics from the concluding period */ _Rate_monotonic_Update_statistics( the_period ); the_period->state = RATE_MONOTONIC_ACTIVE; the_period->next_length = length; _Rate_monotonic_Release_postponed_job( the_period, executing, length, lock_context ); return RTEMS_TIMEOUT; } rtems_status_code rtems_rate_monotonic_period( rtems_id id, rtems_interval length ) { Rate_monotonic_Control *the_period; ISR_lock_Context lock_context; Thread_Control *executing; rtems_status_code status; rtems_rate_monotonic_period_states state; the_period = _Rate_monotonic_Get( id, &lock_context ); if ( the_period == NULL ) { return RTEMS_INVALID_ID; } executing = _Thread_Executing; if ( executing != the_period->owner ) { _ISR_lock_ISR_enable( &lock_context ); return RTEMS_NOT_OWNER_OF_RESOURCE; } _Rate_monotonic_Acquire_critical( the_period, &lock_context ); state = the_period->state; if ( length == RTEMS_PERIOD_STATUS ) { status = _Rate_monotonic_Get_status_for_state( state ); _Rate_monotonic_Release( the_period, &lock_context ); } else { switch ( state ) { case RATE_MONOTONIC_ACTIVE: if( the_period->postponed_jobs > 0 ){ /* * If the number of postponed jobs is not 0, it means the * previous postponed instance is finished without exceeding * the current period deadline. * * Do nothing on the watchdog deadline assignment but release the * next remaining postponed job. */ status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); }else{ /* * Normal case that no postponed jobs and no expiration, so wait for * the period and update the deadline of watchdog accordingly. */ status = _Rate_monotonic_Block_while_active( the_period, length, executing, &lock_context ); } break; case RATE_MONOTONIC_INACTIVE: status = _Rate_monotonic_Activate( the_period, length, executing, &lock_context ); break; default: /* * As now this period was already TIMEOUT, there must be at least one * postponed job recorded by the watchdog. The one which exceeded * the previous deadlines was just finished. * * Maybe there is more than one job postponed due to the preemption or * the previous finished job. */ _Assert( state == RATE_MONOTONIC_EXPIRED ); status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); break; } } return status; }
/** * @file * * @brief Rate Monotonic Support * @ingroup ClassicRateMon */ /* * COPYRIGHT (c) 1989-2010. * On-Line Applications Research Corporation (OAR). * Copyright (c) 2016 embedded brains GmbH. * COPYRIGHT (c) 2016 Kuan-Hsun Chen. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #if HAVE_CONFIG_H #include "config.h" #endif #include <rtems/rtems/ratemonimpl.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/todimpl.h> // TODO: the ")" at the end of the parameter list should be in a new line // but it can't be modeled // TODO: pointer alignement to the right is not supported (yet) bool _Rate_monotonic_Get_status( const Rate_monotonic_Control* the_period, Timestamp_Control* wall_since_last_period, Timestamp_Control* cpu_since_last_period ) { Timestamp_Control uptime; Thread_Control* owning_thread = the_period->owner; Timestamp_Control used; /* * Determine elapsed wall time since period initiated. */ _TOD_Get_uptime( &uptime ); // TODO: Here the ");" cannot be placed in the next row by clang-format _Timestamp_Subtract( &the_period->time_period_initiated, &uptime, wall_since_last_period ); /* * Determine cpu usage since period initiated. */ _Thread_Get_CPU_time_used( owning_thread, &used ); /* * The cpu usage info was reset while executing. Can't * determine a status. */ if ( _Timestamp_Less_than( &used, &the_period->cpu_usage_period_initiated ) ) return false; /* used = current cpu usage - cpu usage at start of period */ // TODO: when a function call is split into multiple rows, // the function parameters should each be in a new row // can't be done with clang-format _Timestamp_Subtract( &the_period->cpu_usage_period_initiated, &used, cpu_since_last_period ); return true; } static void _Rate_monotonic_Release_postponed_job( Rate_monotonic_Control* the_period, Thread_Control* owner, rtems_interval next_length, ISR_lock_Context* lock_context ) { Per_CPU_Control* cpu_self; Thread_queue_Context queue_context; --the_period->postponed_jobs; // TODO: clang-format does not always stick to the 80 column limit _Scheduler_Release_job( owner, &the_period->Priority, the_period->latest_deadline, &queue_context ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_direct( cpu_self ); } static void _Rate_monotonic_Release_job( Rate_monotonic_Control* the_period, Thread_Control* owner, rtems_interval next_length, ISR_lock_Context* lock_context ) { Per_CPU_Control* cpu_self; Thread_queue_Context queue_context; uint64_t deadline; cpu_self = _Thread_Dispatch_disable_critical( lock_context ); deadline = _Watchdog_Per_CPU_insert_ticks( &the_period->Timer, cpu_self, next_length ); _Scheduler_Release_job( owner, &the_period->Priority, deadline, &queue_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); } void _Rate_monotonic_Restart( Rate_monotonic_Control* the_period, Thread_Control* owner, ISR_lock_Context* lock_context ) { /* * Set the starting point and the CPU time used for the statistics. */ _TOD_Get_uptime( &the_period->time_period_initiated ); _Thread_Get_CPU_time_used( owner, &the_period->cpu_usage_period_initiated ); _Rate_monotonic_Release_job( the_period, owner, the_period->next_length, lock_context ); } // TODO: can't turn off the break after function return type in this case // although it is set to None in the .clang-format // function parameters do not begin in a new row here static void _Rate_monotonic_Update_statistics( Rate_monotonic_Control* the_period ) { Timestamp_Control executed; Timestamp_Control since_last_period; Rate_monotonic_Statistics* stats; bool valid_status; /* * Assume we are only called in states where it is appropriate * to update the statistics. This should only be RATE_MONOTONIC_ACTIVE * and RATE_MONOTONIC_EXPIRED. */ /* * Update the counts. */ stats = &the_period->Statistics; stats->count++; if ( the_period->state == RATE_MONOTONIC_EXPIRED ) stats->missed_count++; /* * Grab status for time statistics. */ valid_status = _Rate_monotonic_Get_status( the_period, &since_last_period, &executed ); if ( !valid_status ) return; /* * Update CPU time */ _Timestamp_Add_to( &stats->total_cpu_time, &executed ); if ( _Timestamp_Less_than( &executed, &stats->min_cpu_time ) ) stats->min_cpu_time = executed; if ( _Timestamp_Greater_than( &executed, &stats->max_cpu_time ) ) stats->max_cpu_time = executed; /* * Update Wall time */ _Timestamp_Add_to( &stats->total_wall_time, &since_last_period ); if ( _Timestamp_Less_than( &since_last_period, &stats->min_wall_time ) ) stats->min_wall_time = since_last_period; if ( _Timestamp_Greater_than( &since_last_period, &stats->max_wall_time ) ) stats->max_wall_time = since_last_period; } // same as above static rtems_status_code _Rate_monotonic_Get_status_for_state( rtems_rate_monotonic_period_states state ) { switch ( state ) { case RATE_MONOTONIC_INACTIVE: return RTEMS_NOT_DEFINED; case RATE_MONOTONIC_EXPIRED: return RTEMS_TIMEOUT; default: _Assert( state == RATE_MONOTONIC_ACTIVE ); return RTEMS_SUCCESSFUL; } } static rtems_status_code _Rate_monotonic_Activate( Rate_monotonic_Control* the_period, rtems_interval length, Thread_Control* executing, ISR_lock_Context* lock_context ) { the_period->postponed_jobs = 0; the_period->state = RATE_MONOTONIC_ACTIVE; the_period->next_length = length; _Rate_monotonic_Restart( the_period, executing, lock_context ); return RTEMS_SUCCESSFUL; } static rtems_status_code _Rate_monotonic_Block_while_active( Rate_monotonic_Control* the_period, rtems_interval length, Thread_Control* executing, ISR_lock_Context* lock_context ) { Per_CPU_Control* cpu_self; bool success; /* * Update statistics from the concluding period. */ _Rate_monotonic_Update_statistics( the_period ); /* * This tells the _Rate_monotonic_Timeout that this task is * in the process of blocking on the period and that we * may be changing the length of the next period. */ the_period->next_length = length; executing->Wait.return_argument = the_period; _Thread_Wait_flags_set( executing, RATE_MONOTONIC_INTEND_TO_BLOCK ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Set_state( executing, STATES_WAITING_FOR_PERIOD ); success = _Thread_Wait_flags_try_change_acquire( executing, RATE_MONOTONIC_INTEND_TO_BLOCK, RATE_MONOTONIC_BLOCKED ); if ( !success ) { _Assert( _Thread_Wait_flags_get( executing ) == RATE_MONOTONIC_READY_AGAIN ); _Thread_Unblock( executing ); } _Thread_Dispatch_direct( cpu_self ); return RTEMS_SUCCESSFUL; } /* * There are two possible cases: one is that the previous deadline is missed, * The other is that the number of postponed jobs is not 0, but the current * deadline is still not expired, i.e., state = RATE_MONOTONIC_ACTIVE. */ static rtems_status_code _Rate_monotonic_Block_while_expired( Rate_monotonic_Control* the_period, rtems_interval length, Thread_Control* executing, ISR_lock_Context* lock_context ) { /* * No matter the just finished jobs in time or not, * they are actually missing their deadlines already. */ the_period->state = RATE_MONOTONIC_EXPIRED; /* * Update statistics from the concluding period */ _Rate_monotonic_Update_statistics( the_period ); the_period->state = RATE_MONOTONIC_ACTIVE; the_period->next_length = length; _Rate_monotonic_Release_postponed_job( the_period, executing, length, lock_context ); return RTEMS_TIMEOUT; } // TODO:same as above rtems_status_code rtems_rate_monotonic_period( rtems_id id, rtems_interval length ) { Rate_monotonic_Control* the_period; ISR_lock_Context lock_context; Thread_Control* executing; rtems_status_code status; rtems_rate_monotonic_period_states state; the_period = _Rate_monotonic_Get( id, &lock_context ); if ( the_period == NULL ) { return RTEMS_INVALID_ID; } executing = _Thread_Executing; if ( executing != the_period->owner ) { _ISR_lock_ISR_enable( &lock_context ); return RTEMS_NOT_OWNER_OF_RESOURCE; } _Rate_monotonic_Acquire_critical( the_period, &lock_context ); state = the_period->state; if ( length == RTEMS_PERIOD_STATUS ) { status = _Rate_monotonic_Get_status_for_state( state ); _Rate_monotonic_Release( the_period, &lock_context ); } else { switch ( state ) { case RATE_MONOTONIC_ACTIVE: if ( the_period->postponed_jobs > 0 ) { /* * If the number of postponed jobs is not 0, it means the * previous postponed instance is finished without exceeding * the current period deadline. * * Do nothing on the watchdog deadline assignment but release the * next remaining postponed job. */ //TODO: the following arguments should all be in a seperate row // but they get put in one, when columnlimit is 80 status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); } else { /* * Normal case that no postponed jobs and no expiration, so wait for * the period and update the deadline of watchdog accordingly. */ status = _Rate_monotonic_Block_while_active( the_period, length, executing, &lock_context ); } break; case RATE_MONOTONIC_INACTIVE: status = _Rate_monotonic_Activate( the_period, length, executing, &lock_context ); break; default: /* * As now this period was already TIMEOUT, there must be at least one * postponed job recorded by the watchdog. The one which exceeded * the previous deadlines was just finished. * * Maybe there is more than one job postponed due to the preemption or * the previous finished job. */ _Assert( state == RATE_MONOTONIC_EXPIRED ); status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); break; } } return status; }
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel