@@ -361,121 +361,144 @@ aco_t* aco_create(
361361}
362362
363363aco_attr_no_asan
364- void aco_resume (aco_t * resume_co ){
365- assert ( resume_co != NULL && resume_co -> main_co != NULL
366- && resume_co -> is_end == 0
367- );
368- if ( resume_co -> share_stack -> owner != resume_co ){
369- if (resume_co -> share_stack -> owner != NULL ){
370- aco_t * owner_co = resume_co -> share_stack -> owner ;
371- assert (owner_co -> share_stack == resume_co -> share_stack );
364+ static void aco_own_stack (aco_t * co ){
365+ if ( co -> share_stack -> owner == co ){
366+ return ;
367+ }
368+
369+ if (co -> share_stack -> owner != NULL ){
370+ aco_t * owner_co = co -> share_stack -> owner ;
371+ assert (owner_co -> share_stack == co -> share_stack );
372372#if defined(__i386__ ) || defined(__x86_64__ )
373- assert (
374- (
375- (uintptr_t )(owner_co -> share_stack -> align_retptr )
376- >=
377- (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ])
378- )
379- &&
380- (
381- (uintptr_t )(owner_co -> share_stack -> align_highptr )
382- -
383- (uintptr_t )(owner_co -> share_stack -> align_limit )
384- <=
385- (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ])
386- )
387- );
388- owner_co -> save_stack .valid_sz =
373+ assert (
374+ (
389375 (uintptr_t )(owner_co -> share_stack -> align_retptr )
376+ >=
377+ (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ])
378+ )
379+ &&
380+ (
381+ (uintptr_t )(owner_co -> share_stack -> align_highptr )
390382 -
391- (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ]);
392- if (owner_co -> save_stack .sz < owner_co -> save_stack .valid_sz ){
393- free (owner_co -> save_stack .ptr );
394- owner_co -> save_stack .ptr = NULL ;
395- while (1 ){
396- owner_co -> save_stack .sz = owner_co -> save_stack .sz << 1 ;
397- assert (owner_co -> save_stack .sz > 0 );
398- if (owner_co -> save_stack .sz >= owner_co -> save_stack .valid_sz ){
399- break ;
400- }
383+ (uintptr_t )(owner_co -> share_stack -> align_limit )
384+ <=
385+ (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ])
386+ )
387+ );
388+ owner_co -> save_stack .valid_sz =
389+ (uintptr_t )(owner_co -> share_stack -> align_retptr )
390+ -
391+ (uintptr_t )(owner_co -> reg [ACO_REG_IDX_SP ]);
392+ if (owner_co -> save_stack .sz < owner_co -> save_stack .valid_sz ){
393+ free (owner_co -> save_stack .ptr );
394+ owner_co -> save_stack .ptr = NULL ;
395+ while (1 ){
396+ owner_co -> save_stack .sz = owner_co -> save_stack .sz << 1 ;
397+ assert (owner_co -> save_stack .sz > 0 );
398+ if (owner_co -> save_stack .sz >= owner_co -> save_stack .valid_sz ){
399+ break ;
401400 }
402- owner_co -> save_stack .ptr = malloc (owner_co -> save_stack .sz );
403- assertalloc_ptr (owner_co -> save_stack .ptr );
404401 }
405- // TODO: optimize the performance penalty of memcpy function call
406- // for very short memory span
407- if (owner_co -> save_stack .valid_sz > 0 ) {
408- #ifdef __x86_64__
409- aco_amd64_optimized_memcpy_drop_in (
410- owner_co -> save_stack .ptr ,
411- owner_co -> reg [ACO_REG_IDX_SP ],
412- owner_co -> save_stack .valid_sz
413- );
414- #else
415- memcpy (
416- owner_co -> save_stack .ptr ,
417- owner_co -> reg [ACO_REG_IDX_SP ],
418- owner_co -> save_stack .valid_sz
419- );
420- #endif
421- owner_co -> save_stack .ct_save ++ ;
422- }
423- if (owner_co -> save_stack .valid_sz > owner_co -> save_stack .max_cpsz ){
424- owner_co -> save_stack .max_cpsz = owner_co -> save_stack .valid_sz ;
425- }
426- owner_co -> share_stack -> owner = NULL ;
427- owner_co -> share_stack -> align_validsz = 0 ;
428- #else
429- #error "platform no support yet"
430- #endif
402+ owner_co -> save_stack .ptr = malloc (owner_co -> save_stack .sz );
403+ assertalloc_ptr (owner_co -> save_stack .ptr );
431404 }
432- assert (resume_co -> share_stack -> owner == NULL );
433- #if defined(__i386__ ) || defined(__x86_64__ )
434- assert (
435- resume_co -> save_stack .valid_sz
436- <=
437- resume_co -> share_stack -> align_limit - sizeof (void * )
438- );
439405 // TODO: optimize the performance penalty of memcpy function call
440406 // for very short memory span
441- if (resume_co -> save_stack .valid_sz > 0 ) {
442- #ifdef __x86_64__
407+ if (owner_co -> save_stack .valid_sz > 0 ) {
408+ #ifdef __x86_64__
443409 aco_amd64_optimized_memcpy_drop_in (
444- (void * )(
445- (uintptr_t )(resume_co -> share_stack -> align_retptr )
446- -
447- resume_co -> save_stack .valid_sz
448- ),
449- resume_co -> save_stack .ptr ,
450- resume_co -> save_stack .valid_sz
410+ owner_co -> save_stack .ptr ,
411+ owner_co -> reg [ACO_REG_IDX_SP ],
412+ owner_co -> save_stack .valid_sz
451413 );
452- #else
414+ #else
453415 memcpy (
454- (void * )(
455- (uintptr_t )(resume_co -> share_stack -> align_retptr )
456- -
457- resume_co -> save_stack .valid_sz
458- ),
459- resume_co -> save_stack .ptr ,
460- resume_co -> save_stack .valid_sz
416+ owner_co -> save_stack .ptr ,
417+ owner_co -> reg [ACO_REG_IDX_SP ],
418+ owner_co -> save_stack .valid_sz
461419 );
462- #endif
463- resume_co -> save_stack .ct_restore ++ ;
420+ #endif
421+ owner_co -> save_stack .ct_save ++ ;
464422 }
465- if (resume_co -> save_stack .valid_sz > resume_co -> save_stack .max_cpsz ){
466- resume_co -> save_stack .max_cpsz = resume_co -> save_stack .valid_sz ;
423+ if (owner_co -> save_stack .valid_sz > owner_co -> save_stack .max_cpsz ){
424+ owner_co -> save_stack .max_cpsz = owner_co -> save_stack .valid_sz ;
467425 }
468- resume_co -> share_stack -> align_validsz = resume_co -> save_stack . valid_sz + sizeof ( void * ) ;
469- resume_co -> share_stack -> owner = resume_co ;
426+ owner_co -> share_stack -> owner = NULL ;
427+ owner_co -> share_stack -> align_validsz = 0 ;
470428#else
471429 #error "platform no support yet"
472430#endif
473431 }
432+ assert (co -> share_stack -> owner == NULL );
433+ #if defined(__i386__ ) || defined(__x86_64__ )
434+ assert (
435+ co -> save_stack .valid_sz
436+ <=
437+ co -> share_stack -> align_limit - sizeof (void * )
438+ );
439+ // TODO: optimize the performance penalty of memcpy function call
440+ // for very short memory span
441+ if (co -> save_stack .valid_sz > 0 ) {
442+ #ifdef __x86_64__
443+ aco_amd64_optimized_memcpy_drop_in (
444+ (void * )(
445+ (uintptr_t )(co -> share_stack -> align_retptr )
446+ -
447+ co -> save_stack .valid_sz
448+ ),
449+ co -> save_stack .ptr ,
450+ co -> save_stack .valid_sz
451+ );
452+ #else
453+ memcpy (
454+ (void * )(
455+ (uintptr_t )(co -> share_stack -> align_retptr )
456+ -
457+ co -> save_stack .valid_sz
458+ ),
459+ co -> save_stack .ptr ,
460+ co -> save_stack .valid_sz
461+ );
462+ #endif
463+ co -> save_stack .ct_restore ++ ;
464+ }
465+ if (co -> save_stack .valid_sz > co -> save_stack .max_cpsz ){
466+ co -> save_stack .max_cpsz = co -> save_stack .valid_sz ;
467+ }
468+ co -> share_stack -> align_validsz = co -> save_stack .valid_sz + sizeof (void * );
469+ co -> share_stack -> owner = co ;
470+ #else
471+ #error "platform no support yet"
472+ #endif
473+ }
474+
475+ aco_attr_no_asan
476+ void aco_resume (aco_t * resume_co ){
477+ assert (resume_co != NULL && resume_co -> main_co != NULL
478+ && resume_co -> is_end == 0
479+ );
480+ aco_own_stack (resume_co );
474481 aco_gtls_co = resume_co ;
475482 acosw (resume_co -> main_co , resume_co );
476483 aco_gtls_co = resume_co -> main_co ;
477484}
478485
486+ aco_attr_no_asan
487+ void aco_yield_to (aco_t * resume_co ){
488+ assert (resume_co != NULL && resume_co -> main_co != NULL
489+ && resume_co -> is_end == 0
490+ );
491+ if (aco_unlikely (resume_co == aco_gtls_co )){
492+ // Nothing to do
493+ return ;
494+ }
495+ assert (resume_co -> main_co == aco_gtls_co -> main_co );
496+ aco_own_stack (resume_co );
497+ aco_t * yield_co = aco_gtls_co ;
498+ aco_gtls_co = resume_co ;
499+ acosw (yield_co , resume_co );
500+ }
501+
479502void aco_destroy (aco_t * co ){
480503 assertptr (co );
481504 if (aco_is_main_co (co )){
0 commit comments