BTW here's a code fragment showing roughly the tree-locking algorithm I described at one point. If everyone uses this for things that can change tree topology, they'll get locks from root to affected-subtree ... in parallel, not colliding.
If task #1 locks a subtree, then task #2 wants to lock a non-overlapping subtree, they can work concurrently and start in either order. If task #3 locked a subtree of what task #1 locked, then either (a) #1 doesn't care about that subtree, and won't get deeper locks (it won't every block getting them), or (b) it does case, but it'll block getting the lock until #3 finishes with it. If task #4 locked a tree that's a superset of what #1 locked, then #1 won't get the lock until #4 finishes. And if the subtree being locked gets removed from the tree before locktree() returns, it's a clean failure.
Or that's the idea. :)
- Dave
/* grab device/port lock, safely freezing its configuration
* return the index of that port (zero based).
*/
static int locktree (struct usb_device *dev)
{
int t;
struct usb_device *hub; if (!dev)
return -ENODEV; /* root hub is always the first lock in the series */
hub = dev->parent;
if (!hub) {
down(&dev->serialize);
return 0;
} /* on the path from root to us, lock everything from
* top down, dropping parent locks when not needed
*/
t = locktree (hub);
if (t < 0)
return t;
for (t = 0; t < hub->maxchild; t++) {
if (hub->children[t] == dev) {
/* when everyone grabs locks top->bottom,
* non-overlapping work may be concurrent
*/
down(&dev->serialize);
up(&hub->serialize);
return t;
}
}
up(&hub->serialize);
return -ENODEV;
}-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE. http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
