Re: Problem using queued spinlocks on single cpu comp uter

Actually there is a well-known C++ design pattern called Flyweight that
is tailor-made for this very purpose (i.e. a Word processor where you’d
find it convenient to work with each character via a CChar class, but
don’t want to create an instance for every character in the document).

Jamey Kirby wrote:

Pure insanity!

Jamey Kirby, Windows DDK MVP
StorageCraft Inc.
xxxxx@storagecraft.com
http://www.storagecraft.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Moreira, Alberto
Sent: Thursday, September 25, 2003 11:55 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: Problem using queued spinlocks on single cpu comp uter

It all depends on what you want to do with the bits and with the uchars as
you define them. If the functionality is complicated enough, yes, it may
make sense to encapsulate things that way. It all depends on what you want
to accomplish.

Furthermore, we have bit functionality in C, we have “unsigned char”, and so
on - why do we need BIT, UCHAR ? Waste of time, no ? Or maybe there’s some
additional effects people want to achieve that can’t be done the old way ?

And you know, who needs structs if you can make do with arrays ? Long live
Fortran II. But hey, at some point we might want to retire that Model T.

Alberto.

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Thursday, September 25, 2003 1:44 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: Problem using queued spinlocks on single cpu comp
uter

Oh, I got it… Let’s encapsulate the actual bits… That should make for
some very manageable and robust driver code; NOT!

class BIT
{
};

class UCHAR : BIT
{
};

class WCHAR : UCHAR
{
};

Oooo… Ahhhh… Thing are becoming more clear and more robust; don’t you
agree? Heck, my grand mother could maintain this code.

Jamey Kirby, Windows DDK MVP
StorageCraft Inc.
xxxxx@storagecraft.com
http://www.storagecraft.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Moreira, Alberto
Sent: Thursday, September 25, 2003 10:17 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: Problem using queued spinlocks on single cpu comp uter

In object oriented design, resources are no longer pure data, they’re now
objects ! The use of an object is internal to that object, only interfaces
are published. Otherwise you must give up having a healthy encapsulation,
just look at that “friend” statement you need in the class. Another problem
I see with this design, as I told Max, is that the queue handle is now
attached to the Acquirer and not to the Lock: if two different pieces of
code try to acquire the same spinlock, you will end up with two queues,
which defeats the purpose of using a queued lock.

Alberto.

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Thursday, September 25, 2003 12:46 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: Problem using queued spinlocks on single cpu comp
uter

>That’s an interesting statement, Chuck, what advantages do you see in
>separating these two ?

The conceptual separation of a resource from its use. We can use the
current discussion as the basis for an example:

class CSpinLockAcquire;

class CSpinLock
{
public:
CSpinLock() { KeInitializeSpinLock(&SpinLock); }
private:
Lock(KLOCK_QUEUE_HANDLE & h) {
KeAcquireInStackQueuedSpinLock(&SpinLock, &h); }
Unlock(KLOCK_QUEUE_HANDLE & h) {
KeReleaseInStackQueuedSpinLock(&SpinLock, &h); }
KSPIN_LOCK SpinLock;
friend class CSpinLockAcquire;
};

class CSpinLockAcquire
{
public:
CSpinLockAcquire(CSpinLock & s) : SpinLock(s) {
s.Lock(Handle); }
~CSpinLockAcquire() { s.Unlock(Handle); }
private:
CSpinLock & SpinLock;
KLOCK_QUEUE_HANDLE Handle;
};

This conceptual separation is useful any time you have a resource which
must be acquired/released, locked/unlocked, etc. There are a few
concrete benefits:

  1. Exception safety. Since locking and unlocking is handled by the
    constructor/destructor of CSpinLockAcquire, you can never have a
    situation of a lock not being matched with a corresponding unlock, even
    in the presence of exceptions.

  2. Human error and maintainability. For the same reason, it’s
    impossible for the programmer to “forget” to unlock a resource.
    Granted, if you forget to release a spin lock, you’re likely to know
    pretty quickly, but it still wastes time and effort diagnosing the
    problem. The same general principle applies to other types of resources
    (e.g. not necessarily spin locks) where usage may be more involved
    and/or subtle and hence more prone to difficult-to-diagnose “forgetting
    to unlock” errors.

  3. Acquisition/release data is separate from resource data. This is
    good for two reasons:

a. Memory storage for the resource object itself may be precious.
Consider the “single class” implementation where the spin lock and its
queue handle are stored together. The spin lock has to go into shared
memory which is accessible to all those who might potentially acquire
it. There’s no reason for the queue handle to be shared, since it’s
only used by one acquirer at a time. So separating them is beneficial
when use of shared memory has performance implications.

b. Resource acquisition data sometimes must be separate from the
resource, especially when it’s possible for more that one entity to
acquire a given resource at the same time. This is less useful in this
case, when only one processor can acquire a spinlock at any given time.
(Though it’s still a bit aesthetically displeasing to me, when you think
about two different processors calling KeAcquireInStackQueuedSpinLock()
with a pointer to the same queue handle; “luckily” only one of them will
succeed in acquiring the spin lock, so there will never be more than one
user of the queue handle… but still makes me shudder.) But there are
situations in which this is necessary. For example, a resource which
has both read and write acquires, where multiple readers are allowed but
only a single writer (with no readers) is allowed. Since you can have
multiple readers, obviously it won’t do to put the acquisition handle
(or whatever relevant acquisition-related information) in the resource
object itself.

Chuck


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Nick Ryan (MVP for DDK)