mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 5e22f873ed
			
		
	
	
		5e22f873ed
		
	
	
	
	
		
			
			Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.
We take the following inclusion order in this changeset:
1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.
Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
		
	
			
		
			
				
	
	
		
			51 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <assert.h>
 | |
| #include <stddef.h>
 | |
| #include <stdint.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #define COROUTINE __attribute__((noreturn)) void
 | |
| 
 | |
| enum {
 | |
|   COROUTINE_REGISTERS =
 | |
|   19  /* 18 general purpose registers (r14-r31) and 1 return address */
 | |
|   + 4  /* space for fiber_entry() to store the link register */
 | |
| };
 | |
| 
 | |
| struct coroutine_context
 | |
| {
 | |
|     void **stack_pointer;
 | |
| };
 | |
| 
 | |
| typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
 | |
| 
 | |
| static inline void coroutine_initialize_main(struct coroutine_context * context) {
 | |
|     context->stack_pointer = NULL;
 | |
| }
 | |
| 
 | |
| static inline void coroutine_initialize(
 | |
|     struct coroutine_context *context,
 | |
|     coroutine_start start,
 | |
|     void *stack,
 | |
|     size_t size
 | |
| ) {
 | |
|     assert(start && stack && size >= 1024);
 | |
| 
 | |
|     // Stack grows down. Force 16-byte alignment.
 | |
|     char * top = (char*)stack + size;
 | |
|     context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
 | |
| 
 | |
|     context->stack_pointer -= COROUTINE_REGISTERS;
 | |
|     memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
 | |
| 
 | |
|     /* Skip a global prologue that sets the TOC register */
 | |
|     context->stack_pointer[18] = ((char*)start) + 8;
 | |
| }
 | |
| 
 | |
| struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
 | |
| 
 | |
| static inline void coroutine_destroy(struct coroutine_context * context)
 | |
| {
 | |
|     context->stack_pointer = NULL;
 | |
| }
 |