aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp70
1 files changed, 29 insertions, 41 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 6123766..99c5812 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -185,26 +185,26 @@ static bool push_registry_table( lua_State* L, UniqueKey key, bool create)
185 * Add the lane to tracking chain; the ones still running at the end of the 185 * Add the lane to tracking chain; the ones still running at the end of the
186 * whole process will be cancelled. 186 * whole process will be cancelled.
187 */ 187 */
188static void tracking_add( Lane* s) 188static void tracking_add(Lane* s)
189{ 189{
190 190
191 MUTEX_LOCK( &s->U->tracking_cs); 191 s->U->tracking_cs.lock();
192 { 192 {
193 assert( s->tracking_next == nullptr); 193 assert( s->tracking_next == nullptr);
194 194
195 s->tracking_next = s->U->tracking_first; 195 s->tracking_next = s->U->tracking_first;
196 s->U->tracking_first = s; 196 s->U->tracking_first = s;
197 } 197 }
198 MUTEX_UNLOCK( &s->U->tracking_cs); 198 s->U->tracking_cs.unlock();
199} 199}
200 200
201/* 201/*
202 * A free-running lane has ended; remove it from tracking chain 202 * A free-running lane has ended; remove it from tracking chain
203 */ 203 */
204static bool tracking_remove( Lane* s) 204static bool tracking_remove(Lane* s)
205{ 205{
206 bool found{ false }; 206 bool found{ false };
207 MUTEX_LOCK( &s->U->tracking_cs); 207 s->U->tracking_cs.lock();
208 { 208 {
209 // Make sure (within the MUTEX) that we actually are in the chain 209 // Make sure (within the MUTEX) that we actually are in the chain
210 // still (at process exit they will remove us from chain and then 210 // still (at process exit they will remove us from chain and then
@@ -228,7 +228,7 @@ static bool tracking_remove( Lane* s)
228 assert( found); 228 assert( found);
229 } 229 }
230 } 230 }
231 MUTEX_UNLOCK( &s->U->tracking_cs); 231 s->U->tracking_cs.unlock();
232 return found; 232 return found;
233} 233}
234 234
@@ -396,12 +396,12 @@ static int run_finalizers( lua_State* L, int lua_rc)
396 */ 396 */
397static void selfdestruct_add( Lane* s) 397static void selfdestruct_add( Lane* s)
398{ 398{
399 MUTEX_LOCK( &s->U->selfdestruct_cs); 399 s->U->selfdestruct_cs.lock();
400 assert( s->selfdestruct_next == nullptr); 400 assert( s->selfdestruct_next == nullptr);
401 401
402 s->selfdestruct_next = s->U->selfdestruct_first; 402 s->selfdestruct_next = s->U->selfdestruct_first;
403 s->U->selfdestruct_first= s; 403 s->U->selfdestruct_first= s;
404 MUTEX_UNLOCK( &s->U->selfdestruct_cs); 404 s->U->selfdestruct_cs.unlock();
405} 405}
406 406
407/* 407/*
@@ -410,7 +410,7 @@ static void selfdestruct_add( Lane* s)
410static bool selfdestruct_remove( Lane* s) 410static bool selfdestruct_remove( Lane* s)
411{ 411{
412 bool found{ false }; 412 bool found{ false };
413 MUTEX_LOCK( &s->U->selfdestruct_cs); 413 s->U->selfdestruct_cs.lock();
414 { 414 {
415 // Make sure (within the MUTEX) that we actually are in the chain 415 // Make sure (within the MUTEX) that we actually are in the chain
416 // still (at process exit they will remove us from chain and then 416 // still (at process exit they will remove us from chain and then
@@ -436,7 +436,7 @@ static bool selfdestruct_remove( Lane* s)
436 assert( found); 436 assert( found);
437 } 437 }
438 } 438 }
439 MUTEX_UNLOCK( &s->U->selfdestruct_cs); 439 s->U->selfdestruct_cs.unlock();
440 return found; 440 return found;
441} 441}
442 442
@@ -451,7 +451,7 @@ static int selfdestruct_gc( lua_State* L)
451 { 451 {
452 // Signal _all_ still running threads to exit (including the timer thread) 452 // Signal _all_ still running threads to exit (including the timer thread)
453 // 453 //
454 MUTEX_LOCK( &U->selfdestruct_cs); 454 U->selfdestruct_cs.lock();
455 { 455 {
456 Lane* s = U->selfdestruct_first; 456 Lane* s = U->selfdestruct_first;
457 while( s != SELFDESTRUCT_END) 457 while( s != SELFDESTRUCT_END)
@@ -470,7 +470,7 @@ static int selfdestruct_gc( lua_State* L)
470 s = s->selfdestruct_next; 470 s = s->selfdestruct_next;
471 } 471 }
472 } 472 }
473 MUTEX_UNLOCK( &U->selfdestruct_cs); 473 U->selfdestruct_cs.unlock();
474 474
475 // When noticing their cancel, the lanes will remove themselves from 475 // When noticing their cancel, the lanes will remove themselves from
476 // the selfdestruct chain. 476 // the selfdestruct chain.
@@ -497,7 +497,7 @@ static int selfdestruct_gc( lua_State* L)
497 // count the number of cancelled thread that didn't have the time to act yet 497 // count the number of cancelled thread that didn't have the time to act yet
498 int n = 0; 498 int n = 0;
499 double t_now = 0.0; 499 double t_now = 0.0;
500 MUTEX_LOCK( &U->selfdestruct_cs); 500 U->selfdestruct_cs.lock();
501 { 501 {
502 Lane* s = U->selfdestruct_first; 502 Lane* s = U->selfdestruct_first;
503 while( s != SELFDESTRUCT_END) 503 while( s != SELFDESTRUCT_END)
@@ -507,7 +507,7 @@ static int selfdestruct_gc( lua_State* L)
507 s = s->selfdestruct_next; 507 s = s->selfdestruct_next;
508 } 508 }
509 } 509 }
510 MUTEX_UNLOCK( &U->selfdestruct_cs); 510 U->selfdestruct_cs.unlock();
511 // if timeout elapsed, or we know all threads have acted, stop waiting 511 // if timeout elapsed, or we know all threads have acted, stop waiting
512 t_now = now_secs(); 512 t_now = now_secs();
513 if( n == 0 || (t_now >= t_until)) 513 if( n == 0 || (t_now >= t_until))
@@ -535,7 +535,7 @@ static int selfdestruct_gc( lua_State* L)
535 // first thing we did was to raise the linda signals the threads were waiting on (if any) 535 // first thing we did was to raise the linda signals the threads were waiting on (if any)
536 // therefore, any well-behaved thread should be in CANCELLED state 536 // therefore, any well-behaved thread should be in CANCELLED state
537 // these are not running, and the state can be closed 537 // these are not running, and the state can be closed
538 MUTEX_LOCK( &U->selfdestruct_cs); 538 U->selfdestruct_cs.lock();
539 { 539 {
540 Lane* s = U->selfdestruct_first; 540 Lane* s = U->selfdestruct_first;
541 while( s != SELFDESTRUCT_END) 541 while( s != SELFDESTRUCT_END)
@@ -557,7 +557,7 @@ static int selfdestruct_gc( lua_State* L)
557 } 557 }
558 U->selfdestruct_first = SELFDESTRUCT_END; 558 U->selfdestruct_first = SELFDESTRUCT_END;
559 } 559 }
560 MUTEX_UNLOCK( &U->selfdestruct_cs); 560 U->selfdestruct_cs.unlock();
561 561
562 DEBUGSPEW_CODE( fprintf( stderr, "Killed %d lane(s) at process end.\n", n)); 562 DEBUGSPEW_CODE( fprintf( stderr, "Killed %d lane(s) at process end.\n", n));
563 } 563 }
@@ -575,7 +575,8 @@ static int selfdestruct_gc( lua_State* L)
575 // no need to mutex-protect this as all threads in the universe are gone at that point 575 // no need to mutex-protect this as all threads in the universe are gone at that point
576 if( U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer 576 if( U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer
577 { 577 {
578 -- U->timer_deep->refcount; // should be 0 now 578 int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) };
579 ASSERT_L(prev_ref_count == 1); // this should be the last reference
579 free_deep_prelude( L, (DeepPrelude*) U->timer_deep); 580 free_deep_prelude( L, (DeepPrelude*) U->timer_deep);
580 U->timer_deep = nullptr; 581 U->timer_deep = nullptr;
581 } 582 }
@@ -585,15 +586,8 @@ static int selfdestruct_gc( lua_State* L)
585 // remove the protected allocator, if any 586 // remove the protected allocator, if any
586 cleanup_allocator_function( U, L); 587 cleanup_allocator_function( U, L);
587 588
588#if HAVE_LANE_TRACKING() 589 U->Universe::~Universe();
589 MUTEX_FREE( &U->tracking_cs); 590
590#endif // HAVE_LANE_TRACKING()
591 // Linked chains handling
592 MUTEX_FREE( &U->selfdestruct_cs);
593 MUTEX_FREE( &U->require_cs);
594 // Locks for 'tools.c' inc/dec counters
595 MUTEX_FREE( &U->deep_lock);
596 MUTEX_FREE( &U->mtid_lock);
597 // universe is no longer available (nor necessary) 591 // universe is no longer available (nor necessary)
598 // we need to do this in case some deep userdata objects were created before Lanes was initialized, 592 // we need to do this in case some deep userdata objects were created before Lanes was initialized,
599 // as potentially they will be garbage collected after Lanes at application shutdown 593 // as potentially they will be garbage collected after Lanes at application shutdown
@@ -950,10 +944,10 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void* vs)
950 // 944 //
951 lua_close( s->L); 945 lua_close( s->L);
952 946
953 MUTEX_LOCK( &s->U->selfdestruct_cs); 947 s->U->selfdestruct_cs.lock();
954 // done with lua_close(), terminal shutdown sequence may proceed 948 // done with lua_close(), terminal shutdown sequence may proceed
955 -- s->U->selfdestructing_count; 949 -- s->U->selfdestructing_count;
956 MUTEX_UNLOCK( &s->U->selfdestruct_cs); 950 s->U->selfdestruct_cs.unlock();
957 951
958 lane_cleanup( s); // s is freed at this point 952 lane_cleanup( s); // s is freed at this point
959 } 953 }
@@ -1665,7 +1659,7 @@ LUAG_FUNC( threads)
1665 1659
1666 // List _all_ still running threads 1660 // List _all_ still running threads
1667 // 1661 //
1668 MUTEX_LOCK( &U->tracking_cs); 1662 U->tracking_cs.lock();
1669 if( U->tracking_first && U->tracking_first != TRACKING_END) 1663 if( U->tracking_first && U->tracking_first != TRACKING_END)
1670 { 1664 {
1671 Lane* s = U->tracking_first; 1665 Lane* s = U->tracking_first;
@@ -1683,7 +1677,7 @@ LUAG_FUNC( threads)
1683 s = s->tracking_next; 1677 s = s->tracking_next;
1684 } 1678 }
1685 } 1679 }
1686 MUTEX_UNLOCK( &U->tracking_cs); 1680 U->tracking_cs.unlock();
1687 return lua_gettop( L) - top; // 0 or 1 1681 return lua_gettop( L) - top; // 0 or 1
1688} 1682}
1689#endif // HAVE_LANE_TRACKING() 1683#endif // HAVE_LANE_TRACKING()
@@ -1863,12 +1857,12 @@ LUAG_FUNC( configure)
1863#endif // THREADAPI == THREADAPI_PTHREAD 1857#endif // THREADAPI == THREADAPI_PTHREAD
1864 1858
1865 STACK_GROW( L, 4); 1859 STACK_GROW( L, 4);
1866 STACK_CHECK_START_ABS( L, 1); // settings 1860 STACK_CHECK_START_ABS( L, 1); // settings
1867 1861
1868 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); 1862 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L));
1869 DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); 1863 DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth);
1870 1864
1871 if( U == nullptr) 1865 if(U == nullptr)
1872 { 1866 {
1873 U = universe_create( L); // settings universe 1867 U = universe_create( L); // settings universe
1874 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1868 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
@@ -1885,17 +1879,11 @@ LUAG_FUNC( configure)
1885 U->demoteFullUserdata = lua_toboolean( L, -1) ? true : false; 1879 U->demoteFullUserdata = lua_toboolean( L, -1) ? true : false;
1886 lua_pop( L, 1); // settings 1880 lua_pop( L, 1); // settings
1887#if HAVE_LANE_TRACKING() 1881#if HAVE_LANE_TRACKING()
1888 MUTEX_INIT( &U->tracking_cs);
1889 lua_getfield( L, 1, "track_lanes"); // settings track_lanes 1882 lua_getfield( L, 1, "track_lanes"); // settings track_lanes
1890 U->tracking_first = lua_toboolean( L, -1) ? TRACKING_END : nullptr; 1883 U->tracking_first = lua_toboolean( L, -1) ? TRACKING_END : nullptr;
1891 lua_pop( L, 1); // settings 1884 lua_pop( L, 1); // settings
1892#endif // HAVE_LANE_TRACKING() 1885#endif // HAVE_LANE_TRACKING()
1893 // Linked chains handling 1886 // Linked chains handling
1894 MUTEX_INIT( &U->selfdestruct_cs);
1895 MUTEX_RECURSIVE_INIT( &U->require_cs);
1896 // Locks for 'tools.c' inc/dec counters
1897 MUTEX_INIT( &U->deep_lock);
1898 MUTEX_INIT( &U->mtid_lock);
1899 U->selfdestruct_first = SELFDESTRUCT_END; 1887 U->selfdestruct_first = SELFDESTRUCT_END;
1900 initialize_allocator_function( U, L); 1888 initialize_allocator_function( U, L);
1901 initialize_on_state_create( U, L); 1889 initialize_on_state_create( U, L);
@@ -1908,10 +1896,10 @@ LUAG_FUNC( configure)
1908 lua_call( L, 1, 1); // settings linda 1896 lua_call( L, 1, 1); // settings linda
1909 STACK_CHECK( L, 2); 1897 STACK_CHECK( L, 2);
1910 1898
1911 // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer 1899 // Proxy userdata contents is only a 'DeepPrelude*' pointer
1912 U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); 1900 U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1);
1913 // increment refcount so that this linda remains alive as long as the universe exists. 1901 // increment refcount so that this linda remains alive as long as the universe exists.
1914 ++ U->timer_deep->refcount; 1902 U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed);
1915 lua_pop( L, 1); // settings 1903 lua_pop( L, 1); // settings
1916 } 1904 }
1917 STACK_CHECK( L, 1); 1905 STACK_CHECK( L, 1);
@@ -1938,7 +1926,7 @@ LUAG_FUNC( configure)
1938 1926
1939 { 1927 {
1940 char const* errmsg; 1928 char const* errmsg;
1941 errmsg = push_deep_proxy( U, L, (DeepPrelude*) U->timer_deep, 0, eLM_LaneBody); // settings M timer_deep 1929 errmsg = push_deep_proxy(L, (DeepPrelude*) U->timer_deep, 0, eLM_LaneBody); // settings M timer_deep
1942 if( errmsg != nullptr) 1930 if( errmsg != nullptr)
1943 { 1931 {
1944 return luaL_error( L, errmsg); 1932 return luaL_error( L, errmsg);