ufunc calls to functions can have scheduling complexities.
This commit is contained in:
parent
84b0ca822b
commit
4ace97a083
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
35
vvp/ufunc.cc
35
vvp/ufunc.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue