In a multi-task environment, it is inevitable to use locks to prevent competition. The Locks can be implemented through mutex or direct switch interruption. You need to lock key code or data before accessing it, And then unlock it after it is used up. As a good habit, the locking granularity should be kept small and possible.
For the code in figure 1, the timer_init () function locks the _ handler data structure before initializing it. After initializing the data structure, the unlock operation is performed on Row 3. This code is functional, but it does not make the lock granularity as small as possible. If you carefully read this code, the reader will find that the 124 line will check whether the mark _ variable has been set as the value defined by TIMER_MARK. If it has been set, the error will be handled, the logic is that an initialized timer cannot be initialized again. If you continue, you can see that the value setting operation is performed on the mark _ variable in the 144 line.
Example. c
00096: typedef struct tag_timer
00097 :{
00098: dll_node_t node _;
00106 :...
00107 :} timer_instance_t, * timer_handler_t;
00108:
00109: // guard for initialized timer
00110: static const csize_t TIMER_MARK = 0x20091026;
00111:
00112: error_t timer_init (timer_handler_t _ handler, msecond_t _ duration,
00113: expiration_cb_t _ cb, const char * _ name)
00114 :{
00122 :...
00123: timer_lock ();
00124: if (TIMER_MARK = _ handler-> mark _){
00125: // if it has been initialized then failing it
00126: timer_unlock ();
00127: return ERROR_T (ERROR_TIMER_INIT_INITIALIZED );
00128 :}
00129:
00130: // convert to TICK_DURATION_IN_MSEC unit
00131: _ handler-> ticks _ = _ duration/TICK_DURATION_IN_MSEC;
00132: if (0 ==_handler-> ticks _){
00133: _ handler-> ticks _ ++;
00134 :}
00135: _ handler-> cb _ = _ cb;
00136: _ handler-> state _ = TIMER_INITIALIZED;
00137: dll_node_init (& _ handler-> node _);
00138: if (0 = _ name ){
00139: _ handler-> name _ [0] = 0;
00140 :}
00141: else {
00142: strncpy (_ handler-> name _, _ name, sizeof (_ handler-> name _));
00143 :}
00144: _ handler-> mark _ = TIMER_MARK;
00145: timer_unlock ();
00146:
00147: return 0;
00148:} Figure 1
How can we reduce the lock granularity? In fact, as long as the 114 ~ The first line is moved up, as shown in Code 2 after the change. The length is 115 ~ 130 rows can minimize the lock time and avoid competition issues.
Example. c
00112: error_t timer_init (timer_handler_t _ handler, msecond_t _ duration,
00113: expiration_cb_t _ cb, const char * _ name)
00114 :{
00122 :...
00123: timer_lock ();
00124: if (TIMER_MARK = _ handler-> mark _){
00125: // if it has been initialized then failing it
00126: timer_unlock ();
00127: return ERROR_T (ERROR_TIMER_INIT_INITIALIZED );
00128 :}
00129: _ handler-> mark _ = TIMER_MARK;
00130: timer_unlock ();
00122 :...
00148:} Figure 2
Why should we minimize the lock granularity? The implementation of a single function in timer_init () may not show its advantages, but do not forget that a module usually has multiple functions, and multiple functions are likely and likely to exist) locks are required. When a module is called by multiple tasks, its locking granularity will affect the real-time performance of the entire system. If the locking granularity is minimized, it will help improve the system's real-time performance and performance.
The timer_init () function shows the granularity of the lock time dimension, in addition to the granularity of the resource dimension. If A module requires two independent resources, A and B, and some functions in this module only need resources A and some functions only need resources B, of course, some functions need to use both A and B resources. When both A and B need to use locks for protection, two different locks instead of the same should be designed for A and B, that is to say, "dedicated lock" is used to reduce the lock granularity. Obviously, the purpose of reducing the granularity of the resource dimension is to reduce the granularity of the time dimension.
This article from "to Jane Li cloud" blog, please be sure to keep this source http://yunli.blog.51cto.com/831344/273752