summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-12-01 15:31:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-12-01 15:31:22 +0000
commit0e4d4dd89170d47a662f1cd0de1b4f3a5dbc1f2d (patch)
tree324429d9476664c8dff6d315daaf98b4a011c48d /libc
parent4298bd6e30f8841250f4912fdbda7a4a2230b561 (diff)
optimize signal mask ops. comment out "impossible" errors
text data bss dec hex filename - 1179 13 2 1194 4aa libc/misc/syslog/syslog.o + 1165 13 2 1180 49c libc/misc/syslog/syslog.o - 435 4 0 439 1b7 libc/pwd_grp/lckpwdf.o + 393 4 0 397 18d libc/pwd_grp/lckpwdf.o - 38 0 0 38 26 libc/signal/sigandset.o + 32 0 0 32 20 libc/signal/sigandset.o - 63 0 0 63 3f libc/signal/sigblock.o + 56 0 0 56 38 libc/signal/sigblock.o - 22 0 0 22 16 libc/signal/sigempty.o + 20 0 0 20 14 libc/signal/sigempty.o - 25 0 0 25 19 libc/signal/sigfillset.o + 20 0 0 20 14 libc/signal/sigfillset.o - 34 0 0 34 22 libc/signal/sigisempty.o + 16 0 0 16 10 libc/signal/sigisempty.o - 38 0 0 38 26 libc/signal/sigorset.o + 32 0 0 32 20 libc/signal/sigorset.o - 119 0 0 119 77 libc/signal/sigpause.o + 113 0 0 113 71 libc/signal/sigpause.o - 215 0 0 215 d7 libc/signal/sigset.o + 211 0 0 211 d3 libc/signal/sigset.o - 63 0 0 63 3f libc/signal/sigsetmask.o + 56 0 0 56 38 libc/signal/sigsetmask.o - 194 0 1 195 c3 libc/stdlib/abort.o + 183 0 1 184 b8 libc/stdlib/abort.o - 323 0 0 323 143 libc/unistd/sleep.o + 309 0 0 309 135 libc/unistd/sleep.o
Diffstat (limited to 'libc')
-rw-r--r--libc/misc/syslog/syslog.c7
-rw-r--r--libc/pwd_grp/lckpwdf.c42
-rw-r--r--libc/signal/sigempty.c4
-rw-r--r--libc/signal/sigfillset.c4
-rw-r--r--libc/signal/sigset-cvt-mask.h4
-rw-r--r--libc/signal/sigwait.c4
-rw-r--r--libc/sysdeps/linux/alpha/sigprocmask.c4
-rw-r--r--libc/sysdeps/linux/common/bits/sigset.h127
-rw-r--r--libc/sysdeps/linux/common/ssp.c4
9 files changed, 127 insertions, 73 deletions
diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c
index ccc71ddec..32fcd1f2b 100644
--- a/libc/misc/syslog/syslog.c
+++ b/libc/misc/syslog/syslog.c
@@ -207,11 +207,11 @@ vsyslog(int pri, const char *fmt, va_list ap)
memset(&action, 0, sizeof(action));
action.sa_handler = closelog_intern;
- sigemptyset(&action.sa_mask); /* TODO: memset already zeroed it out! */
+ /* __sigemptyset(&action.sa_mask); - memset already did it */
/* Only two errors are possible for sigaction:
* EFAULT (bad address of &oldaction) and EINVAL (invalid signo)
* none of which can happen here. */
- /*int sigpipe =*/ sigaction(SIGPIPE, &action, &oldaction);
+ sigaction(SIGPIPE, &action, &oldaction);
saved_errno = errno;
@@ -317,8 +317,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
getout:
__UCLIBC_MUTEX_UNLOCK(mylock);
- /*if (sigpipe == 0)*/
- sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL);
+ sigaction(SIGPIPE, &oldaction, NULL);
}
libc_hidden_def(vsyslog)
diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c
index a9601d45d..41987ca5d 100644
--- a/libc/pwd_grp/lckpwdf.c
+++ b/libc/pwd_grp/lckpwdf.c
@@ -39,11 +39,9 @@
/* libc_hidden_proto(sigemptyset) */
/* libc_hidden_proto(alarm) */
-/* How long to wait for getting the lock before returning with an
- error. */
+/* How long to wait for getting the lock before returning with an error. */
#define TIMEOUT 15 /* sec */
-
/* File descriptor for lock file. */
static int lock_fd = -1;
@@ -51,7 +49,6 @@ static int lock_fd = -1;
#include <bits/uClibc_mutex.h>
__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
-
/* Prototypes for local functions. */
static void noop_handler (int __sig);
@@ -82,33 +79,39 @@ lckpwdf (void)
}
/* Make sure file gets correctly closed when process finished. */
- flags = fcntl (lock_fd, F_GETFD, 0);
+ flags = fcntl (lock_fd, F_GETFD);
+#if 0 /* never fails */
if (flags == -1) {
/* Cannot get file flags. */
close(lock_fd);
lock_fd = -1;
goto DONE;
}
- flags |= FD_CLOEXEC; /* Close on exit. */
+#endif
+ flags |= FD_CLOEXEC;
+#if 1
+ fcntl (lock_fd, F_SETFD, flags);
+#else /* never fails */
if (fcntl (lock_fd, F_SETFD, flags) < 0) {
/* Cannot set new flags. */
close(lock_fd);
lock_fd = -1;
goto DONE;
}
-
+#endif
/* Now we have to get exclusive write access. Since multiple
process could try this we won't stop when it first fails.
Instead we set a timeout for the system call. Once the timer
expires it is likely that there are some problems which cannot be
- resolved by waiting.
+ resolved by waiting. (sa_flags have no SA_RESTART. Thus SIGALRM
+ will EINTR fcntl(F_SETLKW)
It is important that we don't change the signal state. We must
restore the old signal behaviour. */
memset (&new_act, '\0', sizeof (struct sigaction));
new_act.sa_handler = noop_handler;
- sigfillset (&new_act.sa_mask);
- new_act.sa_flags = 0ul;
+ __sigfillset (&new_act.sa_mask);
+ /* new_act.sa_flags = 0; */
/* Install new action handler for alarm and save old. */
if (sigaction (SIGALRM, &new_act, &saved_act) < 0) {
@@ -119,34 +122,35 @@ lckpwdf (void)
}
/* Now make sure the alarm signal is not blocked. */
- sigemptyset (&new_set);
+ __sigemptyset (&new_set);
sigaddset (&new_set, SIGALRM);
+#if 1
+ sigprocmask (SIG_UNBLOCK, &new_set, &saved_set);
+#else /* never fails */
if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0) {
sigaction (SIGALRM, &saved_act, NULL);
close(lock_fd);
lock_fd = -1;
goto DONE;
}
+#endif
/* Start timer. If we cannot get the lock in the specified time we
get a signal. */
alarm (TIMEOUT);
/* Try to get the lock. */
- memset (&fl, '\0', sizeof (struct flock));
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
+ memset (&fl, '\0', sizeof (fl));
+ if (F_WRLCK)
+ fl.l_type = F_WRLCK;
+ if (SEEK_SET)
+ fl.l_whence = SEEK_SET;
result = fcntl (lock_fd, F_SETLKW, &fl);
/* Clear alarm. */
alarm (0);
- /* Restore old set of handled signals. We don't need to know
- about the current one.*/
sigprocmask (SIG_SETMASK, &saved_set, NULL);
-
- /* Restore old action handler for alarm. We don't need to know
- about the current one. */
sigaction (SIGALRM, &saved_act, NULL);
if (result < 0) {
diff --git a/libc/signal/sigempty.c b/libc/signal/sigempty.c
index 96260fb92..56b62bc65 100644
--- a/libc/signal/sigempty.c
+++ b/libc/signal/sigempty.c
@@ -26,13 +26,15 @@
/* libc_hidden_proto(sigemptyset) */
int sigemptyset (sigset_t *set)
{
+#if 0 /* is it really required by standards?! */
if (set == NULL)
{
__set_errno (EINVAL);
return -1;
}
+#endif
- memset (set, 0, sizeof (sigset_t));
+ __sigemptyset (set);
return 0;
}
diff --git a/libc/signal/sigfillset.c b/libc/signal/sigfillset.c
index 2f8fb8138..b0b093032 100644
--- a/libc/signal/sigfillset.c
+++ b/libc/signal/sigfillset.c
@@ -27,13 +27,15 @@
int
sigfillset (sigset_t *set)
{
+#if 0 /* is it really required by standards?! */
if (set == NULL)
{
__set_errno (EINVAL);
return -1;
}
+#endif
- memset (set, 0xff, sizeof (sigset_t));
+ __sigfillset (set);
/* If the implementation uses a cancellation signal don't set the bit. */
#ifdef SIGCANCEL
diff --git a/libc/signal/sigset-cvt-mask.h b/libc/signal/sigset-cvt-mask.h
index 83be40a51..76dd01c7e 100644
--- a/libc/signal/sigset-cvt-mask.h
+++ b/libc/signal/sigset-cvt-mask.h
@@ -22,7 +22,9 @@
static __inline__ void __attribute__ ((unused))
sigset_set_old_mask (sigset_t *set, int mask)
{
- if (_SIGSET_NWORDS > 1)
+ if (_SIGSET_NWORDS == 2) /* typical */
+ set->__val[1] = 0;
+ if (_SIGSET_NWORDS > 2)
memset(set, 0, sizeof(*set));
set->__val[0] = (unsigned int) mask;
}
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c
index 9b2c32079..64a889f7b 100644
--- a/libc/signal/sigwait.c
+++ b/libc/signal/sigwait.c
@@ -56,12 +56,12 @@ int __sigwait (const sigset_t *set, int *sig)
int this;
/* Prepare set. */
- sigfillset (&tmp_mask);
+ __sigfillset (&tmp_mask);
/* Unblock all signals in the SET and register our nice handler. */
action.sa_handler = ignore_signal;
action.sa_flags = 0;
- sigfillset (&action.sa_mask); /* Block all signals for handler. */
+ __sigfillset (&action.sa_mask); /* Block all signals for handler. */
/* Make sure we recognize error conditions by setting WAS_SIG to a
value which does not describe a legal signal number. */
diff --git a/libc/sysdeps/linux/alpha/sigprocmask.c b/libc/sysdeps/linux/alpha/sigprocmask.c
index 5728418b5..e143f61e3 100644
--- a/libc/sysdeps/linux/alpha/sigprocmask.c
+++ b/libc/sysdeps/linux/alpha/sigprocmask.c
@@ -51,7 +51,9 @@ sigprocmask (int how, const sigset_t *set, sigset_t *oset)
if (oset)
{
- if (_SIGSET_NWORDS > 1)
+ if (_SIGSET_NWORDS == 2) /* typical */
+ oset->__val[1] = 0;
+ if (_SIGSET_NWORDS > 2)
memset(oset, 0, sizeof(*oset));
oset->__val[0] = result;
}
diff --git a/libc/sysdeps/linux/common/bits/sigset.h b/libc/sysdeps/linux/common/bits/sigset.h
index 14497671d..964b09178 100644
--- a/libc/sysdeps/linux/common/bits/sigset.h
+++ b/libc/sysdeps/linux/common/bits/sigset.h
@@ -30,10 +30,9 @@ typedef int __sig_atomic_t;
*/
# define _SIGSET_NWORDS (64 / (8 * sizeof (unsigned long int)))
-typedef struct
- {
- unsigned long int __val[_SIGSET_NWORDS];
- } __sigset_t;
+typedef struct {
+ unsigned long int __val[_SIGSET_NWORDS];
+} __sigset_t;
#endif
@@ -59,47 +58,91 @@ typedef struct
/* Return the word index for SIG. */
# define __sigword(sig) ((unsigned)((sig) - 1) / (8 * sizeof (unsigned long int)))
+/* gcc 4.3.1 is not clever enough to optimize for _SIGSET_NWORDS == 1 and 2,
+ * which are about the only values which can be there */
+
# if defined __GNUC__ && __GNUC__ >= 2
# define __sigemptyset(set) \
- (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
- sigset_t *__set = (set); \
- while (--__cnt >= 0) __set->__val[__cnt] = 0; \
- 0; }))
+(__extension__ ({ \
+ sigset_t *__set = (set); \
+ if (_SIGSET_NWORDS <= 2) { \
+ __set->__val[0] = 0; \
+ if (_SIGSET_NWORDS == 2) \
+ __set->__val[1] = 0; \
+ } else { \
+ int __cnt = _SIGSET_NWORDS; \
+ while (--__cnt >= 0) __set->__val[__cnt] = 0; \
+ } \
+ 0; \
+}))
# define __sigfillset(set) \
- (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
- sigset_t *__set = (set); \
- while (--__cnt >= 0) __set->__val[__cnt] = ~0UL; \
- 0; }))
+(__extension__ ({ \
+ sigset_t *__set = (set); \
+ if (_SIGSET_NWORDS <= 2) { \
+ __set->__val[0] = ~0UL; \
+ if (_SIGSET_NWORDS == 2) \
+ __set->__val[1] = ~0UL; \
+ } else { \
+ int __cnt = _SIGSET_NWORDS; \
+ while (--__cnt >= 0) __set->__val[__cnt] = ~0UL; \
+ } \
+ 0; \
+}))
# ifdef __USE_GNU
/* The POSIX does not specify for handling the whole signal set in one
command. This is often wanted and so we define three more functions
here. */
# define __sigisemptyset(set) \
- (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
- const sigset_t *__set = (set); \
- int __ret = __set->__val[--__cnt]; \
- while (!__ret && --__cnt >= 0) \
- __ret = __set->__val[__cnt]; \
- __ret == 0; }))
+(__extension__ ({ \
+ long __ret; \
+ const sigset_t *__set = (set); \
+ if (_SIGSET_NWORDS == 1) { \
+ __ret = __set->__val[0]; \
+ } else if (_SIGSET_NWORDS == 2) { \
+ __ret = __set->__val[0] | __set->__val[1]; \
+ } else { \
+ int __cnt = _SIGSET_NWORDS; \
+ __ret = __set->__val[--__cnt]; \
+ while (!__ret && --__cnt >= 0) \
+ __ret = __set->__val[__cnt]; \
+ } \
+ __ret == 0; \
+}))
# define __sigandset(dest, left, right) \
- (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
- sigset_t *__dest = (dest); \
- const sigset_t *__left = (left); \
- const sigset_t *__right = (right); \
- while (--__cnt >= 0) \
- __dest->__val[__cnt] = (__left->__val[__cnt] \
- & __right->__val[__cnt]); \
- 0; }))
+(__extension__ ({ \
+ sigset_t *__dest = (dest); \
+ const sigset_t *__left = (left); \
+ const sigset_t *__right = (right); \
+ if (_SIGSET_NWORDS <= 2) { \
+ __dest->__val[0] = __left->__val[0] & __right->__val[0];\
+ if (_SIGSET_NWORDS == 2) \
+ __dest->__val[1] = __left->__val[1] & __right->__val[1];\
+ } else { \
+ int __cnt = _SIGSET_NWORDS; \
+ while (--__cnt >= 0) \
+ __dest->__val[__cnt] = (__left->__val[__cnt] \
+ & __right->__val[__cnt]); \
+ } \
+ 0; \
+}))
# define __sigorset(dest, left, right) \
- (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
- sigset_t *__dest = (dest); \
- const sigset_t *__left = (left); \
- const sigset_t *__right = (right); \
- while (--__cnt >= 0) \
- __dest->__val[__cnt] = (__left->__val[__cnt] \
- | __right->__val[__cnt]); \
- 0; }))
+(__extension__ ({ \
+ sigset_t *__dest = (dest); \
+ const sigset_t *__left = (left); \
+ const sigset_t *__right = (right); \
+ if (_SIGSET_NWORDS <= 2) { \
+ __dest->__val[0] = __left->__val[0] | __right->__val[0];\
+ if (_SIGSET_NWORDS == 2) \
+ __dest->__val[1] = __left->__val[1] | __right->__val[1];\
+ } else { \
+ int __cnt = _SIGSET_NWORDS; \
+ while (--__cnt >= 0) \
+ __dest->__val[__cnt] = (__left->__val[__cnt] \
+ | __right->__val[__cnt]); \
+ } \
+ 0; \
+}))
# endif
# endif
@@ -114,14 +157,14 @@ extern int __sigdelset (__sigset_t *, int);
libc_hidden_proto(__sigdelset)
# ifdef __USE_EXTERN_INLINES
-# define __SIGSETFN(NAME, BODY, CONST) \
- _EXTERN_INLINE int \
- NAME (CONST __sigset_t *__set, int __sig) \
- { \
- unsigned long int __mask = __sigmask (__sig); \
- unsigned long int __word = __sigword (__sig); \
- return BODY; \
- }
+# define __SIGSETFN(NAME, BODY, CONST) \
+_EXTERN_INLINE int \
+NAME (CONST __sigset_t *__set, int __sig) \
+{ \
+ unsigned long int __mask = __sigmask (__sig); \
+ unsigned long int __word = __sigword (__sig); \
+ return BODY; \
+}
__SIGSETFN (__sigismember, (__set->__val[__word] & __mask) ? 1 : 0, __const)
__SIGSETFN (__sigaddset, ((__set->__val[__word] |= __mask), 0), )
diff --git a/libc/sysdeps/linux/common/ssp.c b/libc/sysdeps/linux/common/ssp.c
index c244c6220..fadf6077b 100644
--- a/libc/sysdeps/linux/common/ssp.c
+++ b/libc/sysdeps/linux/common/ssp.c
@@ -51,14 +51,14 @@ static void block_signals(void)
struct sigaction sa;
sigset_t mask;
- sigfillset(&mask);
+ __sigfillset(&mask);
sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */
sigprocmask(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */
/* Make the default handler associated with the signal handler */
memset(&sa, 0, sizeof(sa));
- sigfillset(&sa.sa_mask); /* Block all signals */
+ __sigfillset(&sa.sa_mask); /* Block all signals */
/* sa.sa_flags = 0; - memset did it */
if (SIG_DFL) /* if it's constant zero, it's already done */
sa.sa_handler = SIG_DFL;