宁波有哪些宾馆转让:The difference between device

来源:百度文库 编辑:偶看新闻 时间:2024/05/04 06:34:50

The difference between device_info and private_data

As we mentioned in Section 5, the fusd_file_info structure has two seemingly similar fields, both ofwhich can be used by drivers to store their own data: device_info and private_data. However, there is an importantdifference between them:

  • private_data is stored per file descriptor. If 20processes open a FUSD device (or, one process opens a FUSD device 20times), each of those 20 file descriptors will have their own copy ofprivate_data associated with them. This field is thereforeuseful to drivers that need to differentiate multiple requests to asingle device that might be serviced in parallel. (Note that mostUNIX variants, including Linux, do allow multiple processes to share asingle file descriptor--specifically, if a process opens afile, then forks. In this case, processes will also share asingle copy of private_data.)

    The first time a FUSD driver sees private_data (in the open callback), it is guaranteed to be NULL. Any changes to it by adriver callback will only affect the state associated with that singlefile descriptor.

  • device_info is kept per device. That is, allclients of a device share a single copy of device_info.Unlike private_data, which is always initialized to NULL, device_info is always initialized to whatever value the driverpassed to fusd_register as described in the previous section.If a callback changes the copy of device_info in the fusd_file_info structure, this has no effect; device_infocan only be set at registration time, with fusd_register.

In short, device_info is used to differentiate devices.private_data is used to differentiate users of thosedevices.

Program 5, drums2.c, illustrates the difference betweendevice_info and private_data. Like the originaldrums.c, it creates a bunch of devices in /dev/drums/, each ofwhich ``plays'' a different sound. However, it also does somethingnew: keeps track of how many times each device has been opened. Everyread to any drum gives you the name of its sound as well as yourunique ``user number''. And, instead of returning just a single line(as drums.c did), it will keep generating more ``sound'' every time aread() system call arrives.



The trick is that we want to keep users separate from each other. Forexample, user one might type:

% more /dev/drums/bamYou are user 1 to hear a drum go 'bam'!You are user 1 to hear a drum go 'bam'!You are user 1 to hear a drum go 'bam'!...

Meanwhile, another user in a different shell might type the samecommand at the same time, and get different results:

% more /dev/drums/bamYou are user 2 to hear a drum go 'bam'!You are user 2 to hear a drum go 'bam'!You are user 2 to hear a drum go 'bam'!...

The idea is that no matter how long those two users go on readingtheir devices, the driver always generates a message that is specificto that user. The two users' data are not intermingled.

To implement this, Program 5 introduces a new drum_info structure (lines 1-4), which keeps track of both thedrum's name, and the number of time each drum device has been opened.An instance of this structure, drums, is initialized on lines4-8. Note that the call to fusd_register (line 45) now passesa pointer to a drum_info structure. (This drum_info *pointer is shared by every instance of a client that opens aparticular type of drum.)

Each time a drum device is opened, its drum_info structure isretrieved from device_info (line 15). Then, on line 18, thenum_users field is incremented and the new user number isstored in fusd_file_info's private_data field. Toreiterate our earlier point: device_info containsinformation global to all users of a device, while private_datahas information specific to a particular user of the device.

It's also worthwhile to note that when we increment num_userson line 18, a simple num_users++ is correct. If this was adriver inside the kernel, we'd have to use something like atomic_inc() because a plain i++ is not atomic. Such anon-atomic statement will result in a race condition on SMP platforms,if an interrupt handler also touches num_users, or in somefuture Linux kernel that is preemptive. Since this FUSD driver isjust a plain, single-threaded user-space application, good old ++ still works.