Changeset 5988


Ignore:
Timestamp:
Mar 7, 2007, 6:01:40 AM (18 years ago)
Author:
Gary Byers
Message:

Use spinlocks to guard updates to "real" locks; those updates can
be simplified.

lock_recursive_lock: no (ignored) timeout arg.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/thread_manager.c

    r5613 r5988  
    8787
    8888
     89int spin_lock_tries = 1;
     90
     91void
     92get_spin_lock(signed_natural *p, TCR *tcr)
     93{
     94  int i, n = spin_lock_tries;
     95 
     96  while (1) {
     97    for (i = 0; i < n; i++) {
     98      if (atomic_swap(p,(signed_natural)tcr) == 0) {
     99        return;
     100      }
     101    }
     102    sched_yield();
     103  }
     104}
     105
     106
    89107int
    90 lock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr, struct timespec *waitfor)
     108lock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr)
    91109{
    92110
     
    99117  }
    100118  while (1) {
    101     if (atomic_incf(&m->avail) == 1) {
     119    get_spin_lock(&(m->spinlock),tcr);
     120    ++m->avail;
     121    if (m->avail == 1) {
    102122      m->owner = tcr;
    103123      m->count = 1;
     124      m->spinlock = 0;
    104125      break;
    105126    }
     127    m->spinlock = 0;
    106128    SEM_WAIT_FOREVER(m->signal);
    107129  }
    108130  return 0;
    109131}
     132
    110133 
    111134int
     
    121144    --m->count;
    122145    if (m->count == 0) {
     146      get_spin_lock(&(m->spinlock),tcr);
    123147      m->owner = NULL;
    124       pending = atomic_swap(&m->avail, 0) - 1;
    125       atomic_incf_by(&m->waiting, pending);
    126       /* We're counting on atomic_decf not actually decrementing
    127          the location below 0, but returning a negative result
    128          in that case.
    129       */
    130       if (atomic_decf(&m->waiting) >= 0) {
     148      pending = m->avail-1 + m->waiting;     /* Don't count us */
     149      m->avail = 0;
     150      --pending;
     151      if (pending > 0) {
     152        m->waiting = pending;
     153      } else {
     154        m->waiting = 0;
     155      }
     156      m->spinlock = 0;
     157      if (pending >= 0) {
    131158        SEM_RAISE(m->signal);
    132159      }
    133       ret = 0;
    134     }
     160    }
     161    ret = 0;
    135162  }
    136163  return ret;
     
    800827
    801828void
     829count_cpus()
     830{
     831#ifdef DARWIN
     832  /* As of OSX 10.4, Darwin doesn't define _SC_NPROCESSORS_ONLN */
     833#include <mach/host_info.h>
     834
     835  struct host_basic_info info;
     836  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
     837 
     838  if (KERN_SUCCESS == host_info(mach_host_self(), HOST_BASIC_INFO,(host_info_t)(&info),&count)) {
     839    if (info.max_cpus > 1) {
     840      spin_lock_tries = 1024;
     841    }
     842  }
     843#else
     844  int n = sysconf(_SC_NPROCESSORS_ONLN);
     845 
     846  if (n > 1) {
     847    spin_lock_tries = 1024;
     848  }
     849#endif
     850}
     851
     852void
    802853init_threads(void * stack_base, TCR *tcr)
    803854{
     
    805856  pthread_key_create((pthread_key_t *)&(lisp_global(TCR_KEY)), shutdown_thread_tcr);
    806857  thread_signal_setup();
     858  count_cpus();
    807859  threads_initialized = true;
    808860}
Note: See TracChangeset for help on using the changeset viewer.