diff src/os/unix/ngx_freebsd_rfork_thread.c @ 267:83205e0b5522

nginx-0.0.2-2004-02-24-20:31:46 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 24 Feb 2004 17:31:46 +0000
parents 5238e93961a1
children 7bb9562216ce
line wrap: on
line diff
--- a/src/os/unix/ngx_freebsd_rfork_thread.c
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -15,12 +15,12 @@
  * The condition variable implementation uses the SysV semaphore set of two
  * semaphores. The first is used by the CV mutex, and the second is used
  * by CV itself.
+ *
+ * This threads implementation currently works on i486 and amd64
+ * platforms only.
  */
 
 
-extern int  __isthreaded;
-
-
 static inline int ngx_gettid();
 
 
@@ -36,7 +36,7 @@ static ngx_uint_t   max_threads;
 static ngx_tid_t   *tids;  /* the threads tids array */
 
 
-/* the thread-safe errno */
+/* the thread-safe libc errno */
 
 static int   errno0;   /* the main thread's errno */
 static int  *errnos;   /* the threads errno's array */
@@ -51,6 +51,41 @@ int *__error()
 }
 
 
+/*
+ * __isthreaded enables spinlock() in some libc functions, i.e. in malloc()
+ * and some other places.  Nevertheless we protect our malloc()/free() calls
+ * by own mutex that is more efficient than the spinlock.
+ *
+ * We define own _spinlock() because a weak referenced _spinlock() stub in
+ * src/lib/libc/gen/_spinlock_stub.c does nothing.
+ */
+
+extern int  __isthreaded;
+
+void _spinlock(ngx_atomic_t *lock)
+{
+    ngx_int_t  tries;
+
+    tries = 0;
+    for ( ;; ) {
+
+        if (*lock) {
+            if (ngx_freebsd_hw_ncpu > 1 && tries++ < 1000) {
+                continue;
+            }
+
+            sched_yield();
+            tries = 0;
+
+        } else {
+            if (ngx_atomic_cmp_set(lock, 0, 1)) {
+                return;
+            }
+        }
+    }
+}
+
+
 int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
                       ngx_log_t *log)
 {
@@ -70,7 +105,8 @@ int ngx_create_thread(ngx_tid_t *tid, in
 
     if (stack == MAP_FAILED) {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                      "mmap(%08X:%d, MAP_STACK) thread stack failed",
+                      "mmap(" PTR_FMT ":" SIZE_T_FMT
+                      ", MAP_STACK) thread stack failed",
                       last_stack, usable_stack_size);
         return NGX_ERROR;
     }
@@ -82,7 +118,7 @@ int ngx_create_thread(ngx_tid_t *tid, in
     stack_top = stack + usable_stack_size;
 
     ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
-                   "thread stack: %08X-%08X", stack, stack_top);
+                   "thread stack: " PTR_FMT "-" PTR_FMT, stack, stack_top);
 
 #if 1
     id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
@@ -113,12 +149,12 @@ int ngx_create_thread(ngx_tid_t *tid, in
 
 ngx_int_t ngx_init_threads(int n, size_t size, ngx_log_t *log)
 {
-    int    len;
-    char  *red_zone, *zone;
+    size_t   len;
+    char    *red_zone, *zone;
 
     max_threads = n;
 
-    len = 4;
+    len = sizeof(usrstack);
     if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                       "sysctlbyname(kern.usrstack) failed");
@@ -129,12 +165,14 @@ ngx_int_t ngx_init_threads(int n, size_t
     red_zone = usrstack - (size + rz_size);
 
     ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
-                   "usrstack: %08X, red zone: %08X", usrstack, red_zone);
+                   "usrstack: " PTR_FMT " red zone: " PTR_FMT,
+                   usrstack, red_zone);
 
     zone = mmap(red_zone, rz_size, PROT_NONE, MAP_ANON, -1, 0);
     if (zone == MAP_FAILED) {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                      "mmap(%08X:%d, PROT_NONE, MAP_ANON) red zone failed",
+                      "mmap(" PTR_FMT ":" SIZE_T_FMT
+                      ", PROT_NONE, MAP_ANON) red zone failed",
                       red_zone, rz_size);
         return NGX_ERROR;
     }
