Linux clock processing mechanism (2)

Source: Internet
Author: User
Article Title: Linux clock processing mechanism (2 ). Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.

3.3 add or delete a Software Clock

After learning about the data organization of the Software Clock, let's take a look at how to add and delete a Software Clock.

3.3.1 add Software Clock

To add a software clock in the Linux kernel, you must first allocate a variable of the struct timer_list type and then call the add_timer () function () add the software clock to the base of the CPU that calls the add_timer function. Add_timer is a layer package for function _ mod_timer. The Code of function _ mod_timer () is shown in listing 3-2:

Listing 3-2 _ mod_timer Function

Int _ mod_timer (struct timer_list * timer, unsigned long expires) {struct tvec_base * base, * new_base; unsigned long flags; int ret = 0 ;...... Base = lock_timer_base (timer, & flags); if (timer_pending (timer) {detach_timer (timer, 0); ret = 1;} new_base = _ get_cpu_var (tvec_bases ); if (base! = New_base) {if (likely (base-> running_timer! = Timer) {/* See the comment in lock_timer_base () */timer_set_base (timer, NULL); spin_unlock (& base-> lock); base = new_base; spin_lock (& base-> lock); timer_set_base (timer, base) ;}} timer-> expires = expires; internal_add_timer (base, timer); spin_unlock_irqrestore (& base-> lock, flags); return ret ;}

Code explanation:

Note: detaching a Software Clock means removing the software clock from the base where the Software Clock is located. This is also the meaning of detaching a Software Clock later.

Obtain the synchronization lock on the base where the Software Clock is located (the spin lock in the struct tvec_base variable), return the base of the Software Clock, and save it in the base variable.

If the Software Clock is in pending state (in base, ready for execution), uninstall the Software Clock

Obtain the base pointer on the CPU (type: struct tvec_base *) and save it in new_base.

If the base and new_base are different, that is, the Software Clock is migrated (from one CPU to another ), if the processing function of the software clock is not running on the CPU before the migration, set the base of the Software Clock to NULL first, then, set the base of the Software Clock to new_base. Otherwise, go to Step 5.

Set the Software Clock expiration time

Call the internal_add_timer function to add the software clock to the base of the Software Clock (the base of the current CPU)

Release lock

It is necessary to explain in detail how the software clock is added to the base of the Software Clock (the tv1 ~ Tv5), because this is the basis of Software Clock processing. Let's look at the implementation of the internal_add_timer function, as shown in Figure 3-3.

Listing 3-3 internal_add_timer Functions

Static void Merge (struct tvec_base * base, struct timer_list * timer) {unsigned long expires = timer-> expires; unsigned long idx = expires-base-> struct; struct list_head * vec; if (idx <TVR_SIZE) {int I = expires & TVR_MASK; vec = base-> tv1.vec + I;} else if (idx <1 <(TVR_BITS + TVN_BITS )) {int I = (expires> TVR_BITS) & TVN_MASK; vec = base-> tv2.vec + I;} else if (idx <1 <(TVR_BITS + 2 * TVN_BITS )) {int I = (expires >>( TVR_BITS + TVN_BITS) & TVN_MASK; vec = base-> tv3.vec + I ;} else if (idx <1 <(TVR_BITS + 3 * TVN_BITS) {int I = (expires> (TVR_BITS + 2 * TVN_BITS) & TVN_MASK; vec = base-> tv4.vec + I;} else if (signed long) idx <0) {vec = base-> tv1.vec + (base-> timer_jiffies & TVR_MASK );} else {int I; if (idx> 0 xfffffful) {idx = 0 xfffffful; expires = idx + base-> timer_jiffies ;} I = (expires> (TVR_BITS + 3 * TVN_BITS) & TVN_MASK; vec = base-> tv5.vec + I;} list_add_tail (& timer-> entry, vec );}

Code explanation:

Calculate the difference between the expiration time of the Software Clock and the timer_jiffies (the expiration time of the Software Clock currently being processed), and store it as an index in the idx variable.

Determine the interval of idx, in

[0,] or (, 0) (the Software Clock has expired), it will be added to tv1

[,], To be added to tv2

[,], To be added to tv3

[,], To be added to tv4

[,), It will be added to tv5, but the actual maximum value is 0 xffffffffUL

Calculate the specific position to be added (in which linked list, that is, tv1 ~ Which sub-linked list of tv5, refer to-1)

Finally, add it to the corresponding linked list.

From this function, we can know that the kernel adds the software clock to the base where the Software Clock is located according to the relative value of the Software Clock expiration time (relative to the value of timer_jiffies.

3.3.2 delete a Software Clock

The kernel can call the del_timer function to delete the Software Clock. The del_timer code is shown in listing 3-4.

Listing 3-4 del_timer Functions

Int del_timer (struct timer_list * timer) {struct tvec_base * base; unsigned long flags; int ret = 0 ;...... If (timer_pending (timer) {base = lock_timer_base (timer, & flags); if (timer_pending (timer) {detach_timer (timer, 1); ret = 1 ;} spin_unlock_irqrestore (& base-> lock, flags);} return ret ;}

Code explanation:

Checks whether the software clock is in pending state (in base, ready to run). If not, the function returns

If it is in pending status, the lock is obtained.

Check again whether the software clock is in pending status (the Software Clock may be uninstalled). If not, release the lock and then the function returns

If it is still pending, it will be detached, and then the lock will be released. The function returns

In the SMP system, you need to use the del_timer_sync function to delete the Software Clock. Before explaining the del_timer_sync function, let's take a look at the implementation of the try_to_del_timer_sync function (this function is used by the del_timer_sync function). The Code is shown in listing 3-5.

Listing 3-5 try_to_del_timer_sync Functions

Int try_to_del_timer_sync (struct timer_list * timer) {struct tvec_base * base; unsigned long flags; int ret =-1; base = lock_timer_base (timer, & flags ); if (base-> running_timer = timer) goto out; ret = 0; if (timer_pending (timer) {detach_timer (timer, 1); ret = 1;} out: spin_unlock_irqrestore (& base-> lock, flags); return ret ;}

This function checks whether the currently running software clock is the Software Clock. If yes, the function returns-1, indicating that the software clock cannot be deleted currently; if the software clock is not in pending status, if not, the function returns 0, indicating that the software clock has been uninstalled. If the software clock is in pending status, the function returns 1, indicates that the software clock is successfully uninstalled.

[1] [2] [3] Next page

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.