diff options
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r-- | src/lanes.cpp | 70 |
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 | */ |
188 | static void tracking_add( Lane* s) | 188 | static 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 | */ |
204 | static bool tracking_remove( Lane* s) | 204 | static 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 | */ |
397 | static void selfdestruct_add( Lane* s) | 397 | static 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) | |||
410 | static bool selfdestruct_remove( Lane* s) | 410 | static 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); |