ufunc calls to functions can have scheduling complexities.

This commit is contained in:
steve 2003-05-07 03:39:12 +00:00
parent 84b0ca822b
commit 4ace97a083
3 changed files with 69 additions and 18 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: codes.h,v 1.59 2003/03/28 02:33:56 steve Exp $"
#ident "$Id: codes.h,v 1.60 2003/05/07 03:39:12 steve Exp $"
#endif
@ -117,7 +117,8 @@ extern bool of_XORR(vthread_t thr, vvp_code_t code);
extern bool of_ZOMBIE(vthread_t thr, vvp_code_t code);
extern bool of_CALL_UFUNC(vthread_t thr, vvp_code_t code);
extern bool of_FORK_UFUNC(vthread_t thr, vvp_code_t code);
extern bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t code);
/*
* This is the format of a machine code instruction.
@ -171,6 +172,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
/*
* $Log: codes.h,v $
* Revision 1.60 2003/05/07 03:39:12 steve
* ufunc calls to functions can have scheduling complexities.
*
* Revision 1.59 2003/03/28 02:33:56 steve
* Add support for division of real operands.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ufunc.cc,v 1.2 2002/08/12 01:35:08 steve Exp $"
#ident "$Id: ufunc.cc,v 1.3 2003/05/07 03:39:12 steve Exp $"
#endif
# include "compile.h"
@ -32,6 +32,7 @@
#endif
# include <stdlib.h>
# include <string.h>
# include <iostream>
# include <assert.h>
#ifdef __MINGW32__
@ -171,12 +172,36 @@ void compile_ufunc(char*label, char*code, unsigned wid,
/* Construct some phantom code that is the thread of the
function call. The first instruction, at the start_address
of the function, loads the points and calls the function.
The last instruction is the usual %end. */
The last instruction is the usual %end. So the thread looks
like this:
%fork_ufunc <core>;
%join;
%join_ufunc;
%end;
The %fork_ufunc starts the user defined function by copying
the input values into local regs, forking a thread and
pushing that thread. The %join waits on that thread. The
$join_ufunc then copies the output values to the
destination net functors. */
vvp_cpoint_t start_address = codespace_allocate();
vvp_code_t start_code = codespace_index(start_address);
start_code->opcode = of_CALL_UFUNC;
start_code->opcode = of_FORK_UFUNC;
code_label_lookup(start_code, code);
{ vvp_cpoint_t cur = codespace_allocate();
vvp_code_t codep = codespace_index(cur);
codep->opcode = &of_JOIN;
}
vvp_code_t ujoin_code;
{ vvp_cpoint_t cur = codespace_allocate();
ujoin_code = codespace_index(cur);
ujoin_code->opcode = &of_JOIN_UFUNC;
}
{ vvp_cpoint_t cur = codespace_allocate();
vvp_code_t codep = codespace_index(cur);
codep->opcode = &of_END;
@ -191,6 +216,7 @@ void compile_ufunc(char*label, char*code, unsigned wid,
start_address,
vpip_peek_current_scope());
start_code->ufunc_core_ptr = core;
ujoin_code->ufunc_core_ptr = core;
/* create enough input functors to connect to all the input
bits of the function. These are used to detect changes and
@ -215,6 +241,9 @@ void compile_ufunc(char*label, char*code, unsigned wid,
/*
* $Log: ufunc.cc,v $
* Revision 1.3 2003/05/07 03:39:12 steve
* ufunc calls to functions can have scheduling complexities.
*
* Revision 1.2 2002/08/12 01:35:08 steve
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vthread.cc,v 1.106 2003/03/28 02:33:57 steve Exp $"
#ident "$Id: vthread.cc,v 1.107 2003/05/07 03:39:12 steve Exp $"
#endif
# include "vthread.h"
@ -2653,28 +2653,43 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
}
/*
* This is a phantom opcode used to call user defined functions. It is
* used in code generated by the .ufunc statement. This instruction
* contains a pointer to executable code of the function, and to a
* These are phantom opcode used to call user defined functions.
* They are used in code generated by the .ufunc statement. They
* contain a pointer to executable code of the function, and to a
* ufunc_core object that has all the port information about the
* function.
*/
bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
bool of_FORK_UFUNC(vthread_t thr, vvp_code_t cp)
{
/* Copy all the inputs to the ufunc object to the port
variables of the function. This copies all the values
atomically. */
cp->ufunc_core_ptr->assign_bits_to_ports();
/* Create a temporary thread, and execute it manually. This is
necessary so that the previous step (assign_bits_to_ports)
and the execution of the function itself are an atomic
unit. If it were not, then the inputs might change between
setup and execution, causing really bad things to happen. */
vthread_t child = vthread_new(cp->cptr, cp->ufunc_core_ptr->scope());
vthread_mark_scheduled(child);
vthread_run(child);
assert(thr->child == 0);
assert(thr->fork_count == 0);
/* Create a temporary thread, and push its execution. This is
done so that the assign_bits_to_ports above is atomic with
this startup. */
vthread_t child = vthread_new(cp->cptr, cp->ufunc_core_ptr->scope());
child->child = 0;
child->parent = thr;
thr->child = child;
thr->fork_count += 1;
schedule_vthread(child, 0, true);
/* After this function, the .ufunc code has placed an of_JOIN
to pause this thread. Since the child was pushed by the
flag to schecule_vthread, the called function starts up
immediately. */
return true;
}
bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
{
/* Now copy the output from the result variable to the output
ports of the .ufunc device. */
cp->ufunc_core_ptr->finish_thread(thr);
@ -2684,6 +2699,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.107 2003/05/07 03:39:12 steve
* ufunc calls to functions can have scheduling complexities.
*
* Revision 1.106 2003/03/28 02:33:57 steve
* Add support for division of real operands.
*