added the new process primitive to create a process with a block as if it has got the value message
This commit is contained in:
		
							
								
								
									
										135
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							| @ -119,17 +119,17 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c) | ||||
|  | ||||
| static void switch_process (stix_t* stix, stix_oop_process_t proc) | ||||
| { | ||||
| 	if (stix->scheduler->active != proc) | ||||
| 	if (stix->processor->active != proc) | ||||
| 	{ | ||||
| printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context); | ||||
|  | ||||
| /* store the active context to the active process */ | ||||
| stix->scheduler->active->active_context = stix->active_context; | ||||
| stix->processor->active->active_context = stix->active_context; | ||||
|  | ||||
| 		SWITCH_ACTIVE_CONTEXT (stix, proc->active_context); | ||||
| printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context); | ||||
| 		/*TODO: set the state to RUNNING */ | ||||
| 		stix->scheduler->active = proc; | ||||
| 		stix->processor->active = proc; | ||||
|  | ||||
| 	} | ||||
| } | ||||
| @ -137,13 +137,13 @@ printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_con | ||||
| static void switch_to_next_process (stix_t* stix) | ||||
| { | ||||
| /* TODO: this is experimental. rewrite it */ | ||||
| 	if (stix->scheduler->active->next == stix->_nil) | ||||
| 	if (stix->processor->active->next == stix->_nil) | ||||
| 	{ | ||||
| 		switch_process (stix, stix->scheduler->head); | ||||
| 		switch_process (stix, stix->processor->head); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		switch_process (stix, stix->scheduler->active->next); | ||||
| 		switch_process (stix, stix->processor->active->next); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -155,21 +155,21 @@ static void schedule_process (stix_t* stix, stix_oop_process_t proc) | ||||
| 		STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil); | ||||
| 		STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil); | ||||
|  | ||||
| 		tally = STIX_OOP_TO_SMINT(stix->scheduler->tally); | ||||
| 		tally = STIX_OOP_TO_SMINT(stix->processor->tally); | ||||
| 		if (tally <= 0) | ||||
| 		{ | ||||
| 			stix->scheduler->head = proc; | ||||
| 			stix->scheduler->tail = proc; | ||||
| 			stix->scheduler->tally  = STIX_OOP_FROM_SMINT(1); | ||||
| 			stix->processor->head = proc; | ||||
| 			stix->processor->tail = proc; | ||||
| 			stix->processor->tally  = STIX_OOP_FROM_SMINT(1); | ||||
| printf ("ADD NEW PROCESS X - %d\n", (int)1); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* TODO: over flow check or maximum number of process check using the tally field? */ | ||||
| 			proc->next = stix->scheduler->head; | ||||
| 			stix->scheduler->head->prev = proc; | ||||
| 			stix->scheduler->head = proc; | ||||
| 			stix->scheduler->tally = STIX_OOP_FROM_SMINT(tally + 1); | ||||
| 			proc->next = stix->processor->head; | ||||
| 			stix->processor->head->prev = proc; | ||||
| 			stix->processor->head = proc; | ||||
| 			stix->processor->tally = STIX_OOP_FROM_SMINT(tally + 1); | ||||
| printf ("ADD NEW PROCESS Y - %d\n", (int)tally + 1); | ||||
| 		} | ||||
|  | ||||
| @ -178,7 +178,7 @@ printf ("ADD NEW PROCESS Y - %d\n", (int)tally + 1); | ||||
|  | ||||
| 		switch_process (stix, proc); | ||||
| 	} | ||||
| 	else if (stix->scheduler->active != proc) | ||||
| 	else if (stix->processor->active != proc) | ||||
| 	{ | ||||
| 		switch_process (stix, proc); | ||||
| 	} | ||||
| @ -775,10 +775,14 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_block_value (stix_t* stix, stix_ooi_t nargs) | ||||
| static int __block_value (stix_t* stix, stix_ooi_t nargs, stix_ooi_t num_first_arg_elems, stix_oop_context_t* pblkctx) | ||||
| { | ||||
| 	stix_oop_context_t blkctx, org_blkctx; | ||||
| 	stix_ooi_t local_ntmprs, i; | ||||
| 	stix_ooi_t actual_arg_count; | ||||
|  | ||||
|  | ||||
| 	actual_arg_count = (num_first_arg_elems > 0)? num_first_arg_elems: nargs; | ||||
|  | ||||
| 	/* TODO: find a better way to support a reentrant block context. */ | ||||
|  | ||||
| @ -814,7 +818,7 @@ printf ("PRIM REVALUING AN BLOCKCONTEXT\n"); | ||||
| 	} | ||||
| 	STIX_ASSERT (STIX_OBJ_GET_SIZE(org_blkctx) == STIX_CONTEXT_NAMED_INSTVARS); | ||||
|  | ||||
| 	if (STIX_OOP_TO_SMINT(org_blkctx->method_or_nargs) != nargs)  | ||||
| 	if (STIX_OOP_TO_SMINT(org_blkctx->method_or_nargs) != actual_arg_count /* nargs */) | ||||
| 	{ | ||||
| 		/* the number of argument doesn't match */ | ||||
| #if defined(STIX_DEBUG_EXEC) | ||||
| @ -851,12 +855,28 @@ printf ("~~~~~~~~~~ BLOCK VALUING %p TO NEW BLOCK %p\n", org_blkctx, blkctx); | ||||
| #endif | ||||
|  | ||||
| /* TODO: check the stack size of a block context to see if it's large enough to hold arguments */ | ||||
| 	/* copy the arguments to the stack */ | ||||
| 	for (i = 0; i < nargs; i++) | ||||
| 	if (num_first_arg_elems > 0) | ||||
| 	{ | ||||
| 		blkctx->slot[i] = ACTIVE_STACK_GET(stix, stix->sp - nargs + i + 1); | ||||
| 		stix_oop_oop_t xarg; | ||||
| 		STIX_ASSERT (nargs == 1); | ||||
| 		xarg = (stix_oop_oop_t)ACTIVE_STACK_GETTOP (stix); | ||||
| 		STIX_ASSERT (STIX_ISTYPEOF(stix,xarg,STIX_OBJ_TYPE_OOP));  | ||||
| 		STIX_ASSERT (STIX_OBJ_GET_SIZE(xarg) == num_first_arg_elems);  | ||||
| 		for (i = 0; i < num_first_arg_elems; i++) | ||||
| 		{ | ||||
| 			blkctx->slot[i] = xarg->slot[i]; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* copy the arguments to the stack */ | ||||
| 		for (i = 0; i < nargs; i++) | ||||
| 		{ | ||||
| 			blkctx->slot[i] = ACTIVE_STACK_GET(stix, stix->sp - nargs + i + 1); | ||||
| 		} | ||||
| 	} | ||||
| 	ACTIVE_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */ | ||||
| 	 | ||||
|  | ||||
| 	STIX_ASSERT (blkctx->home != stix->_nil); | ||||
|  | ||||
| @ -870,6 +890,18 @@ printf ("~~~~~~~~~~ BLOCK VALUING %p TO NEW BLOCK %p\n", org_blkctx, blkctx); | ||||
| 	blkctx->sp = STIX_OOP_FROM_SMINT(local_ntmprs); | ||||
| 	blkctx->sender = (stix_oop_t)stix->active_context; | ||||
|  | ||||
| 	*pblkctx = blkctx; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_block_value (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	int x; | ||||
| 	stix_oop_context_t blkctx; | ||||
|  | ||||
| 	x = __block_value (stix, nargs, 0, &blkctx); | ||||
| 	if (x <= 0) return x; /* hard failure and soft failure */ | ||||
|  | ||||
| #if defined(STIX_DEBUG_EXEC) | ||||
| printf ("<<ENTERING BLOCK>>\n"); | ||||
| #endif | ||||
| @ -879,6 +911,45 @@ printf ("<<ENTERING BLOCK>>\n"); | ||||
|  | ||||
| static int prim_block_new_process (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	int x; | ||||
| 	stix_oop_context_t blkctx; | ||||
| 	stix_oop_process_t proc; | ||||
| 	stix_ooi_t num_first_arg_elems = 0; | ||||
|  | ||||
| 	if (nargs > 1) | ||||
| 	{ | ||||
| 		/* too many arguments */ | ||||
| /* TODO: proper error handling */ | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (nargs == 1) | ||||
| 	{ | ||||
| 		stix_oop_oop_t xarg; | ||||
|  | ||||
| 		xarg = ACTIVE_STACK_GETTOP(stix); | ||||
| 		if (!STIX_ISTYPEOF(stix,xarg,STIX_OBJ_TYPE_OOP)) | ||||
| 		{ | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		num_first_arg_elems = STIX_OBJ_GET_SIZE(xarg); | ||||
| 	} | ||||
|  | ||||
| 	/* this primitive creates a new process with a block as if the block | ||||
| 	 * is sent the value message */ | ||||
| 	x = __block_value (stix, nargs, num_first_arg_elems, &blkctx); | ||||
| 	if (x <= 0) return x; /* hard failure and soft failure */ | ||||
|  | ||||
| 	proc = make_process (stix, blkctx); | ||||
| 	if (!proc) return -1; /* hard failure */ /* TOOD: can't this be a soft failure? */ | ||||
|  | ||||
| 	/* __block_value() has popped all arguments and the receiver.  | ||||
| 	 * PUSH the return value instead of changing the stack top */ | ||||
| 	ACTIVE_STACK_PUSH (stix, (stix_oop_t)proc); | ||||
| 	return 1; | ||||
|  | ||||
| #if 0 | ||||
| 	stix_oop_process_t proc; | ||||
| 	stix_oop_context_t rcv; | ||||
|  | ||||
| @ -896,6 +967,7 @@ printf ("PRIMITVE VALUE RECEIVER IS NOT A BLOCK CONTEXT\n"); | ||||
|  | ||||
| 	ACTIVE_STACK_SETTOP (stix, (stix_oop_t)proc); | ||||
| 	return 1; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int prim_integer_add (stix_t* stix, stix_ooi_t nargs) | ||||
| @ -1137,7 +1209,7 @@ static int prim_integer_ge (stix_t* stix, stix_ooi_t nargs) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int prim_scheduler_add (stix_t* stix, stix_ooi_t nargs) | ||||
| static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	stix_oop_t rcv, arg; | ||||
|  | ||||
| @ -1146,7 +1218,7 @@ static int prim_scheduler_add (stix_t* stix, stix_ooi_t nargs) | ||||
| 	rcv = ACTIVE_STACK_GET(stix, stix->sp - 1); | ||||
| 	arg = ACTIVE_STACK_GET(stix, stix->sp); | ||||
|  | ||||
| 	if (rcv != (stix_oop_t)stix->scheduler || STIX_CLASSOF(stix,arg) != stix->_process) | ||||
| 	if (rcv != (stix_oop_t)stix->processor || STIX_CLASSOF(stix,arg) != stix->_process) | ||||
| 	{ | ||||
| 		return 0; | ||||
| 	} | ||||
| @ -1155,7 +1227,13 @@ static int prim_scheduler_add (stix_t* stix, stix_ooi_t nargs) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_scheduler_remove (stix_t* stix, stix_ooi_t nargs) | ||||
| static int prim_processor_remove (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| /* TODO: */ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int prim_processor_sleep (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| /* TODO: */ | ||||
| 	return 0; | ||||
| @ -1460,7 +1538,7 @@ static prim_t primitives[] = | ||||
| 	{   2,   prim_basic_at_put,         "_basic_at_put"        }, | ||||
|  | ||||
| 	{  -1,   prim_block_value,          "_block_value"         }, | ||||
| 	{   0,   prim_block_new_process,    "_block_new_process"   }, | ||||
| 	{  -1,   prim_block_new_process,    "_block_new_process"   }, | ||||
|  | ||||
| 	{   1,   prim_integer_add,          "_integer_add"         }, | ||||
| 	{   1,   prim_integer_sub,          "_integer_sub"         }, | ||||
| @ -1472,8 +1550,9 @@ static prim_t primitives[] = | ||||
| 	{   1,   prim_integer_le,           "_integer_le"          }, | ||||
| 	{   1,   prim_integer_ge,           "_integer_ge"          }, | ||||
|  | ||||
| 	{   1,   prim_scheduler_add,        "_scheduler_add"       }, | ||||
| 	{   1,   prim_scheduler_remove,     "_scheduler_remove"    }, | ||||
| 	{   1,   prim_processor_schedule,   "_processor_schedule"  }, | ||||
| 	{   1,   prim_processor_remove,     "_processor_remove"    }, | ||||
| 	{   1,   prim_processor_sleep,      "_processor_sleep"     }, | ||||
|  | ||||
| 	{   1,   prim_ffi_open,             "_ffi_open"            }, | ||||
| 	{   1,   prim_ffi_close,            "_ffi_close"           }, | ||||
| @ -2453,7 +2532,7 @@ printf ("<<LEAVING>> SP=%d\n", (int)stix->sp); | ||||
| 				 */ | ||||
| 				stix->ip--;  | ||||
|  | ||||
| 				if (stix->scheduler->active->initial_context == stix->active_context) | ||||
| 				if (stix->processor->active->initial_context == stix->active_context) | ||||
| 				{ | ||||
| /* TODO: terminate a proces... */ | ||||
| printf ("TERMINATING XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); | ||||
| @ -2485,7 +2564,7 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n"); | ||||
|  | ||||
| 				STIX_ASSERT(STIX_CLASSOF(stix, stix->active_context)  == stix->_block_context); | ||||
|  | ||||
| 				if (stix->active_context == stix->scheduler->active->initial_context) | ||||
| 				if (stix->active_context == stix->processor->active->initial_context) | ||||
| 				{ | ||||
| 					/* TODO: terminate the process */ | ||||
| printf ("TERMINATE A PROCESS............\n"); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user