Exemplo n.º 1
0
static void
ngx_thread_pool_destroy(ngx_thread_pool_t *tp)
{
    ngx_uint_t           n;
    ngx_thread_task_t    task;
    volatile ngx_uint_t  lock;
    ngx_memzero(&task, sizeof(ngx_thread_task_t));
    task.handler = ngx_thread_pool_exit_handler;
    task.ctx = (void *) &lock;
    for (n = 0; n < tp->threads; n++)
    {
        lock = 1;
        if (ngx_thread_task_post(tp, &task) != NGX_OK)
        {
            return;
        }
        while (lock)
        {
            ngx_sched_yield();
        }
        task.event.active = 0;
    }
    (void) ngx_thread_cond_destroy(&tp->cond, tp->log);
    (void) ngx_thread_mutex_destroy(&tp->mtx, tp->log);
}
Exemplo n.º 2
0
void
ngx_rwlock_wlock(ngx_atomic_t *lock)
{
    ngx_uint_t  i, n;

    for ( ;; ) {

        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) {
            return;
        }

        if (ngx_ncpu > 1) {

            for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {

                for (i = 0; i < n; i++) {
                    ngx_cpu_pause();
                }

                if (*lock == 0
                    && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK))
                {
                    return;
                }
            }
        }

        ngx_sched_yield();
    }
}
void ngx_rwlock_reserve_read(ngx_rwlock_t *lock)
{
  #if (NGX_HAVE_ATOMIC_OPS)
  ngx_uint_t i, n;
  
  #if (DISABLE_RWLOCK == 1)
  rwl_lock_mutex(lock);
  return;
  #endif
  
  for(;;) {
    NGX_RWLOCK_MUTEX_COND(lock, (lock->lock != NGX_RWLOCK_WRITE), lock->lock++)
    #if (DEBUG_NGX_RWLOCK == 1)
    ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0, "rwlock %p reserve read read (%i)", lock, lock->lock);
    #endif
    if(ngx_ncpu > 1) {
      for(n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {
        for(i = 0; i < n; i++) {
          ngx_cpu_pause();
        }
        #if (DEBUG_NGX_RWLOCK == 1)
        ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0, "rwlock %p read lock wait", lock);
        #endif
        NGX_RWLOCK_MUTEX_COND(lock, (lock->lock != NGX_RWLOCK_WRITE), lock->lock++)
      }
    }
    ngx_sched_yield();
  }
  #else
  #if (NGX_THREADS)
  #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
  #endif
  #endif
}
static void
ngx_thread_pool_destroy(ngx_thread_pool_t *tp)
{
    ngx_uint_t           n;
    ngx_thread_task_t    task;
    volatile ngx_uint_t  lock;

    ngx_memzero(&task, sizeof(ngx_thread_task_t));

    task.handler = ngx_thread_pool_exit_handler;//任务退出执行函数
    task.ctx = (void *) &lock;//指向传入的参数  

    // 没有赋值task->event.handler  task->event.data   (void) ngx_notify(ngx_thread_pool_handler); 中会不会段错误??? /
    for (n = 0; n < tp->threads; n++) {  //tp中所有的线程池添加该任务  
        lock = 1;

        if (ngx_thread_task_post(tp, &task) != NGX_OK) {
            return;
        }

        while (lock) { //主进程判断如果lock没有改变,就让CPU给其他线程执行,以此等待,相当于pthread_join  
            ngx_sched_yield();
        }

        //只有线程池中的一个线程执行了exit_handler后才能会继续for循环

        task.event.active = 0;
    }

    //此时到这边,所有的线程都已经退出   //条件变量销毁   互斥锁

    (void) ngx_thread_cond_destroy(&tp->cond, tp->log);

    (void) ngx_thread_mutex_destroy(&tp->mtx, tp->log);
}
static void rwl_lock_mutex(ngx_rwlock_t *lock) {
  #if (NGX_HAVE_ATOMIC_OPS)
  ngx_atomic_t  *mutex = &lock->mutex;
  ngx_uint_t i, n;
  for(;;) {
    if(*mutex == 0 && ngx_atomic_cmp_set(mutex, 0, ngx_pid)) {
      return;
    }
    if(ngx_ncpu > 1) {
      for(n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {
        for(i = 0; i < n; i++) {
          ngx_cpu_pause();
        }
        #if (DEBUG_NGX_RWLOCK)
        ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0, "rwlock %p mutex wait", lock);
        #endif
        if(*mutex == 0 && ngx_atomic_cmp_set(mutex, 0, ngx_pid)) {
          return;
        }
      }
    }
    ngx_sched_yield();
  }
  #else
  #if (NGX_THREADS)
  #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
  #endif
  #endif
}
void ngx_rwlock_reserve_write(ngx_rwlock_t * lock) {
  #if (NGX_HAVE_ATOMIC_OPS)
  ngx_uint_t i, n;
  
  #if (DISABLE_RWLOCK == 1)
  rwl_lock_mutex(lock);
  return;
  #endif
  
  for(;;) {
    if(ngx_rwlock_write_check(lock))
      return;
    if(ngx_ncpu > 1) {
      for(n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {
        for(i = 0; i < n; i++) {
          ngx_cpu_pause();
        }
        #if (DEBUG_NGX_RWLOCK == 1)
        ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0, "rwlock %p write lock wait (reserved by %ui)", lock, lock->write_pid);
        #endif
        if(ngx_rwlock_write_check(lock))
          return;
      }
    }
    ngx_sched_yield();
  }
  #else
  #if (NGX_THREADS)
  #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
  #endif
  #endif
}
Exemplo n.º 7
0
void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin)
{

#if (NGX_HAVE_ATOMIC_OPS)

  ngx_uint_t  tries;

  tries = 0;

  for ( ;; ) {

    if (*lock) {
      if (ngx_ncpu > 1 && tries++ < spin) {
        continue;
      }

      ngx_sched_yield();

      tries = 0;

    } else {
      if (ngx_atomic_cmp_set(lock, 0, 1)) {
        return;
      }
    }
  }

#else



#endif

}
Exemplo n.º 8
0
void
ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
{

#if (NGX_HAVE_ATOMIC_OPS)

    ngx_uint_t  i, n;

    for ( ;; ) {

        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
            return;
        }

        if (ngx_ncpu > 1) {

            for (n = 1; n < spin; n <<= 1) {

                for (i = 0; i < n; i++) {
                    ngx_cpu_pause();
                }

                if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
                    return;
                }
            }
        }

        ngx_sched_yield();
    }

