VMS/VMS_Implementations/VMS_impls/VMS__MC_shared_impl

view PR__PI.c @ 286:b02b34681414

VReo V2 -- saves checker and doer fn with the port, where triggered
author Sean Halle <seanhalle@yahoo.com>
date Wed, 10 Jul 2013 14:49:04 -0700
parents 40e7625e57bd
children
line source
1 /*
2 * Copyright 2010 OpenSourceResearchInstitute
3 *
4 * Licensed under BSD
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <malloc.h>
11 #include <inttypes.h>
12 #include <sys/time.h>
14 #include "PR.h"
17 /* MEANING OF WL PI SS int
18 * These indicate which places the function is safe to use. They stand for:
19 * WL: Wrapper Library
20 * PI: Plugin
21 * SS: Startup and Shutdown
22 * int: internal to the PR implementation
23 */
26 /*All langlets use this call to make their slaves ready.. this, in turn,
27 * calls the make_ready that was registered by the langlet.
28 */
29 void
30 PR_PI__make_slave_ready( SlaveVP *slave, void *_langEnv )
31 { PRLangEnv *protoLangEnv;
33 if( _PRTopEnv->overrideAssigner != NULL )
34 {
35 //put slave into override readyQ
37 //update override hasWork flag ?
38 }
39 else
40 { //call langlet's registered make ready
41 protoLangEnv = PR_int__give_proto_lang_env( _langEnv );
42 (*protoLangEnv->makeSlaveReadyFn)( slave, _langEnv );
44 //incr amount of work ready, in langlet's environ
45 protoLangEnv->numReadyWork += 1;
46 if(protoLangEnv->numReadyWork == 1)
47 { protoLangEnv->processEnvIsIn->numEnvsWithWork += 1;
48 }
49 }
50 }
51 /*Make slave ready, without having to know the lang env.. just the magic num
52 */
53 void
54 PR_PI__make_slave_ready_for_lang( SlaveVP *slave, int32 magicNum )
55 { void *langEnv;
56 langEnv = PR_PI__give_lang_env_for_slave( slave, magicNum );
57 PR_PI__make_slave_ready( slave, langEnv );
58 }
60 /*Any langlet can transfer slaves over to be resumed in PRServ.. the resume Fn
61 * is registered in the PRServ lang env during process creation.
62 */
63 void
64 PR_PI__resume_slave_in_PRServ( SlaveVP *slave )
65 { void *langEnv;
66 langEnv = PR_PI__give_lang_env_for_slave( slave, PRServ_MAGIC_NUMBER );
67 PR_PI__make_slave_ready( slave, langEnv );
68 }
70 void
71 PR_PI__make_task_ready( void *_task, void *_langEnv )
72 { PRLangEnv *protoLangEnv;
74 if( _PRTopEnv->overrideAssigner != NULL )
75 {
76 //put task into override readyQ
78 //update numWorkReady
79 }
80 else
81 { //call langlet's registered make ready
82 protoLangEnv = PR_int__give_proto_lang_env( _langEnv );
83 (*protoLangEnv->makeTaskReadyFn)( _task, _langEnv );
85 //incr amount of work ready, in langlet's environ
86 protoLangEnv->numReadyWork += 1;
87 if(protoLangEnv->numReadyWork == 1)
88 { protoLangEnv->processEnvIsIn->numEnvsWithWork += 1;
89 }
90 }
91 }
94 /*This is used by langlets.. the intent is that they provide a wrapper
95 * lib call for a "wait" command, and then call this PR service inside their
96 * request handler.
97 *Note: PRServ doesn't offer a "wait for work to end".. it also doesn't have any
98 * create work calls.. and there is no way to end PRServ, except by ending the
99 * process. Therefore, this can safely use the PRServ env to
100 * resume any waiting slaves (incl free task slaves, which are one-to-one
101 * with a task).
102 */
103 void
104 PR_PI__handle_wait_for_langlets_work_to_end( SlaveVP *slave, void *langEnv )
105 { PRLangEnv *protoLangEnv;
107 protoLangEnv = PR_int__give_proto_lang_env( langEnv );
109 if( protoLangEnv->numLiveWork == 0 )
110 { //resume into different env than one with no work, as it may be shut down
111 void *
112 resumeEnv = PR_PI__give_lang_env_from_process( slave->processSlaveIsIn, PRServ_MAGIC_NUMBER );
113 PR_PI__make_slave_ready( slave, resumeEnv );
114 return;
115 }
116 else
117 {
118 writePrivQ( slave, protoLangEnv->waitingForWorkToEndQ );
119 }
120 }
122 SlaveVP *
123 PR_PI__give_slave_lang_meta_task_is_assigned_to( void *langMetaTask )
124 { PRMetaTask *metaTask = PR_int__give_prolog_of_lang_meta_task( langMetaTask );
125 return metaTask->slaveAssignedTo;
126 }
128 void
129 PR_PI__set_no_del_flag_in_lang_meta_task( void *langMetaTask )
130 { PRMetaTask *protoMetaTask = PR_int__give_prolog_of_lang_meta_task( langMetaTask );
131 protoMetaTask->goAheadAndFree = FALSE;
132 }
134 void
135 PR_PI__clear_no_del_flag_in_lang_meta_task( void *langMetaTask )
136 { PRMetaTask *protoMetaTask = PR_int__give_prolog_of_lang_meta_task( langMetaTask );
137 protoMetaTask->goAheadAndFree = TRUE;
138 }
140 /*Two use-cases for freeing a meta-task.. one is the langlet has control
141 * over the meta tasks's life-line it may differ from the task-work-unit's
142 * lifeline.. the other is PR controls, for example when a langlet or
143 * process gets pre-maturely shutdown due to outside influences, or exception,
144 * and so on..
145 *In the first case, the langlet has two choices.. it can free all the langlet
146 * malloc'd data owned by the meta-task, then as PR to free the remaining
147 * proto meta-task.. or, it can just call PR's full-service "free meta-task"
148 * which in turn calls the langlet's "free just langlet-malloc'd data" Fn, which
149 * was given to the meta-task creator..
150 *
151 *In the second case, PR calls the langlet's "free just langlet malloc'd data"
152 * Fn, which was given to the meta-task creator. The langlet has no other
153 * involvement.
154 *
155 *This is used by the langlet when it separately frees its own
156 * portion of the meta-task.
157 *
158 *PR uses "PR_int__free_lang_meta_task", which calls the langlet's freer, which
159 * was given to the meta task creator
160 */
161 void
162 PR_PI__free_proto_meta_task_by_langlet( PRMetaTask *protoMetaTask )
163 {
164 PR_int__remove_elem_from_collection( protoMetaTask->langMagicNumber,
165 (PRCollElem **) protoMetaTask->slaveAssignedTo->metaTasks );
167 PR_int__free( protoMetaTask );
168 }
171 PRReqst *
172 PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq )
173 { PRReqst *req;
175 req = slaveWithReq->request;
176 if( req == NULL ) return NULL;
178 slaveWithReq->request = slaveWithReq->request->nextReqst;
179 return req;
180 }
184 /*May 2012
185 *CHANGED IMPL -- now a macro in header file
186 *
187 *Turn function into macro that just accesses the request field
188 *
189 inline void *
190 PR_PI__take_lang_reqst_from( PRReqst *req )
191 {
192 return req->langReqData;
193 }
194 */