Discussion:
sigset_t type
(too old to reply)
grid
2005-06-08 07:35:44 UTC
Permalink
Hi,
I was going through the signal sources in the kernel for the type for
sigset_t.Earlier implementations had nearly 31 signals so a int which is
32 bits could well represent all the signals with each bit corresponding
to each signal.

But the below sources form the Linux kernel (i386) uses an array as below :

#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)

typedef unsigned long old_sigset_t; /* at least 32 bits */

typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;

Could not we use a datatype like long long to for each of the signals.

And how does this sigfillset() function initialize the sigset_t type as
shown below:

static inline void sigfillset(sigset_t *set)
{
switch (_NSIG_WORDS) {
default:
memset(set, -1, sizeof(sigset_t));
break;
case 2: set->sig[1] = -1;
case 1: set->sig[0] = -1;
break;
}
}


TIA
Nils O. Selåsdal
2005-06-08 07:52:30 UTC
Permalink
Post by grid
Hi,
I was going through the signal sources in the kernel for the type for
sigset_t.Earlier implementations had nearly 31 signals so a int which is
32 bits could well represent all the signals with each bit corresponding
to each signal.
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
Could not we use a datatype like long long to for each of the signals.
Yes.

That would be less flexible as it would be hard to extend though.
A prerequisite is also that the compiler supports long long as well.
Perhaps gcc didn't at the time.
Post by grid
And how does this sigfillset() function initialize the sigset_t type as
It does exactly as the code says..
(What is there to explain ?)
Post by grid
static inline void sigfillset(sigset_t *set)
{
switch (_NSIG_WORDS) {
memset(set, -1, sizeof(sigset_t));
break;
case 2: set->sig[1] = -1;
case 1: set->sig[0] = -1;
break;
}
}
TIA
l***@gmx.net
2005-06-08 08:07:20 UTC
Permalink
Salut Grid,
Post by grid
I was going through the signal sources in the kernel for the type for
sigset_t.Earlier implementations had nearly 31 signals so a int which is
32 bits could well represent all the signals with each bit corresponding
to each signal.
I am not a connoiseur of the Linux Kernel source, but I think I have
some ideas why they implemented the sigset_t that way.
Post by grid
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
Could not we use a datatype like long long to for each of the signals.
The current implementation has 64 signals ( but actually, only 62 are
disponible to the user. The two signals 32 and 33 are reserved for
LinuxThreads/NPTL ).

So yes, we could code the mask on a long long. But what happen if we
need to increase the number of signals? For instance, to 96? long long
won't do it anymore...

In the present code, you just change _NSIG_BPW and that's it.
Post by grid
And how does this sigfillset() function initialize the sigset_t type as
static inline void sigfillset(sigset_t *set)
{
switch (_NSIG_WORDS) {
memset(set, -1, sizeof(sigset_t));
break;
case 2: set->sig[1] = -1;
case 1: set->sig[0] = -1;
break;
}
}
I guess, it is an optimization. Setting to -1 means setting all the
bits of the 32 bits words. When _NSIG_WORDS is more than 2 (that is, we
are dealing with more than 64 signals), all 32 bits words of the table
are set to 0xffffffff.

In the case where the mask can be coded with a table of one (resp. two)
32 bits words, we directly set sig[0] ( and resp. sig[1] ). This avoids
the overhead of calling memset().


HTH,
Loic.

Loading...