Added silc_likely and silc_unlikely GCC branch prediction macros.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 15 Dec 2006 15:23:42 +0000 (15:23 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 15 Dec 2006 15:23:42 +0000 (15:23 +0000)
Added various branc prediction optimizations.

13 files changed:
lib/silcutil/silcbuffer.h
lib/silcutil/silcbuffmt.c
lib/silcutil/silcdlist.h
lib/silcutil/silcfsm.c
lib/silcutil/silcmemory.c
lib/silcutil/silcschedule.c
lib/silcutil/silcschedule.h
lib/silcutil/silcschedule_i.h
lib/silcutil/silcsocketstream.c
lib/silcutil/silcstack.c
lib/silcutil/silctypes.h
lib/silcutil/tests/test_silcfsm.c
lib/silcutil/unix/silcunixschedule.c

index c3148cb34d1533d48d372b710395e3999728348f..90bc3be574611fa2896ca3d2ac751455d57c6d01 100644 (file)
@@ -241,13 +241,13 @@ SilcBuffer silc_buffer_alloc(SilcUInt32 len)
 
   /* Allocate new SilcBuffer */
   sb = (SilcBuffer)silc_calloc(1, sizeof(*sb));
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
 
-  if (len) {
+  if (silc_likely(len)) {
     /* Allocate the actual data area */
     sb->head = (unsigned char *)silc_calloc(len, sizeof(*sb->head));
-    if (!sb->head)
+    if (silc_unlikely(!sb->head))
       return NULL;
 
     /* Set pointers to the new buffer */
@@ -411,7 +411,7 @@ unsigned char *silc_buffer_pull(SilcBuffer sb, SilcUInt32 len)
 #if defined(SILC_DEBUG)
   SILC_ASSERT(len <= silc_buffer_len(sb));
 #else
-  if (len > silc_buffer_len(sb))
+  if (silc_unlikely(len > silc_buffer_len(sb)))
     return NULL;
 #endif
   sb->data += len;
@@ -455,7 +455,7 @@ unsigned char *silc_buffer_push(SilcBuffer sb, SilcUInt32 len)
 #if defined(SILC_DEBUG)
   SILC_ASSERT((sb->data - len) >= sb->head);
 #else
-  if ((sb->data - len) < sb->head)
+  if (silc_unlikely((sb->data - len) < sb->head))
     return NULL;
 #endif
   sb->data -= len;
@@ -499,7 +499,7 @@ unsigned char *silc_buffer_pull_tail(SilcBuffer sb, SilcUInt32 len)
 #if defined(SILC_DEBUG)
   SILC_ASSERT(len <= silc_buffer_taillen(sb));
 #else
-  if (len > silc_buffer_taillen(sb))
+  if (silc_unlikely(len > silc_buffer_taillen(sb)))
     return NULL;
 #endif
   sb->tail += len;
@@ -543,7 +543,7 @@ unsigned char *silc_buffer_push_tail(SilcBuffer sb, SilcUInt32 len)
 #if defined(SILC_DEBUG)
   SILC_ASSERT((sb->tail - len) >= sb->data);
 #else
-  if ((sb->tail - len) < sb->data)
+  if (silc_unlikely((sb->tail - len) < sb->data))
     return NULL;
 #endif
   sb->tail -= len;
@@ -584,7 +584,7 @@ unsigned char *silc_buffer_put_head(SilcBuffer sb,
 #if defined(SILC_DEBUG)
   SILC_ASSERT(len <= silc_buffer_headlen(sb));
 #else
-  if (len > silc_buffer_headlen(sb))
+  if (silc_unlikely(len > silc_buffer_headlen(sb)))
     return NULL;
 #endif
   return (unsigned char *)memcpy(sb->head, data, len);
@@ -624,7 +624,7 @@ unsigned char *silc_buffer_put(SilcBuffer sb,
 #if defined(SILC_DEBUG)
   SILC_ASSERT(len <= silc_buffer_len(sb));
 #else
-  if (len > silc_buffer_len(sb))
+  if (silc_unlikely(len > silc_buffer_len(sb)))
     return NULL;
 #endif
   return (unsigned char *)memcpy(sb->data, data, len);
@@ -664,7 +664,7 @@ unsigned char *silc_buffer_put_tail(SilcBuffer sb,
 #if defined(SILC_DEBUG)
   SILC_ASSERT(len <= silc_buffer_taillen(sb));
 #else
-  if (len > silc_buffer_taillen(sb))
+  if (silc_unlikely(len > silc_buffer_taillen(sb)))
     return NULL;
 #endif
   return (unsigned char *)memcpy(sb->tail, data, len);
@@ -689,7 +689,7 @@ static inline
 SilcBuffer silc_buffer_alloc_size(SilcUInt32 len)
 {
   SilcBuffer sb = silc_buffer_alloc(len);
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
   silc_buffer_pull_tail(sb, len);
   return sb;
@@ -800,7 +800,7 @@ SilcBuffer silc_buffer_copy(SilcBuffer sb)
   SilcBuffer sb_new;
 
   sb_new = silc_buffer_alloc_size(silc_buffer_len(sb));
-  if (!sb_new)
+  if (silc_unlikely(!sb_new))
     return NULL;
   silc_buffer_put(sb_new, sb->data, silc_buffer_len(sb));
 
@@ -828,7 +828,7 @@ SilcBuffer silc_buffer_clone(SilcBuffer sb)
   SilcBuffer sb_new;
 
   sb_new = silc_buffer_alloc_size(silc_buffer_truelen(sb));
-  if (!sb_new)
+  if (silc_unlikely(!sb_new))
     return NULL;
   silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb));
   sb_new->data = sb_new->head + silc_buffer_headlen(sb);
@@ -862,13 +862,13 @@ SilcBuffer silc_buffer_realloc(SilcBuffer sb, SilcUInt32 newsize)
   if (!sb)
     return silc_buffer_alloc(newsize);
 
-  if (newsize <= silc_buffer_truelen(sb))
+  if (silc_unlikely(newsize <= silc_buffer_truelen(sb)))
     return sb;
 
   hlen = silc_buffer_headlen(sb);
   dlen = silc_buffer_len(sb);
   h = (unsigned char *)silc_realloc(sb->head, newsize);
-  if (!h)
+  if (silc_unlikely(!h))
     return NULL;
   sb->head = h;
   sb->data = sb->head + hlen;
@@ -897,7 +897,7 @@ static inline
 SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize)
 {
   sb = silc_buffer_realloc(sb, newsize);
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
   silc_buffer_pull_tail(sb, silc_buffer_taillen(sb));
   return sb;
@@ -927,9 +927,9 @@ SilcBool silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size)
 {
   if (size > silc_buffer_len(sb)) {
     if (size > silc_buffer_taillen(sb) + silc_buffer_len(sb))
-      if (!silc_buffer_realloc(sb, silc_buffer_truelen(sb) +
-                              (size - silc_buffer_taillen(sb) -
-                               silc_buffer_len(sb))))
+      if (silc_unlikely(!silc_buffer_realloc(sb, silc_buffer_truelen(sb) +
+                                            (size - silc_buffer_taillen(sb) -
+                                             silc_buffer_len(sb)))))
        return FALSE;
     silc_buffer_pull_tail(sb, size - silc_buffer_len(sb));
   }
@@ -965,12 +965,12 @@ SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len)
 
   /* Allocate new SilcBuffer */
   sb = (SilcBuffer)silc_scalloc(stack, 1, sizeof(*sb));
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
 
   /* Allocate the actual data area */
   sb->head = (unsigned char *)silc_smalloc_ua(stack, len);
-  if (!sb->head)
+  if (silc_unlikely(!sb->head))
     return NULL;
 
   /* Set pointers to the new buffer */
@@ -1003,7 +1003,7 @@ static inline
 SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len)
 {
   SilcBuffer sb = silc_buffer_salloc(stack, len);
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
   silc_buffer_pull_tail(sb, len);
   return sb;
@@ -1052,7 +1052,7 @@ SilcBuffer silc_buffer_srealloc(SilcStack stack,
     /* Do slow and stack wasting realloc.  The old sb->head is lost and
        is freed eventually. */
     h = silc_smalloc_ua(stack, newsize);
-    if (!h)
+    if (silc_unlikely(!h))
       return NULL;
     memcpy(h, sb->head, silc_buffer_truelen(sb));
   }
@@ -1089,7 +1089,7 @@ SilcBuffer silc_buffer_srealloc_size(SilcStack stack,
                                     SilcBuffer sb, SilcUInt32 newsize)
 {
   sb = silc_buffer_srealloc(stack, sb, newsize);
-  if (!sb)
+  if (silc_unlikely(!sb))
     return NULL;
   silc_buffer_pull_tail(sb, silc_buffer_taillen(sb));
   return sb;
@@ -1123,9 +1123,10 @@ SilcBool silc_buffer_senlarge(SilcStack stack, SilcBuffer sb, SilcUInt32 size)
 {
   if (size > silc_buffer_len(sb)) {
     if (size > silc_buffer_taillen(sb) + silc_buffer_len(sb))
-      if (!silc_buffer_srealloc(stack, sb, silc_buffer_truelen(sb) +
-                               (size - silc_buffer_taillen(sb) -
-                                silc_buffer_len(sb))))
+      if (silc_unlikely(!silc_buffer_srealloc(stack, sb,
+                                             silc_buffer_truelen(sb) +
+                                             (size - silc_buffer_taillen(sb) -
+                                              silc_buffer_len(sb)))))
        return FALSE;
     silc_buffer_pull_tail(sb, size - silc_buffer_len(sb));
   }
@@ -1156,7 +1157,7 @@ SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb)
   SilcBuffer sb_new;
 
   sb_new = silc_buffer_salloc_size(stack, silc_buffer_len(sb));
-  if (!sb_new)
+  if (silc_unlikely(!sb_new))
     return NULL;
   silc_buffer_put(sb_new, sb->data, silc_buffer_len(sb));
 
@@ -1187,7 +1188,7 @@ SilcBuffer silc_buffer_sclone(SilcStack stack, SilcBuffer sb)
   SilcBuffer sb_new;
 
   sb_new = silc_buffer_salloc_size(stack, silc_buffer_truelen(sb));
-  if (!sb_new)
+  if (silc_unlikely(!sb_new))
     return NULL;
   silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb));
   sb_new->data = sb_new->head + silc_buffer_headlen(sb);
index b17e5253d09d1de3c578ee62b9d3e2e27edc4407..562af7d86501524808c3c596e11645fa77b412cc 100644 (file)
 
 /* Check that buffer has enough room to format data in it, if not
    allocate more. */
-#define FORMAT_HAS_SPACE(s, b, req)            \
-do {                                           \
-  if (!silc_buffer_senlarge(s, b, req))                \
-    goto fail;                                 \
-  flen += req;                                 \
+#define FORMAT_HAS_SPACE(s, b, req)                    \
+do {                                                   \
+  if (silc_unlikely(!silc_buffer_senlarge(s, b, req))) \
+    goto fail;                                         \
+  flen += req;                                         \
 } while(0)
 
 /* Check that there is data to be unformatted */
 #define UNFORMAT_HAS_SPACE(b, req)             \
 do {                                           \
-  if (req > silc_buffer_len(b))                        \
+  if (silc_unlikely(req > silc_buffer_len(b))) \
     goto fail;                                 \
-  if ((req + 1) <= 0)                          \
+  if (silc_unlikely((req + 1) <= 0))           \
     goto fail;                                 \
 } while(0)
 
@@ -350,7 +350,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        unsigned char **x = va_arg(ap, unsigned char **);
        SilcUInt32 len2 = va_arg(ap, SilcUInt32);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (len2 && x)
+       if (silc_likely(len2 && x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -361,7 +361,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        unsigned char **x = va_arg(ap, unsigned char **);
        SilcUInt32 len2 = va_arg(ap, SilcUInt32);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (len2 && x) {
+       if (silc_likely(len2 && x)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -372,7 +372,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        unsigned char *x = va_arg(ap, unsigned char *);
        UNFORMAT_HAS_SPACE(src, 1);
-       if (x)
+       if (silc_likely(x))
          *x = src->data[0];
        silc_buffer_pull(src, 1);
        break;
@@ -381,7 +381,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt16 *x = va_arg(ap, SilcUInt16 *);
        UNFORMAT_HAS_SPACE(src, 2);
-       if (x)
+       if (silc_likely(x))
          SILC_GET16_MSB(*x, src->data);
        silc_buffer_pull(src, 2);
        break;
@@ -390,7 +390,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt32 *x = va_arg(ap, SilcUInt32 *);
        UNFORMAT_HAS_SPACE(src, 4);
-       if (x)
+       if (silc_likely(x))
          SILC_GET32_MSB(*x, src->data);
        silc_buffer_pull(src, 4);
        break;
@@ -399,7 +399,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt64 *x = va_arg(ap, SilcUInt64 *);
        UNFORMAT_HAS_SPACE(src, sizeof(SilcUInt64));
-       if (x)
+       if (silc_likely(x))
          SILC_GET64_MSB(*x, src->data);
        silc_buffer_pull(src, sizeof(SilcUInt64));
        break;
@@ -408,7 +408,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        char *x = va_arg(ap, char *);
        UNFORMAT_HAS_SPACE(src, 1);
-       if (x)
+       if (silc_likely(x))
          *x = src->data[0];
        silc_buffer_pull(src, 1);
        break;
@@ -417,7 +417,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt16 *x = va_arg(ap, SilcInt16 *);
        UNFORMAT_HAS_SPACE(src, 2);
-       if (x)
+       if (silc_likely(x))
          SILC_GET16_MSB(*x, src->data);
        silc_buffer_pull(src, 2);
        break;
@@ -426,7 +426,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt32 *x = va_arg(ap, SilcInt32 *);
        UNFORMAT_HAS_SPACE(src, 4);
-       if (x)
+       if (silc_likely(x))
          SILC_GET32_MSB(*x, src->data);
        silc_buffer_pull(src, 4);
        break;
@@ -435,7 +435,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt64 *x = va_arg(ap, SilcInt64 *);
        UNFORMAT_HAS_SPACE(src, sizeof(SilcInt64));
-       if (x)
+       if (silc_likely(x))
          SILC_GET64_MSB(*x, src->data);
        silc_buffer_pull(src, sizeof(SilcInt64));
        break;
@@ -448,7 +448,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        len2 = (SilcUInt8)src->data[0];
        silc_buffer_pull(src, 1);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -461,7 +461,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET16_MSB(len2, src->data);
        silc_buffer_pull(src, 2);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -474,7 +474,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        len2 = (SilcUInt8)src->data[0];
        silc_buffer_pull(src, 1);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -489,7 +489,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET16_MSB(len2, src->data);
        silc_buffer_pull(src, 2);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -504,7 +504,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET32_MSB(len2, src->data);
        silc_buffer_pull(src, 4);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -517,7 +517,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET32_MSB(len2, src->data);
        silc_buffer_pull(src, 4);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -702,7 +702,7 @@ int silc_buffer_strformat(SilcBuffer dst, ...)
 
     slen = strlen(string);
     d = silc_realloc(dst->head, sizeof(*dst->head) * (slen + len + 1));
-    if (!d)
+    if (silc_unlikely(!d))
       return -1;
     dst->head = d;
     memcpy(dst->head + len, string, slen);
@@ -747,7 +747,7 @@ int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...)
     slen = strlen(string);
     d = silc_srealloc_ua(stack, len + 1, dst->head,
                         sizeof(*dst->head) * (slen + len + 1));
-    if (!d)
+    if (silc_unlikely(!d))
       return -1;
     dst->head = d;
     memcpy(dst->head + len, string, slen);
index cb46c82f303b825bb9202ef7ae03c3d002bb2dbb..5b7a6ab69dfda2010bb88fd607ad956743959003 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2000 - 2005 Pekka Riikonen
+  Copyright (C) 2000 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
  * will automatically allocate list entries.  Normal SILC List API cannot
  * be used for this purpose because in that case the context passed to the
  * list must be defined as list structure already.  This is not the case in
- * SilcDList.  But SilcDList is a bit slower than SilcList because it 
+ * SilcDList.  But SilcDList is a bit slower than SilcList because it
  * requires memory allocation when adding new entries to the list.
  *
- * SILC Dynamic List is not thread-safe.  If the same list context must be 
+ * SILC Dynamic List is not thread-safe.  If the same list context must be
  * used in multithreaded environment concurrency control must be employed.
  *
  ***/
@@ -201,7 +201,7 @@ static inline
 SilcBool silc_dlist_add(SilcDList list, void *context)
 {
   SilcDListEntry e = (SilcDListEntry)silc_malloc(sizeof(*e));
-  if (!e)
+  if (silc_unlikely(!e))
     return FALSE;
   e->context = context;
   silc_list_add(list->list, e);
@@ -227,7 +227,7 @@ static inline
 SilcBool silc_dlist_insert(SilcDList list, void *context)
 {
   SilcDListEntry e = (SilcDListEntry)silc_malloc(sizeof(*e));
-  if (!e)
+  if (silc_unlikely(!e))
     return FALSE;
   e->context = context;
   silc_list_insert(list->list, list->prev, e);
index 4df30aec9f06748b14503d335e376b6377a4cad9..4feffdffba0f74110f3d13f929278dcf49b8336e 100644 (file)
@@ -38,11 +38,11 @@ SilcFSM silc_fsm_alloc(void *fsm_context,
   SilcFSM fsm;
 
   fsm = silc_calloc(1, sizeof(*fsm));
-  if (!fsm)
+  if (silc_unlikely(!fsm))
     return NULL;
 
-  if (!silc_fsm_init(fsm, fsm_context, destructor,
-                    destructor_context, schedule)) {
+  if (silc_unlikely(!silc_fsm_init(fsm, fsm_context, destructor,
+                                  destructor_context, schedule))) {
     silc_free(fsm);
     return NULL;
   }
@@ -86,7 +86,7 @@ SilcFSMThread silc_fsm_thread_alloc(SilcFSM fsm,
   SilcFSMThread thread;
 
   thread = silc_calloc(1, sizeof(*thread));
-  if (!thread)
+  if (silc_unlikely(!thread))
     return NULL;
 
   silc_fsm_thread_init(thread, fsm, thread_context, destructor,
@@ -480,7 +480,7 @@ SilcFSMSema silc_fsm_sema_alloc(SilcFSM fsm, SilcUInt32 value)
   SilcFSMSema sema;
 
   sema = silc_calloc(1, sizeof(*sema));
-  if (!sema)
+  if (silc_unlikely(!sema))
     return NULL;
 
   silc_fsm_sema_init(sema, fsm, value);
@@ -673,7 +673,7 @@ void silc_fsm_sema_post(SilcFSMSema sema)
     }
 
     p = silc_calloc(1, sizeof(*p));
-    if (!p)
+    if (silc_unlikely(!p))
       continue;
     p->sema = sema;
     p->fsm = fsm;
@@ -725,11 +725,12 @@ static void *silc_fsm_thread(void *context)
      cannot be used in this thread.  Application may still use it if it
      wants but we use our own. */
   fsm->schedule = silc_schedule_init(0, old);
-  if (!fsm->schedule)
+  if (silc_unlikely(!fsm->schedule))
     return NULL;
 
   /* Start the FSM thread */
-  if (!silc_schedule_task_add_timeout(fsm->schedule, silc_fsm_run, fsm, 0, 0))
+  if (silc_unlikely(!silc_schedule_task_add_timeout(fsm->schedule,
+                                                   silc_fsm_run, fsm, 0, 0)))
     return NULL;
 
   /* Run the scheduler */
index 3ab49aa290903605df16f3f7bf139119a145f2e7..cf8bc54c9636ef4127d7b045fa7d27c1964719b1 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1999 - 2005 Pekka Riikonen
+  Copyright (C) 1999 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
 void *silc_malloc(size_t size)
 {
   void *addr;
-  if (size <= 0 || size >= SILC_MAX_ALLOC) {
+  if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Invalid memory allocation"));
     return NULL;
   }
   addr = malloc(size);
-  if (!addr)
+  if (silc_unlikely(!addr))
     SILC_LOG_ERROR(("System out of memory"));
   return addr;
 }
@@ -40,12 +40,12 @@ void *silc_malloc(size_t size)
 void *silc_calloc(size_t items, size_t size)
 {
   void *addr;
-  if (size * items <= 0 || size * items >= SILC_MAX_ALLOC) {
+  if (silc_unlikely(size * items <= 0 || size * items >= SILC_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Invalid memory allocation"));
     return NULL;
   }
   addr = calloc(items, size);
-  if (!addr)
+  if (silc_unlikely(!addr))
     SILC_LOG_ERROR(("System out of memory"));
   return addr;
 }
@@ -53,12 +53,12 @@ void *silc_calloc(size_t items, size_t size)
 void *silc_realloc(void *ptr, size_t size)
 {
   void *addr;
-  if (size <= 0 || size >= SILC_MAX_ALLOC) {
+  if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Invalid memory allocation"));
     return NULL;
   }
   addr = realloc(ptr, size);
-  if (!addr)
+  if (silc_unlikely(!addr))
     SILC_LOG_ERROR(("System out of memory"));
   return addr;
 }
@@ -72,7 +72,7 @@ void *silc_memdup(const void *ptr, size_t size)
 {
   unsigned char *addr;
   addr = silc_malloc(size + 1);
-  if (!addr) {
+  if (silc_unlikely(!addr)) {
     SILC_LOG_ERROR(("System out of memory"));
     return NULL;
   }
@@ -103,7 +103,7 @@ void *silc_scalloc(SilcStack stack, SilcUInt32 items, SilcUInt32 size)
     return silc_calloc(items, size);
 
   addr = silc_stack_malloc(stack, items * size, TRUE);
-  if (!addr)
+  if (silc_unlikely(!addr))
     return NULL;
   memset(addr, 0, items * size);
   return (void *)addr;
@@ -131,7 +131,7 @@ void *silc_smemdup(SilcStack stack, const void *ptr, SilcUInt32 size)
     return silc_memdup(ptr, size);
 
   addr = silc_stack_malloc(stack, size + 1, TRUE);
-  if (!addr)
+  if (silc_unlikely(!addr))
     return NULL;
   memcpy((void *)addr, ptr, size);
   addr[size] = '\0';
@@ -147,7 +147,7 @@ char *silc_sstrdup(SilcStack stack, const char *str)
     return silc_memdup(str, size);
 
   addr = silc_stack_malloc(stack, size + 1, FALSE);
-  if (!addr)
+  if (silc_unlikely(!addr))
     return NULL;
   memcpy((void *)addr, str, size);
   addr[size] = '\0';
index 449975207c41b0318035b5e130fc71c4a3b6f63e..ac96afab07ae8f46aa829fd9c12ea02ba0651e89 100644 (file)
@@ -54,11 +54,11 @@ static void silc_schedule_dispatch_fd(SilcSchedule schedule)
   while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
     t = (SilcTask)task;
 
-    if (!t->valid) {
+    if (silc_unlikely(!t->valid)) {
       silc_schedule_task_remove(schedule, t);
       continue;
     }
-    if (!task->events || !task->revents)
+    if (!task->revents || !task->events)
       continue;
 
     /* Is the task ready for reading */
@@ -78,7 +78,7 @@ static void silc_schedule_dispatch_fd(SilcSchedule schedule)
     }
 
     /* Remove if task was invalidated in the task callback */
-    if (!t->valid)
+    if (silc_unlikely(!t->valid))
       silc_schedule_task_remove(schedule, t);
   }
   silc_hash_table_list_reset(&htl);
@@ -102,31 +102,37 @@ static void silc_schedule_dispatch_timeout(SilcSchedule schedule,
 
   /* First task in the task queue has always the earliest timeout. */
   silc_list_start(schedule->timeout_queue);
-  while ((task = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
+  task = silc_list_get(schedule->timeout_queue);
+  do {
     t = (SilcTask)task;
 
     /* Remove invalid task */
-    if (!t->valid) {
+    if (silc_unlikely(!t->valid)) {
       silc_schedule_task_remove(schedule, t);
       continue;
     }
 
+    SILC_SCHEDULE_UNLOCK(schedule);
+
     /* Execute the task if the timeout has expired */
-    if (dispatch_all || silc_compare_timeval(&task->timeout, &curtime)) {
-      t->valid = FALSE;
-      SILC_SCHEDULE_UNLOCK(schedule);
-      t->callback(schedule, schedule->app_context, SILC_TASK_EXPIRE, 0,
-                 t->context);
+    if (!silc_compare_timeval(&task->timeout, &curtime) && !dispatch_all) {
       SILC_SCHEDULE_LOCK(schedule);
+      break;
+    }
 
-      /* Remove the expired task */
-      silc_schedule_task_remove(schedule, t);
+    t->valid = FALSE;
+    t->callback(schedule, schedule->app_context, SILC_TASK_EXPIRE, 0,
+               t->context);
 
-      /* Balance when we have lots of small timeouts */
-      if ((++count) > 40)
-       break;
-    }
-  }
+    SILC_SCHEDULE_LOCK(schedule);
+
+    /* Remove the expired task */
+    silc_schedule_task_remove(schedule, t);
+
+    /* Balance when we have lots of small timeouts */
+    if (silc_unlikely((++count) > 40))
+      break;
+  } while (silc_likely((task = silc_list_get(schedule->timeout_queue))));
 }
 
 /* Calculates next timeout. This is the timeout value when at earliest some
@@ -146,11 +152,12 @@ static void silc_schedule_select_timeout(SilcSchedule schedule)
 
   /* First task in the task queue has always the earliest timeout. */
   silc_list_start(schedule->timeout_queue);
-  while ((task = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
+  task = silc_list_get(schedule->timeout_queue);
+  do {
     t = (SilcTask)task;
 
     /* Remove invalid task */
-    if (!t->valid) {
+    if (silc_unlikely(!t->valid)) {
       silc_schedule_task_remove(schedule, t);
       continue;
     }
@@ -159,7 +166,7 @@ static void silc_schedule_select_timeout(SilcSchedule schedule)
        timeout tasks from the past. */
     if (silc_compare_timeval(&task->timeout, &curtime) && dispatch) {
       silc_schedule_dispatch_timeout(schedule, FALSE);
-      if (!schedule->valid)
+      if (silc_unlikely(!schedule->valid))
        return;
 
       /* Start selecting new timeout again after dispatch */
@@ -181,9 +188,8 @@ static void silc_schedule_select_timeout(SilcSchedule schedule)
        curtime.tv_sec = 0;
       curtime.tv_usec += 1000000L;
     }
-
     break;
-  }
+  } while ((task = silc_list_get(schedule->timeout_queue)));
 
   /* Save the timeout */
   if (task) {
@@ -200,9 +206,8 @@ static void silc_schedule_select_timeout(SilcSchedule schedule)
 static void silc_schedule_task_remove(SilcSchedule schedule, SilcTask task)
 {
   SilcTaskFd ftask;
-  SilcTaskTimeout ttask;
 
-  if (task == SILC_ALL_TASKS) {
+  if (silc_unlikely(task == SILC_ALL_TASKS)) {
     SilcTask task;
     SilcHashTableList htl;
     SilcUInt32 fd;
@@ -223,25 +228,17 @@ static void silc_schedule_task_remove(SilcSchedule schedule, SilcTask task)
     return;
   }
 
-  /* Delete from timeout queue */
-  if (task->type == 1) {
-    silc_list_start(schedule->timeout_queue);
-    while ((ttask = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
-      if (ttask == (SilcTaskTimeout)task) {
-       silc_list_del(schedule->timeout_queue, ttask);
-
-       /* Put to free list */
-       silc_list_add(schedule->free_tasks, ttask);
-       break;
-      }
-    }
+  if (silc_likely(task->type == 1)) {
+    /* Delete from timeout queue */
+    silc_list_del(schedule->timeout_queue, task);
 
-    return;
+    /* Put to free list */
+    silc_list_add(schedule->free_tasks, task);
+  } else {
+    /* Delete from fd queue */
+    ftask = (SilcTaskFd)task;
+    silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(ftask->fd));
   }
-
-  /* Delete from fd queue */
-  ftask = (SilcTaskFd)task;
-  silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(ftask->fd));
 }
 
 /* Timeout freelist garbage collection */
@@ -418,21 +415,18 @@ void silc_schedule_stop(SilcSchedule schedule)
   SILC_SCHEDULE_UNLOCK(schedule);
 }
 
-/* Runs the scheduler once and then returns. */
+/* Runs the scheduler once and then returns.   Must be called locked. */
 
-SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
+static SilcBool silc_schedule_iterate(SilcSchedule schedule, int timeout_usecs)
 {
   struct timeval timeout;
   int ret;
 
-  if (!schedule->is_locked)
-    SILC_SCHEDULE_LOCK(schedule);
-
   do {
     SILC_LOG_DEBUG(("In scheduler loop"));
 
     /* Deliver signals if any has been set to be called */
-    if (schedule->signal_tasks) {
+    if (silc_unlikely(schedule->signal_tasks)) {
       SILC_SCHEDULE_UNLOCK(schedule);
       schedule_ops.signals_call(schedule, schedule->internal);
       schedule->signal_tasks = FALSE;
@@ -440,10 +434,8 @@ SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
     }
 
     /* Check if scheduler is valid */
-    if (schedule->valid == FALSE) {
+    if (silc_unlikely(schedule->valid == FALSE)) {
       SILC_LOG_DEBUG(("Scheduler not valid anymore, exiting"));
-      if (!schedule->is_locked)
-       SILC_SCHEDULE_UNLOCK(schedule);
       return FALSE;
     }
 
@@ -453,10 +445,8 @@ SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
     silc_schedule_select_timeout(schedule);
 
     /* Check if scheduler is valid */
-    if (schedule->valid == FALSE) {
+    if (silc_unlikely(schedule->valid == FALSE)) {
       SILC_LOG_DEBUG(("Scheduler not valid anymore, exiting"));
-      if (!schedule->is_locked)
-       SILC_SCHEDULE_UNLOCK(schedule);
       return FALSE;
     }
 
@@ -473,50 +463,52 @@ SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
     SILC_LOG_DEBUG(("Select"));
     ret = schedule_ops.select(schedule, schedule->internal);
 
-    switch (ret) {
-    case 0:
+    if (silc_likely(ret == 0)) {
       /* Timeout */
       SILC_LOG_DEBUG(("Running timeout tasks"));
-      if (silc_list_count(schedule->timeout_queue))
+      if (silc_likely(silc_list_count(schedule->timeout_queue)))
        silc_schedule_dispatch_timeout(schedule, FALSE);
-      break;
-    case -1:
-      /* Error */
-      if (errno == EINTR)
-       break;
-      SILC_LOG_ERROR(("Error in select(): %s", strerror(errno)));
-      break;
-    default:
+      continue;
+
+    } else if (silc_likely(ret > 0)) {
       /* There is some data available now */
       SILC_LOG_DEBUG(("Running fd tasks"));
       silc_schedule_dispatch_fd(schedule);
-      break;
+      continue;
+
+    } else {
+      /* Error */
+      if (silc_likely(errno == EINTR))
+       continue;
+      SILC_LOG_ERROR(("Error in select()/poll(): %s", strerror(errno)));
+      continue;
     }
   } while (timeout_usecs == -1);
 
-  if (!schedule->is_locked)
-    SILC_SCHEDULE_UNLOCK(schedule);
-
   return TRUE;
 }
 
-/* The SILC scheduler. This is actually the main routine in SILC programs.
-   When this returns the program is to be ended. Before this function can
-   be called, one must call silc_schedule_init function. */
+/* Runs the scheduler once and then returns. */
+
+SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
+{
+  SilcBool ret;
+  SILC_SCHEDULE_LOCK(schedule);
+  ret = silc_schedule_iterate(schedule, timeout_usecs);
+  SILC_SCHEDULE_UNLOCK(schedule);
+  return ret;
+}
+
+/* Runs the scheduler and blocks here.  When this returns the scheduler
+   has ended. */
 
 void silc_schedule(SilcSchedule schedule)
 {
   SILC_LOG_DEBUG(("Running scheduler"));
 
-  if (schedule->valid == FALSE) {
-    SILC_LOG_ERROR(("Scheduler is not valid, stopping"));
-    return;
-  }
-
   /* Start the scheduler loop */
   SILC_SCHEDULE_LOCK(schedule);
-  schedule->is_locked = TRUE;
-  silc_schedule_one(schedule, -1);
+  silc_schedule_iterate(schedule, -1);
   SILC_SCHEDULE_UNLOCK(schedule);
 }
 
@@ -556,19 +548,20 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 {
   SilcTask task = NULL;
 
-  if (!schedule->valid)
+  if (silc_unlikely(!schedule->valid))
     return NULL;
 
   SILC_SCHEDULE_LOCK(schedule);
 
-  if (type == SILC_TASK_TIMEOUT) {
+  if (silc_likely(type == SILC_TASK_TIMEOUT)) {
     SilcTaskTimeout tmp, prev, ttask;
+    SilcList list;
 
     silc_list_start(schedule->free_tasks);
     ttask = silc_list_get(schedule->free_tasks);
-    if (!ttask) {
+    if (silc_unlikely(!ttask)) {
       ttask = silc_calloc(1, sizeof(*ttask));
-      if (!ttask)
+      if (silc_unlikely(!ttask))
        goto out;
     }
     silc_list_del(schedule->free_tasks, ttask);
@@ -594,9 +587,10 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 
     /* Add task to correct spot so that the first task in the list has
        the earliest timeout. */
-    silc_list_start(schedule->timeout_queue);
+    list = schedule->timeout_queue;
+    silc_list_start(list);
     prev = NULL;
-    while ((tmp = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
+    while ((tmp = silc_list_get(list)) != SILC_LIST_END) {
       /* If we have shorter timeout, we have found our spot */
       if (silc_compare_timeval(&ttask->timeout, &tmp->timeout)) {
        silc_list_insert(schedule->timeout_queue, prev, ttask);
@@ -609,21 +603,23 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 
     task = (SilcTask)ttask;
 
-  } else if (type == SILC_TASK_FD) {
+  } else if (silc_likely(type == SILC_TASK_FD)) {
     /* Check if fd is already added */
-    if (silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fd),
-                            NULL, (void **)&task))
+    if (silc_unlikely(silc_hash_table_find(schedule->fd_queue,
+                                          SILC_32_TO_PTR(fd),
+                                          NULL, (void **)&task)))
       goto out;
 
     /* Check max tasks */
-    if (schedule->max_tasks > 0 &&
-       silc_hash_table_count(schedule->fd_queue) >= schedule->max_tasks) {
+    if (silc_unlikely(schedule->max_tasks > 0 &&
+                     silc_hash_table_count(schedule->fd_queue) >=
+                     schedule->max_tasks)) {
       SILC_LOG_WARNING(("Scheduler task limit reached: cannot add new task"));
       goto out;
     }
 
     SilcTaskFd ftask = silc_calloc(1, sizeof(*ftask));
-    if (!ftask)
+    if (silc_unlikely(!ftask))
       goto out;
 
     SILC_LOG_DEBUG(("New fd task %p fd=%d", ftask, fd));
@@ -640,14 +636,13 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 
     task = (SilcTask)ftask;
 
-  } else if (type == SILC_TASK_SIGNAL) {
+  } else if (silc_unlikely(type == SILC_TASK_SIGNAL)) {
     SILC_SCHEDULE_UNLOCK(schedule);
-    schedule_ops.signal_register(schedule, schedule->internal, (int)fd,
+    schedule_ops.signal_register(schedule, schedule->internal, fd,
                                 callback, context);
     return NULL;
   }
 
-
  out:
   SILC_SCHEDULE_UNLOCK(schedule);
   return task;
@@ -657,7 +652,7 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 
 void silc_schedule_task_del(SilcSchedule schedule, SilcTask task)
 {
-  if (task == SILC_ALL_TASKS) {
+  if (silc_unlikely(task == SILC_ALL_TASKS)) {
     SilcHashTableList htl;
 
     SILC_LOG_DEBUG(("Unregister all tasks"));
@@ -697,14 +692,15 @@ void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd)
   SILC_SCHEDULE_LOCK(schedule);
 
   /* fd is unique, so there is only one task with this fd in the table */
-  if (silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fd), NULL,
-                          (void **)&task))
+  if (silc_likely(silc_hash_table_find(schedule->fd_queue,
+                                      SILC_32_TO_PTR(fd), NULL,
+                                      (void **)&task)))
     task->valid = FALSE;
 
   SILC_SCHEDULE_UNLOCK(schedule);
 
   /* If it is signal, remove it */
-  if (!task)
+  if (silc_unlikely(!task))
     schedule_ops.signal_unregister(schedule, schedule->internal, fd);
 }
 
@@ -715,6 +711,7 @@ void silc_schedule_task_del_by_callback(SilcSchedule schedule,
 {
   SilcTask task;
   SilcHashTableList htl;
+  SilcList list;
 
   SILC_LOG_DEBUG(("Unregister task by callback"));
 
@@ -729,9 +726,9 @@ void silc_schedule_task_del_by_callback(SilcSchedule schedule,
   silc_hash_table_list_reset(&htl);
 
   /* Delete from timeout queue */
-  silc_list_start(schedule->timeout_queue);
-  while ((task = (SilcTask)silc_list_get(schedule->timeout_queue))
-        != SILC_LIST_END) {
+  list = schedule->timeout_queue;
+  silc_list_start(list);
+  while ((task = (SilcTask)silc_list_get(list))) {
     if (task->callback == callback)
       task->valid = FALSE;
   }
@@ -745,6 +742,7 @@ void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context)
 {
   SilcTask task;
   SilcHashTableList htl;
+  SilcList list;
 
   SILC_LOG_DEBUG(("Unregister task by context"));
 
@@ -759,9 +757,9 @@ void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context)
   silc_hash_table_list_reset(&htl);
 
   /* Delete from timeout queue */
-  silc_list_start(schedule->timeout_queue);
-  while ((task = (SilcTask)silc_list_get(schedule->timeout_queue))
-        != SILC_LIST_END) {
+  list = schedule->timeout_queue;
+  silc_list_start(list);
+  while ((task = (SilcTask)silc_list_get(list))) {
     if (task->context == context)
       task->valid = FALSE;
   }
@@ -775,6 +773,7 @@ void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
                                   SilcTaskCallback callback, void *context)
 {
   SilcTask task;
+  SilcList list;
 
   SILC_LOG_DEBUG(("Unregister task by fd, callback and context"));
 
@@ -785,9 +784,9 @@ void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
   SILC_SCHEDULE_LOCK(schedule);
 
   /* Delete from timeout queue */
-  silc_list_start(schedule->timeout_queue);
-  while ((task = (SilcTask)silc_list_get(schedule->timeout_queue))
-        != SILC_LIST_END) {
+  list = schedule->timeout_queue;
+  silc_list_start(list);
+  while ((task = (SilcTask)silc_list_get(list))) {
     if (task->callback == callback && task->context == context)
       task->valid = FALSE;
   }
@@ -804,7 +803,7 @@ void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
 {
   SilcTaskFd task;
 
-  if (!schedule->valid)
+  if (silc_unlikely(!schedule->valid))
     return;
 
   SILC_SCHEDULE_LOCK(schedule);
@@ -812,7 +811,7 @@ void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
   if (silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fd),
                           NULL, (void **)&task)) {
     task->events = mask;
-    if (send_events) {
+    if (silc_unlikely(send_events)) {
       task->revents = mask;
       silc_schedule_dispatch_fd(schedule);
     }
index e2f4e581d5aeb047e4e08cd2fbaf62807ea2c5be..637f058101bf28f52e3587df8caef94e1b772b86 100644 (file)
@@ -414,8 +414,8 @@ void *silc_schedule_get_context(SilcSchedule schedule);
  *    the signal call silc_schedule_task_del_by_fd.
  *
  ***/
-#define silc_schedule_task_add_signal(schedule, signal, callback, context) \
-  silc_schedule_task_add(schedule, signal, callback, context, 0, 0,    \
+#define silc_schedule_task_add_signal(schedule, sig, callback, context) \
+  silc_schedule_task_add(schedule, sig, callback, context, 0, 0,       \
                         SILC_TASK_SIGNAL)
 
 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del
index c7135393788ee109f51c46a71e429703650e89c3..3c1598c7fe0901bd429bdaa017a283e8aea8b429 100644 (file)
@@ -62,7 +62,6 @@ struct SilcScheduleStruct {
   unsigned int max_tasks     : 28; /* Max FD tasks */
   unsigned int has_timeout   : 1;  /* Set if timeout is set */
   unsigned int valid         : 1;  /* Set if scheduler is valid */
-  unsigned int is_locked     : 1;  /* Set if scheduler is locked */
   unsigned int signal_tasks  : 1;  /* Set if to dispatch signals */
 };
 
index 1bd6b8b32144b79c18b25048db5f23640fae0555..0e40d4141ddd64ab799c7a59b4c68c427281b9ed 100644 (file)
@@ -60,7 +60,7 @@ SILC_TASK_CALLBACK(silc_socket_stream_io)
 {
   SilcSocketStream stream = context;
 
-  if (!stream->notifier)
+  if (silc_unlikely(!stream->notifier))
     return;
 
   switch (type) {
index 0e4b67de83c38cfabf51c4fd698319e134fe2c57..9432b22d25c10c69693345f6072156fd1b8066f8 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 - 2005 Pekka Riikonen
+  Copyright (C) 2003 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -155,13 +155,13 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, SilcBool aligned)
   SILC_ST_DEBUG(("Allocating %d bytes (%s) from %p",
                 size, aligned ? "align" : "not align", stack));
 
-  if (!size) {
+  if (silc_unlikely(!size)) {
     SILC_LOG_ERROR(("Allocation by zero (0)"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
   }
 
-  if (size > SILC_STACK_MAX_ALLOC) {
+  if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Allocating too much"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -193,7 +193,7 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, SilcBool aligned)
     bsize2 <<= 1;
     si++;
   }
-  if (si >= SILC_STACK_BLOCK_NUM) {
+  if (silc_unlikely(si >= SILC_STACK_BLOCK_NUM)) {
     SILC_LOG_ERROR(("Allocating too large block"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -205,7 +205,7 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, SilcBool aligned)
     stack->stack[si] = silc_malloc(bsize2 +
                                   SILC_STACK_ALIGN(sizeof(**stack->stack),
                                                    SILC_STACK_DEFAULT_ALIGN));
-    if (!stack->stack[si]) {
+    if (silc_unlikely(!stack->stack[si])) {
       SILC_STACK_STAT(stack, num_errors, 1);
       return NULL;
     }
@@ -244,13 +244,13 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
   SILC_ST_DEBUG(("Reallocating %d bytes (%d) (%s) from %p", size, old_size,
                 aligned ? "align" : "not align", stack));
 
-  if (!size || !old_size) {
+  if (silc_unlikely(!size || !old_size)) {
     SILC_LOG_ERROR(("Allocation by zero (0)"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
   }
 
-  if (size > SILC_STACK_MAX_ALLOC) {
+  if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Allocating too much"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
index 1e7639ce879a9f255c57a261ef176f7ab12873ee..851bdd011979f29d6925842344390829235efe8f 100644 (file)
@@ -107,8 +107,19 @@ typedef unsigned char SilcBool;
 #endif
 /***/
 
+/* Our offsetof macro */
 #define silc_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 
+/* silc_likely and silc_unlikely GCC branch prediction macros. Use only if
+   you have profiled the code first. */
+#if __GNUC__ >= 3
+#define silc_likely(expr) __builtin_expect(!!(expr), 1)
+#define silc_unlikely(expr) __builtin_expect(!!(expr), 0)
+#else
+#define silc_likely(expr) (expr)
+#define silc_unlikely(expr) (expr)
+#endif /* __GNUC__ >= 3 */
+
 #if SILC_SIZEOF_SHORT > 2
 #error "size of the short must be 2 bytes"
 #endif
@@ -285,8 +296,8 @@ typedef SilcUInt32 * void *;
  */
 #define SILC_GET16_MSB(l, cp)                          \
 do {                                                   \
-       (l) = ((SilcUInt32)(SilcUInt8)(cp)[0] << 8)     \
-           | ((SilcUInt32)(SilcUInt8)(cp)[1]);         \
+  (l) = ((SilcUInt32)(SilcUInt8)(cp)[0] << 8)          \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1]);                        \
 } while(0)
 /***/
 
@@ -304,10 +315,10 @@ do {                                                      \
  */
 #define SILC_GET32_MSB(l, cp)                          \
 do {                                                   \
-       (l) = ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24    \
-           | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16)    \
-           | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8)     \
-           | ((SilcUInt32)(SilcUInt8)(cp)[3]);         \
+  (l) = ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24         \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16)           \
+    | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8)            \
+    | ((SilcUInt32)(SilcUInt8)(cp)[3]);                        \
 } while(0)
 /***/
 
@@ -325,8 +336,8 @@ do {                                                        \
  */
 #define SILC_GET64_MSB(l, cp)                                  \
 do {                                                           \
-       (l) = ((((SilcUInt64)SILC_GET_WORD((cp))) << 32) |      \
-             ((SilcUInt64)SILC_GET_WORD((cp) + 4)));           \
+  (l) = ((((SilcUInt64)SILC_GET_WORD((cp))) << 32) |           \
+        ((SilcUInt64)SILC_GET_WORD((cp) + 4)));                \
 } while(0)
 /***/
 
@@ -342,11 +353,15 @@ do {                                                              \
  *
  * SOURCE
  */
+#if defined(SILC_I486) && defined(__GNUC__)
+#define SILC_GET16_LSB(l, cp) (l) = (*(SilcUInt16 *)(cp))
+#else
 #define SILC_GET16_LSB(l, cp)                          \
 do {                                                   \
-       (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])          \
-           | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8);    \
+  (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])               \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8);           \
 } while(0)
+#endif /* SILC_I486 && __GNUC__ */
 /***/
 
 /****d* silcutil/SILCTypes/SILC_GET32_LSB
@@ -361,20 +376,28 @@ do {                                                      \
  *
  * SOURCE
  */
+#if defined(SILC_I486) && defined(__GNUC__)
+#define SILC_GET32_LSB(l, cp) (l) = (*(SilcUInt32 *)(cp))
+#else
 #define SILC_GET32_LSB(l, cp)                          \
 do {                                                   \
-       (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])          \
-           | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)     \
-           | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)    \
-           | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24);   \
+  (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])               \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)            \
+    | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)           \
+    | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24);          \
 } while(0)
+#endif /* SILC_I486 && __GNUC__ */
 
 /* Same as upper but XOR the result always. Special purpose macro. */
+#if defined(SILC_I486) && defined(__GNUC__)
+#define SILC_GET32_X_LSB(l, cp) (l) ^= (*(SilcUInt32 *)(cp))
+#else
 #define SILC_GET32_X_LSB(l, cp)                                \
-       (l) ^= ((SilcUInt32)(SilcUInt8)(cp)[0])         \
-           | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)     \
-           | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)    \
-           | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24)
+  (l) ^= ((SilcUInt32)(SilcUInt8)(cp)[0])              \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)            \
+    | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)           \
+    | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24)
+#endif /* SILC_I486 && __GNUC__ */
 /***/
 
 /****d* silcutil/SILCTypes/SILC_PUT16_MSB
@@ -391,8 +414,8 @@ do {                                                        \
  */
 #define SILC_PUT16_MSB(l, cp)                  \
 do {                                           \
-       (cp)[0] = (SilcUInt8)((l) >> 8);        \
-       (cp)[1] = (SilcUInt8)(l);               \
+  (cp)[0] = (SilcUInt8)((l) >> 8);             \
+  (cp)[1] = (SilcUInt8)(l);                    \
 } while(0)
 /***/
 
@@ -410,10 +433,10 @@ do {                                              \
  */
 #define SILC_PUT32_MSB(l, cp)                  \
 do {                                           \
-       (cp)[0] = (SilcUInt8)((l) >> 24);       \
-       (cp)[1] = (SilcUInt8)((l) >> 16);       \
-       (cp)[2] = (SilcUInt8)((l) >> 8);        \
-       (cp)[3] = (SilcUInt8)(l);               \
+  (cp)[0] = (SilcUInt8)((l) >> 24);            \
+  (cp)[1] = (SilcUInt8)((l) >> 16);            \
+  (cp)[2] = (SilcUInt8)((l) >> 8);             \
+  (cp)[3] = (SilcUInt8)(l);                    \
 } while(0)
 /***/
 
@@ -448,11 +471,15 @@ do {                                                              \
  *
  * SOURCE
  */
+#if defined(SILC_I486) && defined(__GNUC__)
+#define SILC_PUT16_LSB(l, cp) (*(SilcUInt16 *)(cp)) = (l)
+#else
 #define SILC_PUT16_LSB(l, cp)                  \
 do  {                                          \
-       (cp)[0] = (SilcUInt8)(l);               \
-       (cp)[1] = (SilcUInt8)((l) >> 8);        \
+  (cp)[0] = (SilcUInt8)(l);                    \
+  (cp)[1] = (SilcUInt8)((l) >> 8);             \
 } while(0)
+#endif /* SILC_I486 && __GNUC__ */
 /***/
 
 /****d* silcutil/SILCTypes/SILC_PUT32_LSB
@@ -467,13 +494,17 @@ do  {                                             \
  *
  * SOURCE
  */
+#if defined(SILC_I486) && defined(__GNUC__)
+#define SILC_PUT32_LSB(l, cp) (*(SilcUInt32 *)(cp)) = (l)
+#else
 #define SILC_PUT32_LSB(l, cp)                  \
 do {                                           \
-       (cp)[0] = (SilcUInt8)(l);               \
-       (cp)[1] = (SilcUInt8)((l) >> 8);        \
-       (cp)[2] = (SilcUInt8)((l) >> 16);       \
-       (cp)[3] = (SilcUInt8)((l) >> 24);       \
+  (cp)[0] = (SilcUInt8)(l);                    \
+  (cp)[1] = (SilcUInt8)((l) >> 8);             \
+  (cp)[2] = (SilcUInt8)((l) >> 16);            \
+  (cp)[3] = (SilcUInt8)((l) >> 24);            \
 } while(0)
+#endif /* SILC_I486 && __GNUC__ */
 /***/
 
 /****d* silcutil/SILCTypes/SILC_SWAB_16
index df11891ba2bb90c1b817355a51340a9c8fc96dcf..04cd98067711dc29014b8ade1128ca17a4fd11bd 100644 (file)
@@ -386,6 +386,43 @@ int main(int argc, char **argv)
     silc_log_set_debug_string("*fsm*,*async*");
   }
 
+{
+#define SSILC_GET32_MSB(l, cp)                         \
+do {                                                   \
+  (l) = ((SilcUInt32)(SilcUInt8)(cp)[3]) << 24         \
+    | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)           \
+    | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)            \
+    | ((SilcUInt32)(SilcUInt8)(cp)[0]);                        \
+} while(0)
+  unsigned char tmp[8], tmp2[8];
+  SilcUInt32 t1, t2, t3, t4;
+
+  tmp[0] = 0x11;
+  tmp[1] = 0x22;
+  tmp[2] = 0x33;
+  tmp[3] = 0x44;
+  tmp[4] = 0x55;
+  tmp[5] = 0x66;
+  tmp[6] = 0x77;
+  tmp[7] = 0x88;
+
+  SILC_LOG_HEXDUMP(("DATA"), tmp, 4);
+
+  SILC_GET32_LSB(t1, tmp);
+  SILC_LOG_DEBUG(("GET_LSB: %x", t1));
+  
+  SSILC_GET32_MSB(t1, tmp);
+  SILC_LOG_DEBUG(("GET_MSB: %x", t1));
+
+  SILC_PUT32_LSB(t1, tmp2);
+  SILC_LOG_HEXDUMP(("PUT_LSB"), tmp2, 4);
+
+  SILC_PUT32_MSB(t1, tmp2);
+  SILC_LOG_HEXDUMP(("PUT_MSB"), tmp2, 4);
+
+  exit(1);
+}
+
   SILC_LOG_DEBUG(("Allocating scheduler"));
   schedule = silc_schedule_init(0, NULL);
 
index 9372096170b2af53f2acf2e9ddefb4a7e7aef220..914b42fef891a8f2a6391e927425ac951cafb834 100644 (file)
@@ -41,7 +41,7 @@ typedef struct {
 } *SilcUnixScheduler;
 
 typedef struct {
-  SilcUInt32 signal;
+  SilcUInt32 sig;
   SilcTaskCallback callback;
   void *context;
   SilcBool call;
@@ -75,7 +75,7 @@ int silc_poll(SilcSchedule schedule, void *context)
 
       fds = silc_realloc(internal->fds, sizeof(*internal->fds) *
                         (fds_count + (fds_count / 2)));
-      if (!fds)
+      if (silc_unlikely(!fds))
        break;
       internal->fds = fds;
       internal->fds_count = fds_count = fds_count + (fds_count / 2);
@@ -264,7 +264,7 @@ void *silc_schedule_internal_init(SilcSchedule schedule,
   internal->app_context = app_context;
 
   for (i = 0; i < SIGNAL_COUNT; i++) {
-    signal_call[i].signal = 0;
+    signal_call[i].sig = 0;
     signal_call[i].call = FALSE;
     signal_call[i].schedule = schedule;
   }
@@ -321,11 +321,11 @@ static void silc_schedule_internal_sighandler(int signal)
   int i;
 
   for (i = 0; i < SIGNAL_COUNT; i++) {
-    if (signal_call[i].signal == signal) {
+    if (signal_call[i].sig == signal) {
       signal_call[i].call = TRUE;
       signal_call[i].schedule->signal_tasks = TRUE;
       SILC_LOG_DEBUG(("Scheduling signal %d to be called",
-                     signal_call[i].signal));
+                     signal_call[i].sig));
       break;
     }
   }
@@ -343,13 +343,13 @@ void silc_schedule_internal_signal_register(SilcSchedule schedule,
   if (!internal)
     return;
 
-  SILC_LOG_DEBUG(("Registering signal %d", signal));
+  SILC_LOG_DEBUG(("Registering signal %d", sig));
 
   silc_schedule_internal_signals_block(schedule, context);
 
   for (i = 0; i < SIGNAL_COUNT; i++) {
-    if (!signal_call[i].signal) {
-      signal_call[i].signal = sig;
+    if (!signal_call[i].sig) {
+      signal_call[i].sig = sig;
       signal_call[i].callback = callback;
       signal_call[i].context = callback_context;
       signal_call[i].call = FALSE;
@@ -372,13 +372,13 @@ void silc_schedule_internal_signal_unregister(SilcSchedule schedule,
   if (!internal)
     return;
 
-  SILC_LOG_DEBUG(("Unregistering signal %d", signal));
+  SILC_LOG_DEBUG(("Unregistering signal %d", sig));
 
   silc_schedule_internal_signals_block(schedule, context);
 
   for (i = 0; i < SIGNAL_COUNT; i++) {
-    if (signal_call[i].signal == sig) {
-      signal_call[i].signal = 0;
+    if (signal_call[i].sig == sig) {
+      signal_call[i].sig = 0;
       signal_call[i].callback = NULL;
       signal_call[i].context = NULL;
       signal_call[i].call = FALSE;
@@ -408,10 +408,10 @@ void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)
     if (signal_call[i].call &&
         signal_call[i].callback) {
       SILC_LOG_DEBUG(("Calling signal %d callback",
-                     signal_call[i].signal));
+                     signal_call[i].sig));
       signal_call[i].callback(schedule, internal->app_context,
                              SILC_TASK_INTERRUPT,
-                             signal_call[i].signal,
+                             signal_call[i].sig,
                              signal_call[i].context);
       signal_call[i].call = FALSE;
     }