Changeset 7547 for branches/working-0710
- Timestamp:
- Oct 29, 2007, 6:50:04 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/working-0710/ccl/lisp-kernel/thread_manager.c
r7527 r7547 38 38 #endif 39 39 40 void 41 log_tcr_initialization(TCR *tcr) { 42 syslog((LOG_USER|LOG_INFO), "created tcr at 0x%lx for thread 0x%lx", tcr, pthread_self()); 43 } 44 45 void 46 log_tcr_access(TCR *tcr) { 47 syslog((LOG_USER|LOG_INFO), "accessed tcr at 0x%lx from thread 0x%lx", tcr, pthread_self()); 48 } 49 50 void 51 log_tcr_exit(TCR *tcr) { 52 syslog((LOG_USER|LOG_INFO), "thread 0x%lx exiting, had tcr 0x%lx", pthread_self(), tcr); 53 } 54 40 55 extern natural 41 56 store_conditional(natural*, natural, natural); … … 44 59 atomic_swap(signed_natural*, signed_natural); 45 60 61 #ifdef USE_FUTEX 62 #define futex_wait(futex,val) syscall(SYS_futex,futex,FUTEX_WAIT,val) 63 #define futex_wake(futex,n) syscall(SYS_futex,futex,FUTEX_WAKE,n) 64 #define FUTEX_AVAIL (0) 65 #define FUTEX_LOCKED (1) 66 #define FUTEX_CONTENDED (2) 67 #endif 46 68 47 69 int … … 87 109 88 110 111 #ifndef USE_FUTEX 89 112 int spin_lock_tries = 1; 90 113 … … 103 126 } 104 127 } 105 106 128 #endif 129 130 #ifndef USE_FUTEX 107 131 int 108 132 lock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr) … … 131 155 } 132 156 133 157 #else /* USE_FUTEX */ 158 159 static void inline 160 lock_futex(natural *p) 161 { 162 163 while (1) { 164 if (store_conditional(p,FUTEX_AVAIL,FUTEX_LOCKED) == FUTEX_AVAIL) { 165 return; 166 } 167 while (1) { 168 if (atomic_swap(p,FUTEX_CONTENDED) == FUTEX_AVAIL) { 169 return; 170 } 171 futex_wait(p,FUTEX_CONTENDED); 172 } 173 } 174 } 175 176 static void inline 177 unlock_futex(natural *p) 178 { 179 if (atomic_decf(p) != FUTEX_AVAIL) { 180 *p = FUTEX_AVAIL; 181 futex_wake(p,INT_MAX); 182 } 183 } 184 185 int 186 lock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr) 187 { 188 natural val; 189 if (tcr == NULL) { 190 tcr = get_tcr(true); 191 } 192 if (m->owner == tcr) { 193 m->count++; 194 return 0; 195 } 196 lock_futex(&m->avail); 197 m->owner = tcr; 198 m->count = 1; 199 return 0; 200 } 201 #endif /* USE_FUTEX */ 202 203 204 #ifndef USE_FUTEX 134 205 int 135 206 unlock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr) … … 163 234 return ret; 164 235 } 236 #else /* USE_FUTEX */ 237 int 238 unlock_recursive_lock(RECURSIVE_LOCK m, TCR *tcr) 239 { 240 int ret = EPERM, pending; 241 242 if (tcr == NULL) { 243 tcr = get_tcr(true); 244 } 245 246 if (m->owner == tcr) { 247 --m->count; 248 if (m->count == 0) { 249 m->owner = NULL; 250 unlock_futex(&m->avail); 251 } 252 ret = 0; 253 } 254 return ret; 255 } 256 #endif /* USE_FUTEX */ 165 257 166 258 void 167 259 destroy_recursive_lock(RECURSIVE_LOCK m) 168 260 { 261 #ifndef USE_FUTEX 169 262 destroy_semaphore((void **)&m->signal); 263 #endif 170 264 postGCfree((void *)(m->malloced_ptr)); 171 265 } … … 177 271 */ 178 272 273 #ifndef USE_FUTEX 179 274 int 180 275 recursive_lock_trylock(RECURSIVE_LOCK m, TCR *tcr, int *was_free) … … 204 299 return EBUSY; 205 300 } 301 #else 302 int 303 recursive_lock_trylock(RECURSIVE_LOCK m, TCR *tcr, int *was_free) 304 { 305 TCR *owner = m->owner; 306 307 if (owner == tcr) { 308 m->count++; 309 if (was_free) { 310 *was_free = 0; 311 return 0; 312 } 313 } 314 if (store_conditional((natural*)&(m->avail), 0, 1) == 0) { 315 m->owner = tcr; 316 m->count = 1; 317 if (was_free) { 318 *was_free = 1; 319 } 320 return 0; 321 } 322 323 return EBUSY; 324 } 325 #endif 206 326 207 327 void … … 425 545 void *p = calloc(1,sizeof(_recursive_lock)+cache_block_size-1); 426 546 RECURSIVE_LOCK m = NULL; 547 #ifndef USE_FUTEX 427 548 void *signal = new_semaphore(0); 549 #endif 428 550 429 551 if (p) { … … 432 554 } 433 555 556 #ifdef USE_FUTEX 557 if (m) { 558 return m; 559 } 560 #else 434 561 if (m && signal) { 435 562 m->signal = signal; … … 442 569 destroy_semaphore(&signal); 443 570 } 571 #endif 444 572 return NULL; 445 573 } … … 696 824 dequeue_tcr(tcr); 697 825 #endif 826 if (log_tcr_info) { 827 log_tcr_exit(tcr); 828 } 698 829 UNLOCK(lisp_global(TCR_AREA_LOCK),tcr); 699 830 if (termination_semaphore) { … … 783 914 #endif 784 915 tcr->log2_allocation_quantum = unbox_fixnum(lisp_global(DEFAULT_ALLOCATION_QUANTUM)); 916 if (log_tcr_info) { 917 log_tcr_initialization(tcr); 918 } 785 919 } 786 920 … … 843 977 Boolean threads_initialized = false; 844 978 979 #ifndef USE_FUTEX 845 980 void 846 981 count_cpus() … … 866 1001 #endif 867 1002 } 1003 #endif 1004 1005 Boolean log_tcr_info = false; 868 1006 869 1007 void … … 873 1011 pthread_key_create((pthread_key_t *)&(lisp_global(TCR_KEY)), shutdown_thread_tcr); 874 1012 thread_signal_setup(); 1013 if (getenv("LOG_TCR_INFO")) { 1014 extern char *real_executable_name; 1015 log_tcr_info = true; 1016 openlog(real_executable_name, LOG_PID, LOG_USER); 1017 } 1018 #ifndef USE_FUTEX 875 1019 count_cpus(); 1020 #endif 876 1021 threads_initialized = true; 877 1022 } … … 1055 1200 1056 1201 } 1057 1202 if (log_tcr_info) { 1203 log_tcr_access(current); 1204 } 1058 1205 return current; 1059 1206 } … … 1363 1510 rw = (rwlock *) ((((natural)p)+cache_block_size-1) & (~(cache_block_size-1))); 1364 1511 rw->malloced_ptr = p; 1512 #ifndef USE_FUTEX 1365 1513 rw->reader_signal = new_semaphore(0); 1366 1514 rw->writer_signal = new_semaphore(0); … … 1374 1522 rw = NULL; 1375 1523 } 1524 #endif 1376 1525 } 1377 1526 return rw; … … 1387 1536 hold read access once. 1388 1537 */ 1538 #ifndef USE_FUTEX 1389 1539 int 1390 1540 rwlock_rlock(rwlock *rw, TCR *tcr, struct timespec *waitfor) … … 1417 1567 return err; 1418 1568 } 1419 1569 #else 1570 int 1571 rwlock_rlock(rwlock *rw, TCR *tcr, struct timespec *waitfor) 1572 { 1573 natural waitval; 1574 1575 lock_futex(&rw->spin); 1576 1577 if (rw->writer == tcr) { 1578 unlock_futex(&rw->spin); 1579 return EDEADLOCK; 1580 } 1581 while (1) { 1582 if (rw->writer == NULL) { 1583 --rw->state; 1584 unlock_futex(&rw->spin); 1585 return 0; 1586 } 1587 rw->blocked_readers++; 1588 waitval = rw->reader_signal; 1589 unlock_futex(&rw->spin); 1590 futex_wait(&rw->reader_signal,waitval); 1591 lock_futex(&rw->spin); 1592 rw->blocked_readers--; 1593 } 1594 return 0; 1595 } 1596 #endif 1420 1597 1421 1598 … … 1430 1607 */ 1431 1608 1609 #ifndef USE_FUTEX 1432 1610 int 1433 1611 rwlock_wlock(rwlock *rw, TCR *tcr, struct timespec *waitfor) … … 1462 1640 } 1463 1641 1642 #else 1643 int 1644 rwlock_wlock(rwlock *rw, TCR *tcr, struct timespec *waitfor) 1645 { 1646 int err = 0; 1647 natural waitval; 1648 1649 lock_futex(&rw->spin); 1650 if (rw->writer == tcr) { 1651 rw->state++; 1652 unlock_futex(&rw->spin); 1653 return 0; 1654 } 1655 1656 while (rw->state != 0) { 1657 rw->blocked_writers++; 1658 waitval = rw->writer_signal; 1659 unlock_futex(&rw->spin); 1660 futex_wait(&rw->writer_signal,waitval); 1661 lock_futex(&rw->spin); 1662 rw->blocked_writers--; 1663 } 1664 rw->state = 1; 1665 rw->writer = tcr; 1666 unlock_futex(&rw->spin); 1667 return err; 1668 } 1669 #endif 1670 1464 1671 /* 1465 1672 Sort of the same as above, only return EBUSY if we'd have to wait. 1466 1673 */ 1674 #ifndef USE_FUTEX 1467 1675 int 1468 1676 rwlock_try_wlock(rwlock *rw, TCR *tcr) … … 1484 1692 return ret; 1485 1693 } 1486 1694 #else 1695 int 1696 rwlock_try_wlock(rwlock *rw, TCR *tcr) 1697 { 1698 int ret = EBUSY; 1699 1700 lock_futex(&rw->spin); 1701 if (rw->writer == tcr) { 1702 rw->state++; 1703 ret = 0; 1704 } else { 1705 if (rw->state == 0) { 1706 rw->writer = tcr; 1707 rw->state = 1; 1708 ret = 0; 1709 } 1710 } 1711 unlock_futex(&rw->spin); 1712 return ret; 1713 } 1714 #endif 1715 1716 #ifndef USE_FUTEX 1487 1717 int 1488 1718 rwlock_try_rlock(rwlock *rw, TCR *tcr) … … 1498 1728 return ret; 1499 1729 } 1500 1501 1502 1730 #else 1731 int 1732 rwlock_try_rlock(rwlock *rw, TCR *tcr) 1733 { 1734 int ret = EBUSY; 1735 1736 lock_futex(&rw->spin); 1737 if (rw->state <= 0) { 1738 --rw->state; 1739 ret = 0; 1740 } 1741 unlock_futex(&rw->spin); 1742 return ret; 1743 } 1744 #endif 1745 1746 1747 1748 #ifndef USE_FUTEX 1503 1749 int 1504 1750 rwlock_unlock(rwlock *rw, TCR *tcr) … … 1514 1760 } else { 1515 1761 --rw->state; 1762 if (rw->state == 0) { 1763 rw->writer = NULL; 1764 } 1516 1765 } 1517 1766 } else { … … 1540 1789 return 0; 1541 1790 } 1791 #else 1792 int 1793 rwlock_unlock(rwlock *rw, TCR *tcr) 1794 { 1795 1796 int err = 0; 1797 1798 lock_futex(&rw->spin); 1799 if (rw->state > 0) { 1800 if (rw->writer != tcr) { 1801 err = EINVAL; 1802 } else { 1803 --rw->state; 1804 if (rw->state == 0) { 1805 rw->writer = NULL; 1806 } 1807 } 1808 } else { 1809 if (rw->state < 0) { 1810 ++rw->state; 1811 } else { 1812 err = EINVAL; 1813 } 1814 } 1815 if (err) { 1816 unlock_futex(&rw->spin); 1817 return err; 1818 } 1819 1820 if (rw->state == 0) { 1821 if (rw->blocked_writers) { 1822 ++rw->writer_signal; 1823 unlock_futex(&rw->spin); 1824 futex_wake(&rw->writer_signal,1); 1825 return 0; 1826 } 1827 if (rw->blocked_readers) { 1828 ++rw->reader_signal; 1829 unlock_futex(&rw->spin); 1830 futex_wake(&rw->reader_signal, INT_MAX); 1831 return 0; 1832 } 1833 } 1834 unlock_futex(&rw->spin); 1835 return 0; 1836 } 1837 #endif 1542 1838 1543 1839 … … 1545 1841 rwlock_destroy(rwlock *rw) 1546 1842 { 1843 #ifndef USE_FUTEX 1547 1844 destroy_semaphore((void **)&rw->reader_signal); 1548 1845 destroy_semaphore((void **)&rw->writer_signal); 1846 #endif 1549 1847 postGCfree((void *)(rw->malloced_ptr)); 1550 1848 }
Note: See TracChangeset
for help on using the changeset viewer.