From d130c376d5e2475fc3cbf30b9fe70d6274f4b7ea Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 15 Dec 2006 15:23:42 +0000 Subject: [PATCH] Added silc_likely and silc_unlikely GCC branch prediction macros. Added various branc prediction optimizations. --- lib/silcutil/silcbuffer.h | 59 ++++---- lib/silcutil/silcbuffmt.c | 50 +++---- lib/silcutil/silcdlist.h | 10 +- lib/silcutil/silcfsm.c | 17 ++- lib/silcutil/silcmemory.c | 22 +-- lib/silcutil/silcschedule.c | 215 +++++++++++++-------------- lib/silcutil/silcschedule.h | 4 +- lib/silcutil/silcschedule_i.h | 1 - lib/silcutil/silcsocketstream.c | 2 +- lib/silcutil/silcstack.c | 14 +- lib/silcutil/silctypes.h | 91 ++++++++---- lib/silcutil/tests/test_silcfsm.c | 37 +++++ lib/silcutil/unix/silcunixschedule.c | 26 ++-- 13 files changed, 308 insertions(+), 240 deletions(-) diff --git a/lib/silcutil/silcbuffer.h b/lib/silcutil/silcbuffer.h index c3148cb3..90bc3be5 100644 --- a/lib/silcutil/silcbuffer.h +++ b/lib/silcutil/silcbuffer.h @@ -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); diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index b17e5253..562af7d8 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -24,19 +24,19 @@ /* 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); diff --git a/lib/silcutil/silcdlist.h b/lib/silcutil/silcdlist.h index cb46c82f..5b7a6ab6 100644 --- a/lib/silcutil/silcdlist.h +++ b/lib/silcutil/silcdlist.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -30,10 +30,10 @@ * 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); diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index 4df30aec..4feffdff 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -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 */ diff --git a/lib/silcutil/silcmemory.c b/lib/silcutil/silcmemory.c index 3ab49aa2..cf8bc54c 100644 --- a/lib/silcutil/silcmemory.c +++ b/lib/silcutil/silcmemory.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -27,12 +27,12 @@ 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'; diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/silcschedule.c index 44997520..ac96afab 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/silcschedule.c @@ -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); } diff --git a/lib/silcutil/silcschedule.h b/lib/silcutil/silcschedule.h index e2f4e581..637f0581 100644 --- a/lib/silcutil/silcschedule.h +++ b/lib/silcutil/silcschedule.h @@ -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 diff --git a/lib/silcutil/silcschedule_i.h b/lib/silcutil/silcschedule_i.h index c7135393..3c1598c7 100644 --- a/lib/silcutil/silcschedule_i.h +++ b/lib/silcutil/silcschedule_i.h @@ -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 */ }; diff --git a/lib/silcutil/silcsocketstream.c b/lib/silcutil/silcsocketstream.c index 1bd6b8b3..0e40d414 100644 --- a/lib/silcutil/silcsocketstream.c +++ b/lib/silcutil/silcsocketstream.c @@ -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) { diff --git a/lib/silcutil/silcstack.c b/lib/silcutil/silcstack.c index 0e4b67de..9432b22d 100644 --- a/lib/silcutil/silcstack.c +++ b/lib/silcutil/silcstack.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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; diff --git a/lib/silcutil/silctypes.h b/lib/silcutil/silctypes.h index 1e7639ce..851bdd01 100644 --- a/lib/silcutil/silctypes.h +++ b/lib/silcutil/silctypes.h @@ -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 diff --git a/lib/silcutil/tests/test_silcfsm.c b/lib/silcutil/tests/test_silcfsm.c index df11891b..04cd9806 100644 --- a/lib/silcutil/tests/test_silcfsm.c +++ b/lib/silcutil/tests/test_silcfsm.c @@ -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); diff --git a/lib/silcutil/unix/silcunixschedule.c b/lib/silcutil/unix/silcunixschedule.c index 93720961..914b42fe 100644 --- a/lib/silcutil/unix/silcunixschedule.c +++ b/lib/silcutil/unix/silcunixschedule.c @@ -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; } -- 2.24.0