#else

#if (NGX_THREADS)

#error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !

#endif

#endif

}
Exemplo n.º 9
0
static void
ngx_wakeup_worker_threads(ngx_cycle_t *cycle)
{
    ngx_int_t   i;
    ngx_uint_t  live;

    for ( ;; ) {

        live = 0;

        for (i = 0; i < ngx_threads_n; i++) {
            if (ngx_threads[i].state < NGX_THREAD_EXIT) {
                if (ngx_cond_signal(ngx_threads[i].cv) == NGX_ERROR) {
                    ngx_threads[i].state = NGX_THREAD_DONE;

                } else {
                    live = 1;
                }
            }

            if (ngx_threads[i].state == NGX_THREAD_EXIT) {
                ngx_thread_join(ngx_threads[i].tid, NULL);
                ngx_threads[i].state = NGX_THREAD_DONE;
            }
        }

        if (live == 0) {
            ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                           "all worker threads are joined");

            /* STUB */
            ngx_done_events(cycle);
            ngx_mutex_destroy(ngx_event_timer_mutex);
            ngx_mutex_destroy(ngx_posted_events_mutex);

            return;
        }

        ngx_sched_yield();
    }
}
Exemplo n.º 10
0
void
ngx_rwlock_rlock(ngx_atomic_t *lock)
{
    ngx_uint_t         i, n;
    ngx_atomic_uint_t  readers;

    for ( ;; ) {
        readers = *lock;

        if (readers != NGX_RWLOCK_WLOCK
            && ngx_atomic_cmp_set(lock, readers, readers + 1))
        {
            return;
        }

        if (ngx_ncpu > 1) {

            for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {

                for (i = 0; i < n; i++) {
                    ngx_cpu_pause();
                }

                readers = *lock;

                if (readers != NGX_RWLOCK_WLOCK
                    && ngx_atomic_cmp_set(lock, readers, readers + 1))
                {
                    return;
                }
            }
        }

        ngx_sched_yield();
    }
}
Exemplo n.º 11
0
void
ngx_shmtx_lock(ngx_shmtx_t *mtx)
{
    ngx_uint_t         i, n;

    ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock");

    for ( ;; ) {

        if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
            return;
        }

        if (ngx_ncpu > 1) {

            for (n = 1; n < mtx->spin; n <<= 1) {

                for (i = 0; i < n; i++) {
                    ngx_cpu_pause();
                }

                if (*mtx->lock == 0
                    && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid))
                {
                    return;
                }
            }
        }

#if (NGX_HAVE_POSIX_SEM)

        if (mtx->semaphore) {
            (void) ngx_atomic_fetch_add(mtx->wait, 1);

            if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
                (void) ngx_atomic_fetch_add(mtx->wait, -1);
                return;
            }

            ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
                           "shmtx wait %uA", *mtx->wait);

            while (sem_wait(&mtx->sem) == -1) {
                ngx_err_t  err;

                err = ngx_errno;

                if (err != NGX_EINTR) {
                    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
                                  "sem_wait() failed while waiting on shmtx");
                    break;
                }
            }

            ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
                           "shmtx awoke");

            continue;
        }

#endif

        ngx_sched_yield();
    }
}