@@ -177,7 +215,15 @@ static inline int ngx_gettid()
         return 0;
     }
 
-    __asm__ ("mov %%esp, %0" : "=q" (sp));
+#if ( __i386__ )
+
+    __asm__ volatile ("mov %%esp, %0" : "=q" (sp));
+
+#elif ( __amd64__ )
+
+    __asm__ volatile ("mov %%rsp, %0" : "=q" (sp));
+
+#endif
 
     return (usrstack - sp) / stack_size;
 }
@@ -258,7 +304,7 @@ void ngx_mutex_done(ngx_mutex_t *m)
                       "semctl(IPC_RMID) failed");
     }
 
-    ngx_free(m);
+    ngx_free((void *) m);
 }
 
 
@@ -271,10 +317,10 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
 #if (NGX_DEBUG)
     if (try) {
         ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
-                       "try lock mutex %08X lock:%X", m, m->lock);
+                       "try lock mutex " PTR_FMT " lock:%X", m, m->lock);
     } else {
         ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
-                       "lock mutex %08X lock:%X", m, m->lock);
+                       "lock mutex " PTR_FMT " lock:%X", m, m->lock);
     }
 #endif
 
@@ -305,7 +351,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
             }
 
             ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
-                           "mutex %08X lock:%X", m, m->lock);
+                           "mutex " PTR_FMT " lock:%X", m, m->lock);
 
             /*
              * The mutex is locked so we increase a number
@@ -316,8 +362,8 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
 
             if ((lock & ~NGX_MUTEX_LOCK_BUSY) > nthreads) {
                 ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
-                              "%d threads wait for mutex %0X, "
-                              "while only %d threads are available",
+                              "%d threads wait for mutex " PTR_FMT
+                              ", while only %d threads are available",
                               lock & ~NGX_MUTEX_LOCK_BUSY, m, nthreads);
                 return NGX_ERROR;
             }
@@ -325,7 +371,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
             if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
 
                 ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
-                               "wait mutex %08X lock:%X", m, m->lock);
+                               "wait mutex " PTR_FMT " lock:%X", m, m->lock);
 
                 /*
                  * The number of the waiting threads has been increased
@@ -341,7 +387,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
                 if (semop(m->semid, &op, 1) == -1) {
                     ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
                                   "semop() failed while waiting "
-                                  "on mutex %08X", m);
+                                  "on mutex " PTR_FMT, m);
                     return NGX_ERROR;
                 }
 
@@ -368,7 +414,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
         if (tries++ > 1000) {
 
             ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
-                           "mutex %08X is contested", m);
+                           "mutex " PTR_FMT " is contested", m);
 
             /* the mutex is probably contested so we are giving up now */
 
@@ -380,7 +426,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t 
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
-                   "mutex %08X is locked, lock:%X", m, m->lock);
+                   "mutex " PTR_FMT " is locked, lock:%X", m, m->lock);
 
     return NGX_OK;
 }
@@ -395,7 +441,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *
 
     if (!(old & NGX_MUTEX_LOCK_BUSY)) {
         ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
-                      "tring to unlock the free mutex %0X", m);
+                      "tring to unlock the free mutex " PTR_FMT, m);
         return NGX_ERROR;
     }
 
@@ -413,7 +459,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *
 
     if (m->semid == -1) {
         ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
-                       "mutex %08X is unlocked", m);
+                       "mutex " PTR_FMT " is unlocked", m);
 
         return NGX_OK;
     }
@@ -448,8 +494,8 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *
 
             if (semop(m->semid, &op, 1) == -1) {
                 ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
-                              "semop() failed while waking up on mutex %08X",
-                              m);
+                              "semop() failed while waking up on mutex "
+                              PTR_FMT, m);
                 return NGX_ERROR;
             }
 
@@ -460,7 +506,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
-                   "mutex %08X is unlocked", m);
+                   "mutex " PTR_FMT " is unlocked", m);
 
     return NGX_OK;
 }