@@ -201,6 +201,7 @@ typedef struct {
201201/* Internal coroutine structure */
202202
203203typedef struct {
204+ uint32_t id ; /* Coroutine identifier */
204205 void (* func )(void * ); /* Entry point function (user-provided) */
205206 void * user_data ; /* User data (hart pointer) */
206207 coro_state_t state ; /* Current state */
@@ -213,7 +214,8 @@ typedef struct {
213214
214215static struct {
215216 coro_t * * coroutines ; /* Array of coroutine pointers */
216- uint32_t n_hart ; /* Number of harts */
217+ uint32_t total_slots ; /* Total number of coroutine slots */
218+ uint32_t hart_slots ; /* Number of slots reserved for harts */
217219 uint32_t current_hart ; /* Currently executing hart ID */
218220 bool initialized ; /* True if subsystem initialized */
219221 coro_t * running ; /* Currently running coroutine */
@@ -376,25 +378,27 @@ static void coro_entry_wrapper(void *arg)
376378
377379/* Public API implementation */
378380
379- bool coro_init (uint32_t n_hart )
381+ bool coro_init (uint32_t total_slots , uint32_t hart_slots )
380382{
381383 if (coro_state .initialized ) {
382384 fprintf (stderr , "coro_init: already initialized\n" );
383385 return false;
384386 }
385387
386- if (n_hart == 0 || n_hart > 32 ) {
387- fprintf (stderr , "coro_init: invalid n_hart=%u\n" , n_hart );
388+ if (total_slots == 0 || total_slots > 256 || hart_slots > total_slots ) {
389+ fprintf (stderr , "coro_init: invalid slots (total=%u, hart=%u)\n" ,
390+ total_slots , hart_slots );
388391 return false;
389392 }
390393
391- coro_state .coroutines = calloc (n_hart , sizeof (coro_t * ));
394+ coro_state .coroutines = calloc (total_slots , sizeof (coro_t * ));
392395 if (!coro_state .coroutines ) {
393396 fprintf (stderr , "coro_init: failed to allocate coroutines array\n" );
394397 return false;
395398 }
396399
397- coro_state .n_hart = n_hart ;
400+ coro_state .total_slots = total_slots ;
401+ coro_state .hart_slots = hart_slots ;
398402 coro_state .current_hart = CORO_HART_ID_IDLE ;
399403 coro_state .initialized = true;
400404 coro_state .running = NULL ;
@@ -407,7 +411,7 @@ void coro_cleanup(void)
407411 if (!coro_state .initialized )
408412 return ;
409413
410- for (uint32_t i = 0 ; i < coro_state .n_hart ; i ++ ) {
414+ for (uint32_t i = 0 ; i < coro_state .total_slots ; i ++ ) {
411415 if (coro_state .coroutines [i ]) {
412416 coro_t * co = coro_state .coroutines [i ];
413417 if (co -> context ) {
@@ -423,22 +427,23 @@ void coro_cleanup(void)
423427
424428 free (coro_state .coroutines );
425429 coro_state .coroutines = NULL ;
426- coro_state .n_hart = 0 ;
430+ coro_state .total_slots = 0 ;
431+ coro_state .hart_slots = 0 ;
427432 coro_state .current_hart = CORO_HART_ID_IDLE ; /* Reset to idle state */
428433 coro_state .initialized = false;
429434 coro_state .running = NULL ;
430435 tls_running_coro = NULL ; /* Reset TLS as well */
431436}
432437
433- bool coro_create_hart (uint32_t hart_id , void (* func )(void * ), void * hart )
438+ bool coro_create_hart (uint32_t slot_id , void (* func )(void * ), void * arg )
434439{
435440 if (!coro_state .initialized ) {
436441 fprintf (stderr , "coro_create_hart: not initialized\n" );
437442 return false;
438443 }
439444
440- if (hart_id >= coro_state .n_hart ) {
441- fprintf (stderr , "coro_create_hart: invalid hart_id =%u\n" , hart_id );
445+ if (slot_id >= coro_state .total_slots ) {
446+ fprintf (stderr , "coro_create_hart: invalid slot_id =%u\n" , slot_id );
442447 return false;
443448 }
444449
@@ -447,9 +452,9 @@ bool coro_create_hart(uint32_t hart_id, void (*func)(void *), void *hart)
447452 return false;
448453 }
449454
450- if (coro_state .coroutines [hart_id ]) {
451- fprintf (stderr , "coro_create_hart: hart %u already has coroutine\n" ,
452- hart_id );
455+ if (coro_state .coroutines [slot_id ]) {
456+ fprintf (stderr , "coro_create_hart: slot %u already has coroutine\n" ,
457+ slot_id );
453458 return false;
454459 }
455460
@@ -461,8 +466,9 @@ bool coro_create_hart(uint32_t hart_id, void (*func)(void *), void *hart)
461466 }
462467
463468 /* Store user function and data */
469+ co -> id = slot_id ;
464470 co -> func = func ;
465- co -> user_data = hart ;
471+ co -> user_data = arg ;
466472 co -> state = CORO_STATE_SUSPENDED ;
467473
468474 /* Allocate context */
@@ -496,31 +502,32 @@ bool coro_create_hart(uint32_t hart_id, void (*func)(void *), void *hart)
496502 }
497503#endif
498504
499- coro_state .coroutines [hart_id ] = co ;
505+ coro_state .coroutines [slot_id ] = co ;
500506 return true;
501507}
502508
503- void coro_resume_hart (uint32_t hart_id )
509+ void coro_resume_hart (uint32_t slot_id )
504510{
505- if (!coro_state .initialized || hart_id >= coro_state .n_hart ) {
506- fprintf (stderr , "coro_resume_hart: invalid hart_id =%u\n" , hart_id );
511+ if (!coro_state .initialized || slot_id >= coro_state .total_slots ) {
512+ fprintf (stderr , "coro_resume_hart: invalid slot_id =%u\n" , slot_id );
507513 return ;
508514 }
509515
510- coro_t * co = coro_state .coroutines [hart_id ];
516+ coro_t * co = coro_state .coroutines [slot_id ];
511517 if (!co || !co -> context ) {
512- fprintf (stderr , "coro_resume_hart: hart %u has no coroutine\n" ,
513- hart_id );
518+ fprintf (stderr , "coro_resume_hart: slot %u has no coroutine\n" ,
519+ slot_id );
514520 return ;
515521 }
516522
517523 if (co -> state != CORO_STATE_SUSPENDED ) {
518- fprintf (stderr , "coro_resume_hart: hart %u not suspended (state=%d)\n" ,
519- hart_id , co -> state );
524+ /* This may happen if a coroutine is waiting on I/O and the main loop
525+ * tries to resume it. It is not a fatal error.
526+ */
520527 return ;
521528 }
522529
523- coro_state .current_hart = hart_id ;
530+ coro_state .current_hart = slot_id ;
524531 co -> state = CORO_STATE_RUNNING ;
525532 jump_into (co );
526533}
@@ -547,12 +554,12 @@ void coro_yield(void)
547554 jump_out (co );
548555}
549556
550- bool coro_is_suspended (uint32_t hart_id )
557+ bool coro_is_suspended (uint32_t slot_id )
551558{
552- if (!coro_state .initialized || hart_id >= coro_state .n_hart )
559+ if (!coro_state .initialized || slot_id >= coro_state .hart_slots )
553560 return false;
554561
555- coro_t * co = coro_state .coroutines [hart_id ];
562+ coro_t * co = coro_state .coroutines [slot_id ];
556563 if (!co || !co -> context )
557564 return false;
558565
0 commit comments