1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe Constraint Logic Programming System. 15 * The Initial Developer of the Original Code is Cisco Systems, Inc. 16 * Portions created by the Initial Developer are 17 * Copyright (C) 1994-2006 Cisco Systems, Inc. All Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 * END LICENSE BLOCK */ 22 23/********************************************************************** 24** System: Parallel ECLiPSe Scheduler 25** File: scheduler.c 26** Author: Liang-Liang Li 27** Description: 28** 29***********************************************************************/ 30 31#include <stdio.h> 32 33#include "config.h" 34 35#include "pds.h" /* The Underlying Message Passing System */ 36#include "memman.h" 37#include "trace.h" /* The tracing events and macros defintions */ 38#include "error.h" 39 40#include "sch_types.h" /* The scheduler tree definitions and macros */ 41#include "sch_eng_interface.h" /* interface: scheduler/engine/worker manage */ 42#include "sch_macros.h" 43 44/***** Scheduler sub-functions *****/ 45/*************************************/ 46#if defined(__STDC__) 47/* Send scheduler msgs of various sizes: 48** recv-id, msg-type, send-id 49** is the smallest size. 50** Smsg_sndIJ means the msg sent has extra I tree ids, and J integers. 51** this grouping is subject to change when dealing with newly introduced msgs 52*/ 53 54static void smsg_snd00(st_id_t *, int, st_id_t *); 55static void smsg_snd01(st_id_t *, int, st_id_t *, int); 56static void smsg_snd02(st_id_t *, int, st_id_t *, int, int); 57static void smsg_snd10(st_id_t *, int, st_id_t *, st_id_t *); 58static void smsg_snd12(st_id_t *, int, st_id_t *, st_id_t *, int,int); 59static void smsg_snd20(st_id_t *, int, st_id_t *, st_id_t *, st_id_t *); 60static void smsg_snd21(st_id_t *, int, st_id_t *, st_id_t *, st_id_t *, int); 61static void smsg_snd30(st_id_t *, int, st_id_t *, st_id_t *, st_id_t *, st_id_t *); 62 63/* handles scheduler msgs of various types */ 64static void sch_port_naive_upcall (site_id_t); 65static void sch_async_msg_hdls (site_id_t, int); 66 67static void sch_msg_hdl_init_lodge (st_id_t *, st_id_t *, int); 68static void sch_msg_hdl_backtrack (st_id_t *, st_id_t *); 69static void sch_msg_hdl_withered (st_id_t *, st_id_t *); 70static void sch_msg_hdl_dec_corpse (st_id_t *, st_id_t *); 71static void sch_msg_hdl_js_in_vain (st_id_t *, st_id_t *); 72static void sch_msg_hdl_load_report (st_id_t *, st_id_t *); 73static void sch_msg_hdl_set_js_root (st_id_t *, st_id_t *); 74static void sch_msg_hdl_js_again (st_id_t *, st_id_t *); 75static void sch_msg_hdl_lodged (st_id_t *, st_id_t *); 76static void sch_msg_hdl_tell_idle (st_id_t *, st_id_t *); 77static void sch_msg_hdl_idle_told (st_id_t *, st_id_t *); 78static void sch_msg_hdl_idle_eng (st_id_t *, st_id_t *); 79static void sch_msg_hdl_wake_eng (st_id_t *, st_id_t *); 80static void sch_msg_hdl_stop_idle (st_id_t *, st_id_t *); 81static void sch_msg_hdl_lmp (st_id_t *, st_id_t *); 82static void sch_msg_hdl_reduce_wk_up (st_id_t *, st_id_t *); 83static void sch_msg_hdl_reduce_wk_dn (st_id_t *, st_id_t *); 84static void sch_msg_hdl_engine_migrate(st_id_t *, st_id_t *); 85 86static void sch_msg_hdl_cut_ok (st_id_t *, st_id_t *, int); 87 88static void sch_msg_hdl_js_success (st_id_t *, st_id_t *, int, int); 89 90static void sch_msg_hdl_cut (st_id_t *, st_id_t *, st_id_t *); 91static void sch_msg_hdl_chop (st_id_t *, st_id_t *, st_id_t *); 92static void sch_msg_hdl_lodge (st_id_t *, st_id_t *, st_id_t *); 93static void sch_msg_hdl_lodge_idle (st_id_t *, st_id_t *, st_id_t *); 94static void sch_msg_hdl_js_prologue (st_id_t *, st_id_t *, st_id_t *); 95 96static void sch_msg_hdl_js_trust (st_id_t *, st_id_t *, st_id_t *, int, int); 97 98static void sch_msg_hdl_js_trav_up (st_id_t *, st_id_t *, st_id_t *, st_id_t *); 99static void sch_msg_hdl_js_trav_dn (st_id_t *, st_id_t *, st_id_t *, st_id_t *); 100static void sch_msg_hdl_js_install_fl (st_id_t *, st_id_t *, st_id_t *, st_id_t *); 101 102static void sch_msg_hdl_straighten (st_id_t *, st_id_t *, st_id_t *, st_id_t *, int); 103 104static void sch_msg_hdl_js_install (st_id_t *, st_id_t *, st_id_t *, st_id_t *, st_id_t *); 105 106/* others */ 107#if defined(MULTI_THREADS) 108int simp_lock(char *); 109void simp_unlock(char *); 110#endif /* MULTI_THREADS */ 111 112#else /* __STDC__ */ 113 114static void smsg_snd00(); 115static void smsg_snd01(); 116static void smsg_snd02(); 117static void smsg_snd10(); 118static void smsg_snd12(); 119static void smsg_snd20(); 120static void smsg_snd21(); 121static void smsg_snd30(); 122 123static void sch_port_naive_upcall (); 124static void sch_async_msg_hdls (); 125 126static void sch_msg_hdl_init_lodge (); 127static void sch_msg_hdl_backtrack (); 128static void sch_msg_hdl_withered (); 129static void sch_msg_hdl_dec_corpse (); 130static void sch_msg_hdl_js_in_vain (); 131static void sch_msg_hdl_load_report (); 132static void sch_msg_hdl_set_js_root (); 133 134static void sch_msg_hdl_cut_ok (); 135static void sch_msg_hdl_js_again (); 136static void sch_msg_hdl_lodged (); 137static void sch_msg_hdl_tell_idle (); 138static void sch_msg_hdl_idle_told (); 139static void sch_msg_hdl_idle_eng (); 140static void sch_msg_hdl_wake_eng (); 141static void sch_msg_hdl_stop_idle (); 142static void sch_msg_hdl_lmp (); 143static void sch_msg_hdl_reduce_wk_up (); 144static void sch_msg_hdl_reduce_wk_dn (); 145static void sch_msg_hdl_engine_migrate(); 146 147static void sch_msg_hdl_js_success (); 148 149static void sch_msg_hdl_cut (); 150static void sch_msg_hdl_chop (); 151static void sch_msg_hdl_lodge (); 152static void sch_msg_hdl_lodge_idle (); 153static void sch_msg_hdl_js_prologue (); 154 155static void sch_msg_hdl_js_trust (); 156 157static void sch_msg_hdl_js_trav_up (); 158static void sch_msg_hdl_js_trav_dn (); 159static void sch_msg_hdl_js_install_fl (); 160 161static void sch_msg_hdl_straighten (); 162 163static void sch_msg_hdl_js_install (); 164 165#if defined(MULTI_THREADS) 166int simp_lock (); 167void simp_unlock (); 168#endif /* MULTI_THREADS */ 169 170#endif /* __STDC__ */ 171 172int zero(); 173 174/***** Scheduler Messages Among Nodes/Leaves *****/ 175/**********************************************************/ 176 177/* Scheduler Message Listing */ 178#define SMSG_INIT_LODGE 0 /* root, leaf, wm_port */ 179#define SMSG_BACKTRACK 1 /* parent, leaf */ 180#define SMSG_STRAIGHTEN 2 /* parent, child, leaf, parent0, nxtcls */ 181#define SMSG_CUT 3 /* (a) parent, leaf */ 182#define SMSG_CUT_OK 4 /* leaf, parent, info */ 183#define SMSG_CHOP 5 /* child, parent, ancestor */ 184#define SMSG_WITHERED 6 /* parent, child */ 185#define SMSG_LODGE 7 /* (a) parent, leaf */ 186#define SMSG_LODGED 8 /* leaf, parent */ 187#define SMSG_DEC_CORPSE 9 /* oldleaf, newleaf */ 188#define SMSG_JS_PROLOGUE 10 /* parent, child, leaf */ 189#define SMSG_JS_TRAV_UP 11 /* parent, child, leaf, coma */ 190#define SMSG_JS_TRAV_DN 12 /* child, parent, leaf, coma */ 191#define SMSG_JS_INSTALL 13 /* child, parent, leaf, coma */ 192#define SMSG_JS_INSTALL_FL 14 /* lodge,child,coma,leaf */ 193#define SMSG_JS_SUCCESS 15 /* leaf, parent, nxtcls, info */ 194#define SMSG_JS_TRUST 16 /* leaf, parent, parent0, nxtcls, info */ 195#define SMSG_JS_IN_VAIN 17 /* leaf, jsroot */ 196#define SMSG_JS_AGAIN 18 /* parent, leaf */ 197#define SMSG_LOAD_REPORT 19 /* parent, child */ 198#define SMSG_SET_JS_ROOT 20 /* child, parent */ 199#define SMSG_WAKE_ENG 21 /* leaf, leaf */ 200#define SMSG_IDLE_ENG 22 /* leaf, leaf */ 201#define SMSG_TELL_IDLE 23 /* parent, leaf */ 202#define SMSG_LODGE_IDLE 24 /* parent, child, leaf */ 203#define SMSG_IDLE_TOLD 25 /* leaf, parent */ 204#define SMSG_STOP_IDLE 26 /* parent, leaf */ 205#define SMSG_LMP 27 /* child, parent */ 206#define SMSG_REDUCE_WK_UP 28 /* parent, child */ 207#define SMSG_REDUCE_WK_DN 29 /* child, parent */ 208#define SMSG_ENGINE_MIGRATE 30 /* parent, leaf */ 209#define SMSG_MAXNUM 31 /* last item */ 210 211/* Comments 212 1. The argument lists for the handlers of messages are listed as comment. 213 2. Some messages are sent upwards the scheduler tree: 214 parent (or ancestors as future parent) as 1st argument 215 3. Other messages are sent downwards the scheduler tree: 216 child or leaf as 1st argument. 217 4. A leaf can receive any of downward messages. 218 (of course, a leaf with specific state may not expect all of them). 219 5. All of the arguments are pointers to a sch-tree identifiers, with 220 exceptions: SMSG_JS_SUCCESS needs a next-clause argument, 221 6. coma -> common ancestor 222*/ 223 224/* Brief explanations for some of the messages : 225 SMSG_STRAIGHTEN: turns a single threaded subtree into a branch; 226 SMSG_CHOP: chops a subtree 227 SMSG_DEC_CORPSE: decouple the old leaf and its reincarnated new leaf 228 SMSG_JS_PROLOGUE: job-search along the lodging path 229 SMSG_JS_TRAV_UP: job-request from a just searched subtree 230 SMSG_JS_INSTALL: asked to install job-state 231 SMSG_JS_INSTALL_FL: fail acknowledgement of installation 232 SMSG_JS_IN_VAIN: nothing is found in the current job-search tree 233 SMSG_JS_AGAIN: start a new session 234 SMSG_JS_TRUST: coupled with SMSG_STRAIGHTEN (reply) 235 SMSG_LOAD_REPORT: report richness of a subtree 236 SMSG_SET_JS_ROOT: set a smallest tree for job search 237 SMSG_IDLE_ENG: instruct the leaf to let the engine idle 238 SMSG_WAKE_ENG: instruct the leaf to wake up the engine 239 SMSG_LMP: instruct the left-most path to become LM set 240 SMSG_REDUCE_WK_UP: 241 SMSG_REDUCE_WK_DN: wake up suspended job-search message flows. 242 SMSG_ENGINE_MIGRATE: the leaf with the engine just copied oracled wants 243 migrate to the new parent 244*/ 245 246char * smsg_name[SMSG_MAXNUM+1]; 247 248static scheduler_t scheduler[1]; 249static st_knot_t knot_template[1]; 250 251/***** Data Blocks Packing Messages of various sizes *****/ 252/***********************************************************/ 253 254/* smsg_xy_t: a message with x stree ids and y integers */ 255 256typedef struct { 257 struct st_id_ds recv; 258 pds_int32 type; 259 struct st_id_ds send; 260} smsg00_t; 261 262typedef struct { 263 struct st_id_ds recv; 264 pds_int32 type; 265 struct st_id_ds send; 266 int i1; 267} smsg01_t; 268 269typedef struct { 270 struct st_id_ds recv; 271 pds_int32 type; 272 struct st_id_ds send; 273 pds_int32 i1; 274 pds_int32 i2; 275} smsg02_t; 276 277typedef struct { 278 struct st_id_ds recv; 279 pds_int32 type; 280 struct st_id_ds send; 281 struct st_id_ds t1; 282} smsg10_t; 283 284typedef struct { 285 struct st_id_ds recv; 286 pds_int32 type; 287 struct st_id_ds send; 288 struct st_id_ds t1; 289 pds_int32 i1; 290 pds_int32 i2; 291} smsg12_t; 292 293typedef struct { 294 struct st_id_ds recv; 295 pds_int32 type; 296 struct st_id_ds send; 297 struct st_id_ds t1; 298 struct st_id_ds t2; 299} smsg20_t; 300 301typedef struct { 302 struct st_id_ds recv; 303 pds_int32 type; 304 struct st_id_ds send; 305 struct st_id_ds t1; 306 struct st_id_ds t2; 307 pds_int32 i1; 308} smsg21_t; 309 310typedef struct { 311 struct st_id_ds recv; 312 pds_int32 type; 313 struct st_id_ds send; 314 struct st_id_ds t1; 315 struct st_id_ds t2; 316 struct st_id_ds t3; 317} smsg30_t; 318 319#define ECLIPSE_SCH_INTFCNO 1217 320 321void smsg_type_init(site) 322site_id_t site; 323{ 324 amsg_typedef_t mdt_smsg_type[10]; 325 amsg_type_t mdt_st_id; 326 327 mdt_smsg_type[0] = MDT_BEGIN; 328 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 329 mdt_smsg_type[2] = MDT_APORTID; 330 mdt_smsg_type[3] = MDT_UINT32; 331 mdt_smsg_type[4] = MDT_UINT32; 332 mdt_smsg_type[5] = MDT_STRUCT_CLOSE; 333 mdt_smsg_type[6] = MDT_END; 334 if (amsg_type_define(ECLIPSE_SCH_INTFCNO, 10, mdt_smsg_type, &mdt_st_id) 335 != AMSG_OK) { 336 error("fail to define st_id type"); 337 } 338 339 mdt_smsg_type[0] = MDT_BEGIN; 340 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 341 mdt_smsg_type[2] = mdt_st_id; 342 mdt_smsg_type[3] = MDT_INT32; 343 mdt_smsg_type[4] = mdt_st_id; 344 mdt_smsg_type[5] = MDT_STRUCT_CLOSE; 345 mdt_smsg_type[6] = MDT_END; 346 if (amsg_type_define( 347 ECLIPSE_SCH_INTFCNO, 11, mdt_smsg_type, &Scheduler(site)->smsg_type[0][0] 348 ) != AMSG_OK) { 349 error("fail to define smsg00 type"); 350 } 351 352 mdt_smsg_type[0] = MDT_BEGIN; 353 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 354 mdt_smsg_type[2] = mdt_st_id; 355 mdt_smsg_type[3] = MDT_INT32; 356 mdt_smsg_type[4] = mdt_st_id; 357 mdt_smsg_type[5] = MDT_INT32; 358 mdt_smsg_type[6] = MDT_STRUCT_CLOSE; 359 mdt_smsg_type[7] = MDT_END; 360 if (amsg_type_define( 361 ECLIPSE_SCH_INTFCNO, 12, mdt_smsg_type, &Scheduler(site)->smsg_type[0][1] 362 ) != AMSG_OK) { 363 error("fail to define smsg01 type"); 364 } 365 366 mdt_smsg_type[0] = MDT_BEGIN; 367 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 368 mdt_smsg_type[2] = mdt_st_id; 369 mdt_smsg_type[3] = MDT_INT32; 370 mdt_smsg_type[4] = mdt_st_id; 371 mdt_smsg_type[5] = MDT_INT32; 372 mdt_smsg_type[6] = MDT_INT32; 373 mdt_smsg_type[7] = MDT_STRUCT_CLOSE; 374 mdt_smsg_type[8] = MDT_END; 375 if (amsg_type_define( 376 ECLIPSE_SCH_INTFCNO, 13, mdt_smsg_type, &Scheduler(site)->smsg_type[0][2] 377 ) != AMSG_OK) { 378 error("fail to define smsg02 type"); 379 } 380 381 mdt_smsg_type[0] = MDT_BEGIN; 382 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 383 mdt_smsg_type[2] = mdt_st_id; 384 mdt_smsg_type[3] = MDT_INT32; 385 mdt_smsg_type[4] = mdt_st_id; 386 mdt_smsg_type[5] = mdt_st_id; 387 mdt_smsg_type[6] = MDT_STRUCT_CLOSE; 388 mdt_smsg_type[7] = MDT_END; 389 if (amsg_type_define( 390 ECLIPSE_SCH_INTFCNO, 14, mdt_smsg_type, &Scheduler(site)->smsg_type[1][0] 391 ) != AMSG_OK) { 392 error("fail to define smsg10 type"); 393 } 394 395 mdt_smsg_type[0] = MDT_BEGIN; 396 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 397 mdt_smsg_type[2] = mdt_st_id; 398 mdt_smsg_type[3] = MDT_INT32; 399 mdt_smsg_type[4] = mdt_st_id; 400 mdt_smsg_type[5] = mdt_st_id; 401 mdt_smsg_type[6] = MDT_INT32; 402 mdt_smsg_type[7] = MDT_INT32; 403 mdt_smsg_type[8] = MDT_STRUCT_CLOSE; 404 mdt_smsg_type[9] = MDT_END; 405 if (amsg_type_define( 406 ECLIPSE_SCH_INTFCNO, 15, mdt_smsg_type, &Scheduler(site)->smsg_type[1][2] 407 ) != AMSG_OK) { 408 error("fail to define smsg12 type"); 409 } 410 411 mdt_smsg_type[0] = MDT_BEGIN; 412 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 413 mdt_smsg_type[2] = mdt_st_id; 414 mdt_smsg_type[3] = MDT_INT32; 415 mdt_smsg_type[4] = mdt_st_id; 416 mdt_smsg_type[5] = mdt_st_id; 417 mdt_smsg_type[6] = mdt_st_id; 418 mdt_smsg_type[7] = MDT_STRUCT_CLOSE; 419 mdt_smsg_type[8] = MDT_END; 420 if (amsg_type_define( 421 ECLIPSE_SCH_INTFCNO, 16, mdt_smsg_type, &Scheduler(site)->smsg_type[2][0] 422 ) != AMSG_OK) { 423 error("fail to define smsg20 type"); 424 } 425 426 mdt_smsg_type[0] = MDT_BEGIN; 427 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 428 mdt_smsg_type[2] = mdt_st_id; 429 mdt_smsg_type[3] = MDT_INT32; 430 mdt_smsg_type[4] = mdt_st_id; 431 mdt_smsg_type[5] = mdt_st_id; 432 mdt_smsg_type[6] = mdt_st_id; 433 mdt_smsg_type[7] = MDT_INT32; 434 mdt_smsg_type[8] = MDT_STRUCT_CLOSE; 435 mdt_smsg_type[9] = MDT_END; 436 if (amsg_type_define( 437 ECLIPSE_SCH_INTFCNO, 17, mdt_smsg_type, &Scheduler(site)->smsg_type[2][1] 438 ) != AMSG_OK) { 439 error("fail to define smsg21 type"); 440 } 441 442 mdt_smsg_type[0] = MDT_BEGIN; 443 mdt_smsg_type[1] = MDT_STRUCT_OPEN; 444 mdt_smsg_type[2] = mdt_st_id; 445 mdt_smsg_type[3] = MDT_INT32; 446 mdt_smsg_type[4] = mdt_st_id; 447 mdt_smsg_type[5] = mdt_st_id; 448 mdt_smsg_type[6] = mdt_st_id; 449 mdt_smsg_type[7] = mdt_st_id; 450 mdt_smsg_type[8] = MDT_STRUCT_CLOSE; 451 mdt_smsg_type[9] = MDT_END; 452 if (amsg_type_define( 453 ECLIPSE_SCH_INTFCNO, 18, mdt_smsg_type, &Scheduler(site)->smsg_type[3][0] 454 ) != AMSG_OK) { 455 error("fail to define smsg30 type"); 456 } 457} 458 459static void smsg_snd00(recv, type, send) 460int type; 461st_id_t *recv, *send; 462{ 463 amsg_t msg; 464 amsg_ret_t ret; 465 amsg_size_t datasize = sizeof(smsg00_t); 466 smsg00_t *data; 467 468 Smsg_Snd_Notify(type, recv, send); 469 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 470 assert(ret==AMSG_OK); 471 data->type = type; 472 data->recv = *recv; 473 data->send = *send; 474 IntraSiteCheckIn(Site(recv),Site(send)); 475 ret = amsg_send( 476 Site(recv), 477 msg, 478 Scheduler(Site(send))->smsg_type[0][0], 479 1, 480 0); 481 assert(ret==AMSG_OK); 482 return; 483} 484 485static void smsg_snd01(recv, type, send, i) 486int type; 487st_id_t *recv, *send; 488int i; 489{ 490 amsg_t msg; 491 amsg_ret_t ret; 492 amsg_size_t datasize = sizeof(smsg01_t); 493 smsg01_t *data; 494 495 Smsg_Snd_Notify(type, recv, send); 496 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 497 assert(ret==AMSG_OK); 498 data->type = type; 499 data->recv = *recv; 500 data->send = *send; 501 data->i1 = i; 502 IntraSiteCheckIn(Site(recv),Site(send)); 503 ret = amsg_send( 504 Site(recv), 505 msg, 506 Scheduler(Site(send))->smsg_type[0][1], 507 1, 508 0); 509 assert(ret==AMSG_OK); 510 return; 511} 512 513static void smsg_snd02(recv, type, send, i1,i2) 514int type; 515st_id_t *recv, *send; 516int i1,i2; 517{ 518 amsg_t msg; 519 amsg_ret_t ret; 520 amsg_size_t datasize = sizeof(smsg02_t); 521 smsg02_t *data; 522 523 Smsg_Snd_Notify(type, recv, send); 524 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 525 assert(ret==AMSG_OK); 526 data->type = type; 527 data->recv = *recv; 528 data->send = *send; 529 data->i1 = i1; 530 data->i2 = i2; 531 IntraSiteCheckIn(Site(recv),Site(send)); 532 ret = amsg_send( 533 Site(recv), 534 msg, 535 Scheduler(Site(send))->smsg_type[0][2], 536 1, 537 0); 538 assert(ret==AMSG_OK); 539 return; 540} 541 542static void smsg_snd10(recv, type, send, t1) 543int type; 544st_id_t *recv, *send, *t1; 545{ 546 amsg_t msg; 547 amsg_ret_t ret; 548 amsg_size_t datasize = sizeof(smsg10_t); 549 smsg10_t *data; 550 551 Smsg_Snd_Notify(type, recv, send); 552 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 553 assert(ret==AMSG_OK); 554 555 data->type = type; 556 data->recv = *recv; 557 data->send = *send; 558 data->t1 = *t1; 559 IntraSiteCheckIn(Site(recv),Site(send)); 560 ret = amsg_send( 561 Site(recv), 562 msg, 563 Scheduler(Site(send))->smsg_type[1][0], 564 1, 565 0); 566 assert(ret==AMSG_OK); 567 return; 568} 569 570static void smsg_snd12(recv, type, send, t1, i1,i2) 571int type; 572st_id_t *recv, *send, *t1; 573int i1,i2; 574{ 575 amsg_t msg; 576 amsg_ret_t ret; 577 amsg_size_t datasize = sizeof(smsg12_t); 578 smsg12_t *data; 579 580 Smsg_Snd_Notify(type, recv, send); 581 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 582 assert(ret==AMSG_OK); 583 data->type = type; 584 data->recv = *recv; 585 data->send = *send; 586 data->t1 = *t1; 587 data->i1 = i1; 588 data->i2 = i2; 589 IntraSiteCheckIn(Site(recv),Site(send)); 590 ret = amsg_send( 591 Site(recv), 592 msg, 593 Scheduler(Site(send))->smsg_type[1][2], 594 1, 595 0); 596 assert(ret==AMSG_OK); 597 return; 598} 599 600static void smsg_snd20(recv, type, send, t1, t2) 601int type; 602st_id_t *recv, *send, *t1, *t2; 603{ 604 amsg_t msg; 605 amsg_ret_t ret; 606 amsg_size_t datasize = sizeof(smsg20_t); 607 smsg20_t *data; 608 609 Smsg_Snd_Notify(type, recv, send); 610 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 611 assert(ret==AMSG_OK); 612 613 data->type = type; 614 data->recv = *recv; 615 data->send = *send; 616 data->t1 = *t1; 617 data->t2 = *t2; 618 IntraSiteCheckIn(Site(recv),Site(send)); 619 ret = amsg_send( 620 Site(recv), 621 msg, 622 Scheduler(Site(send))->smsg_type[2][0], 623 1, 624 0); 625 assert(ret==AMSG_OK); 626 return; 627} 628 629static void smsg_snd21(recv, type, send, t1, t2, i1) 630int type; 631st_id_t *recv, *send, *t1, *t2; 632int i1; 633{ 634 amsg_t msg; 635 amsg_ret_t ret; 636 amsg_size_t datasize = sizeof(smsg21_t); 637 smsg21_t *data; 638 639 Smsg_Snd_Notify(type, recv, send); 640 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 641 assert(ret==AMSG_OK); 642 643 data->type = type; 644 data->recv = *recv; 645 data->send = *send; 646 data->t1 = *t1; 647 data->t2 = *t2; 648 data->i1 = i1; 649 IntraSiteCheckIn(Site(recv),Site(send)); 650 ret = amsg_send( 651 Site(recv), 652 msg, 653 Scheduler(Site(send))->smsg_type[2][1], 654 1, 655 0); 656 assert(ret==AMSG_OK); 657 return; 658} 659 660static void smsg_snd30(recv, type, send, t1, t2, t3) 661int type; 662st_id_t *recv, *send, *t1, *t2, *t3; 663{ 664 amsg_t msg; 665 amsg_ret_t ret; 666 amsg_size_t datasize = sizeof(smsg30_t); 667 smsg30_t *data; 668 669 Smsg_Snd_Notify(type, recv, send); 670 ret = amsg_alloc(datasize, (amsg_data_t **)&data, &msg); 671 assert(ret==AMSG_OK); 672 673 data->type = type; 674 data->recv = *recv; 675 data->send = *send; 676 data->t1 = *t1; 677 data->t2 = *t2; 678 data->t3 = *t3; 679 IntraSiteCheckIn(Site(recv),Site(send)); 680 ret = amsg_send( 681 Site(recv), 682 msg, 683 Scheduler(Site(send))->smsg_type[3][0], 684 1, 685 0); 686 assert(ret==AMSG_OK); 687 return; 688} 689#define sch_msg_snd_backtrack(parent, leaf) \ 690 smsg_snd00((parent),SMSG_BACKTRACK,(leaf)) 691#define sch_msg_snd_lodged(leaf,parent) \ 692 smsg_snd00((leaf),SMSG_LODGED,(parent)) 693#define sch_msg_snd_withered(recv,child) \ 694 smsg_snd00((recv),SMSG_WITHERED,(child)) 695#define sch_msg_snd_dec_corpse(old,new) \ 696 smsg_snd00((old),SMSG_DEC_CORPSE,(new)) 697#define sch_msg_snd_js_in_vain(leaf,jroot) \ 698 smsg_snd00((leaf),SMSG_JS_IN_VAIN,(jroot)) 699#define sch_msg_snd_load_report(parent,child) \ 700 smsg_snd00((parent),SMSG_LOAD_REPORT,(child)) 701#define sch_msg_snd_set_js_root(child,parent) \ 702 smsg_snd00((child),SMSG_SET_JS_ROOT,(parent)) 703#define sch_msg_snd_js_again(parent,leaf) \ 704 smsg_snd00((parent),SMSG_JS_AGAIN,(leaf)) 705#define sch_msg_snd_idle_eng(leaf,leaf0) \ 706 smsg_snd00((leaf),SMSG_IDLE_ENG,(leaf0)) 707#define sch_msg_snd_wake_eng(leaf,leaf0) \ 708 smsg_snd00((leaf),SMSG_WAKE_ENG,(leaf0)) 709#define sch_msg_snd_idle_told(leaf,parent) \ 710 smsg_snd00((leaf),SMSG_IDLE_TOLD,(parent)) 711#define sch_msg_snd_lmp(child,parent) \ 712 smsg_snd00((child),SMSG_LMP,(parent)) 713#define sch_msg_snd_tell_idle(parent,leaf) \ 714 smsg_snd00((parent),SMSG_TELL_IDLE,(leaf)) 715#define sch_msg_snd_stop_idle(parent,leaf) \ 716 smsg_snd00((parent),SMSG_STOP_IDLE,(leaf)) 717#define sch_msg_snd_reduce_wk_up(parent,child) \ 718 smsg_snd00((parent),SMSG_REDUCE_WK_UP,(child)) 719#define sch_msg_snd_reduce_wk_dn(child, parent) \ 720 smsg_snd00((child),SMSG_REDUCE_WK_DN,(parent)) 721#define sch_msg_snd_engine_migrate(parent,leaf) \ 722 smsg_snd00((parent),SMSG_ENGINE_MIGRATE,(leaf)) 723 724#define sch_msg_snd_cut_ok(leaf,parent,info) \ 725 smsg_snd01((leaf),SMSG_CUT_OK,(parent),(info)) 726#define sch_msg_snd_init_lodge(root, leaf, wm) \ 727 smsg_snd01((root),SMSG_INIT_LODGE,(leaf),(wm)) 728 729#define sch_msg_snd_js_success(leaf,parent,nxtcls,info) \ 730 smsg_snd02((leaf),SMSG_JS_SUCCESS,(parent),(nxtcls),(info)) 731 732#define sch_msg_snd_cut(parent, olf, leaf) \ 733 smsg_snd10((parent),SMSG_CUT,(olf),(leaf)) 734#define sch_msg_snd_lodge(parent,child,leaf) \ 735 smsg_snd10((parent),SMSG_LODGE,(child),(leaf)) 736#define sch_msg_snd_chop(child,parent,ancestor) \ 737 smsg_snd10((child),SMSG_CHOP,(parent),(ancestor)) 738#define sch_msg_snd_lodge_idle(parent,child,leaf) \ 739 smsg_snd10((parent),SMSG_LODGE_IDLE,(child),(leaf)) 740#define sch_msg_snd_js_prologue(parent,child,leaf) \ 741 smsg_snd10((parent),SMSG_JS_PROLOGUE,(child),(leaf)) 742 743#define sch_msg_snd_js_trust(leaf,parent,parent_alt,nxtcls,info) \ 744 smsg_snd12((leaf),SMSG_JS_TRUST,(parent),(parent_alt),(nxtcls),(info)) 745 746#define sch_msg_snd_js_trav_up(parent,child,leaf,coma) \ 747 smsg_snd20((parent),SMSG_JS_TRAV_UP,(child),(leaf),(coma)) 748#define sch_msg_snd_js_trav_dn(child,parent,leaf,coma) \ 749 smsg_snd20((child),SMSG_JS_TRAV_DN,(parent),(leaf),(coma)) 750#define sch_msg_snd_js_install_fl(lodge,child,leaf,coma) \ 751 smsg_snd20((lodge),SMSG_JS_INSTALL_FL,(child),(leaf),(coma)) 752 753#define sch_msg_snd_straighten(parent,child,leaf,parent_alt,alt) \ 754 smsg_snd21((parent),SMSG_STRAIGHTEN,(child),(leaf),(parent_alt),(alt)) 755 756#define sch_msg_snd_js_install(child,parent,lodge,leaf,coma) \ 757 smsg_snd30((child), SMSG_JS_INSTALL, (parent),(lodge),(leaf),(coma)) 758 759 760#if defined(MULTI_THREADS) 761int simp_lock(lock) 762char *lock; 763{ 764 int ok = 0; 765 if (sch_mutex_lock()) { 766 if (!*lock) { 767 ok = *lock = 1; 768 } 769 sch_mutex_unlock(); 770 } 771 return(ok); 772} 773 774void simp_unlock(lock) 775char *lock; 776{ 777 while (!sch_mutex_lock()) {} 778 assert(*lock); 779 *lock = 0; 780 sch_mutex_unlock(); 781} 782#endif /* MULTI_THREADS */ 783 784void sch_port_upcall(p) 785site_id_t p; 786{ 787 LOG_EVENT_PUSH(SCH_ASYNC) 788 if (Scheduler(p)->async_hdl) { 789 sch_async_msg_hdls(p, 1); 790 } else { 791 sch_port_naive_upcall(p); 792 } 793 LOG_EVENT_POP; 794} 795 796/* UPCALL functions for the Scheduler Port */ 797static void sch_port_naive_upcall(port) 798aport_id_t port; 799{ 800 eng_msg_trigger(Scheduler(port)->engine); 801 return; 802} 803 804/* UPCALL functions for the Scheduler Port */ 805static void sch_async_msg_hdls(port, async) 806aport_id_t port; 807int async; 808{ 809 amsg_ret_t ret; 810 amsg_t msg; 811 smsg00_t *data; 812 amsg_type_t mdt_type; 813 amsg_count_t mdt_count; 814 815 st_id_t *recv; 816 st_id_t *send; 817 818 eng_msg_trigger(Scheduler(port)->engine); 819 while (1) { 820 Disable_Int(); 821 ret = amsg_peek( port, 822 &msg, 823 (amsg_data_t * *)&data, 824 &mdt_type, 825 &mdt_count); 826 if (ret == AMSG_NOMESSAGE) { 827 eng_msg_reset(Scheduler(port)->engine); 828#if !defined(NO_SHORTCUT) 829 assert(async || !Intrasite_Smsg(port)); 830#endif /* NO_SHORTCUT */ 831 Enable_Int(); 832 return; 833 } 834 Enable_Int(); 835 assert(ret==AMSG_OK && mdt_count == 1); 836 recv = &data->recv; 837 if (!Sch_Lock(recv)) { 838 assert(async); 839 return; 840 } 841 send = &data->send; 842 843 IntraSiteCheckOut(port,Site(send)); 844 845 switch (data->type) { 846 case SMSG_BACKTRACK: 847 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 848 sch_msg_hdl_backtrack(recv,send); 849 break; 850 case SMSG_LODGED: 851 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 852 sch_msg_hdl_lodged(recv,send); 853 break; 854 case SMSG_WITHERED: 855 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 856 sch_msg_hdl_withered(recv,send); 857 break; 858 case SMSG_DEC_CORPSE: 859 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 860 sch_msg_hdl_dec_corpse(recv,send); 861 break; 862 case SMSG_JS_IN_VAIN: 863 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 864 sch_msg_hdl_js_in_vain(recv,send); 865 break; 866 case SMSG_LOAD_REPORT: 867 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 868 sch_msg_hdl_load_report(recv,send); 869 break; 870 case SMSG_SET_JS_ROOT: 871 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 872 sch_msg_hdl_set_js_root(recv,send); 873 break; 874 case SMSG_JS_AGAIN: 875 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 876 sch_msg_hdl_js_again(recv,send); 877 break; 878 case SMSG_IDLE_ENG: 879 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 880 sch_msg_hdl_idle_eng(recv,send); 881 break; 882 case SMSG_WAKE_ENG: 883 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 884 sch_msg_hdl_wake_eng(recv,send); 885 break; 886 case SMSG_TELL_IDLE: 887 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 888 sch_msg_hdl_tell_idle(recv,send); 889 break; 890 case SMSG_STOP_IDLE: 891 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 892 sch_msg_hdl_stop_idle(recv,send); 893 break; 894 case SMSG_IDLE_TOLD: 895 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 896 sch_msg_hdl_idle_told(recv,send); 897 break; 898 case SMSG_LMP: 899 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 900 sch_msg_hdl_lmp(recv,send); 901 break; 902 case SMSG_REDUCE_WK_UP: 903 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 904 sch_msg_hdl_reduce_wk_up(recv,send); 905 break; 906 case SMSG_REDUCE_WK_DN: 907 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 908 sch_msg_hdl_reduce_wk_dn(recv,send); 909 break; 910 case SMSG_ENGINE_MIGRATE: 911 assert(mdt_type == Scheduler(port)->smsg_type[0][0]); 912 sch_msg_hdl_engine_migrate(recv,send); 913 break; 914 915 case SMSG_CUT_OK: 916 assert(mdt_type == Scheduler(port)->smsg_type[0][1]); 917 sch_msg_hdl_cut_ok(recv,send,((smsg01_t *)data)->i1); 918 break; 919 case SMSG_INIT_LODGE: 920 assert(mdt_type == Scheduler(port)->smsg_type[0][1]); 921 sch_msg_hdl_init_lodge(recv,send, ((smsg01_t *)data)->i1); 922 break; 923 924 case SMSG_JS_SUCCESS: 925 assert(mdt_type == Scheduler(port)->smsg_type[0][2]); 926 sch_msg_hdl_js_success(recv, send, 927 ((smsg02_t *)data)->i1, ((smsg02_t *)data)->i2); 928 break; 929 930 case SMSG_CUT: 931 assert(mdt_type == Scheduler(port)->smsg_type[1][0]); 932 sch_msg_hdl_cut(recv,send,&(((smsg10_t *)data)->t1)); 933 break; 934 case SMSG_LODGE: 935 assert(mdt_type == Scheduler(port)->smsg_type[1][0]); 936 sch_msg_hdl_lodge(recv,send,&(((smsg10_t *)data)->t1)); 937 break; 938 case SMSG_CHOP: 939 assert(mdt_type == Scheduler(port)->smsg_type[1][0]); 940 sch_msg_hdl_chop(recv,send,&(((smsg10_t *)data)->t1)); 941 break; 942 case SMSG_LODGE_IDLE: 943 assert(mdt_type == Scheduler(port)->smsg_type[1][0]); 944 sch_msg_hdl_lodge_idle(recv,send,&(((smsg10_t *)data)->t1)); 945 break; 946 case SMSG_JS_PROLOGUE: 947 assert(mdt_type == Scheduler(port)->smsg_type[1][0]); 948 sch_msg_hdl_js_prologue(recv,send, &(((smsg10_t *)data)->t1)); 949 break; 950 951 case SMSG_JS_TRUST: 952 assert(mdt_type == Scheduler(port)->smsg_type[1][2]); 953 sch_msg_hdl_js_trust(recv, send, &(((smsg12_t *)data)->t1), 954 ((smsg12_t *)data)->i1, ((smsg12_t *)data)->i2); 955 break; 956 957 case SMSG_JS_TRAV_UP: 958 assert(mdt_type == Scheduler(port)->smsg_type[2][0]); 959 sch_msg_hdl_js_trav_up(recv,send, 960 &(((smsg20_t *)data)->t1), &(((smsg20_t *)data)->t2)); 961 break; 962 case SMSG_JS_TRAV_DN: 963 assert(mdt_type == Scheduler(port)->smsg_type[2][0]); 964 sch_msg_hdl_js_trav_dn(recv,send, 965 &(((smsg20_t *)data)->t1), &(((smsg20_t *)data)->t2)); 966 break; 967 case SMSG_JS_INSTALL_FL: 968 assert(mdt_type == Scheduler(port)->smsg_type[2][0]); 969 sch_msg_hdl_js_install_fl(recv,send, 970 &(((smsg20_t *)data)->t1), &(((smsg20_t *)data)->t2)); 971 break; 972 973 case SMSG_STRAIGHTEN: 974 assert(mdt_type == Scheduler(port)->smsg_type[2][1]); 975 sch_msg_hdl_straighten(recv,send, 976 &(((smsg21_t *)data)->t1), &(((smsg21_t *)data)->t2), ((smsg21_t *)data)->i1); 977 break; 978 979 case SMSG_JS_INSTALL: 980 assert(mdt_type == Scheduler(port)->smsg_type[3][0]); 981 sch_msg_hdl_js_install(recv,send, 982 &(((smsg30_t *)data)->t1), &(((smsg30_t *)data)->t2), &(((smsg30_t *)data)->t3)); 983 break; 984 985 default: error("unknown scheduler message"); 986 } 987 /* throw away the handled message */ 988 ret = amsg_receive( 989 port, 990 (amsg_t *)0, 991 (amsg_data_t * *)0, 992 &mdt_type, 993 &mdt_count, 994 (amsg_option_t) 0 995 ); 996 assert(ret==AMSG_OK); 997 } 998} 999 1000 1001/* Interface functions called by Worker Management */ 1002 1003void sch_create_leaf(site, engine, leaf) 1004site_id_t site; 1005eng_handle_t engine; 1006st_handle_t **leaf; 1007{ 1008 void smsg_type_init(); 1009 void smsg_stat_init(); 1010 void sch_create_leaf0(); 1011 1012 /* initilize a template for a knot. */ 1013 knot_template->suspended = (st_susp_t *)0; 1014 PackSite(knot_template,site); 1015 knot_template->alive_twigs = 0; 1016 knot_template->nxtcls = 0; 1017 knot_template->nxtcls_b = 0; 1018 knot_template->hybrid = 0; 1019 knot_template->jroot = 0; 1020 knot_template->proot = 0; 1021 knot_template->local = 0; 1022 knot_template->tip = 1; 1023 knot_template->lock = 0; 1024 knot_template->trunk.info = 0; 1025 1026 /* register the various message types which will be sent and/or received 1027 ** via the scheduler port. 1028 */ 1029 smsg_type_init(site); 1030 1031 /* initialise the scheduler datastructure */ 1032 Scheduler(site)->port = site; 1033 Scheduler(site)->engine = engine; 1034 Scheduler(site)->load_report_eager = 0; 1035 Scheduler(site)->async_hdl = 0; 1036 Scheduler(site)->idling = 0; 1037 Scheduler(site)->waking = 0; 1038 Scheduler(site)->lmp = 0; 1039 Scheduler(site)->root_first = 1; 1040 Scheduler(site)->left_first = 1; 1041 1042 Scheduler(site)->max_to_publish = 5; 1043 1044 Scheduler(site)->edge_buffer.count = 0; 1045 Scheduler(site)->edge_buffer.head.trunk.next = 1046 Scheduler(site)->edge_buffer.head.trunk.prev = 1047 &(Scheduler(site)->edge_buffer.head.trunk); 1048 Simp_Initlock(&(Scheduler(site)->edge_buffer)); 1049 1050 Scheduler(site)->susp_buffer.count = 0; 1051 Scheduler(site)->susp_buffer.next = (st_susp_t *) 0; 1052 Simp_Initlock(&(Scheduler(site)->susp_buffer)); 1053 1054#if !defined(NO_SHORTCUT) 1055 Intrasite_Smsg(site) = 0; 1056#endif /* NO_SHORTCUT */ 1057 1058 /* reset scheduler message traffic statistics */ 1059 smsg_stat_init(site); 1060 InitSchOffset(site); 1061 *leaf = &(Scheduler(site)->leaf); 1062 sch_create_leaf0(site, (st_id_t *)*leaf); 1063 return; 1064} 1065 1066void sch_create_leaf0(site, leaf) 1067site_id_t site; 1068st_id_t *leaf; 1069{ 1070 Sch_Alloc_Knot(site,leaf); 1071 if (Sch_Lock(leaf)) { 1072 SetNalive(Trunk(leaf), ST_INIT); 1073 return; 1074 } else { 1075 assert(zero()); 1076 } 1077} 1078 1079 1080void sch_create_root(site, root_hdl) 1081site_id_t site; 1082st_handle_t *root_hdl; 1083{ 1084 st_id_t *root = (st_id_t *)root_hdl; 1085 Sch_Alloc_Knot(site,root); 1086 Knot(root)->tip = 0; 1087 Knot(root)->jroot = 1; 1088 *SupTree(root) = *(root); 1089 SetAlive(Trunk(root)); 1090 SetRich(Trunk(root)); 1091 SetEldest(Trunk(root)); 1092 return; 1093} 1094 1095void sch_genesis(root_hdl,leaf_hdl,twig_hdl,first) 1096st_handle_t *root_hdl, *leaf_hdl, *twig_hdl; 1097int first; 1098{ 1099 st_id_t *root = (st_id_t *)root_hdl; 1100 st_id_t *leaf = (st_id_t *)leaf_hdl; 1101 st_id_t *twig = (st_id_t *)twig_hdl; 1102 1103 Scheduler(Site(leaf))->root = *root_hdl; 1104 1105 if (first) { 1106#if defined(INITIAL_SCHTR) 1107 /* set the scheduler trace */ 1108 (void) global_flags(0, SCH_TRACE_FLAG); 1109#endif /* INITIAL_SCHTR */ 1110 Add_Alive_Twig_Next(twig,leaf,Knot(root),Trunk(root)->prev); 1111 Twig(twig)->info = Trunk(leaf)->info = Trunk(root)->info; 1112 Knot(leaf)->jroot = Knot(root)->jroot; 1113 Sch_Event_Notify2("S_GENESIS", "null ", twig, leaf); 1114 } else { 1115 *twig = *root; 1116 Sch_Event_Notify2("NEW_COMER", "null ", twig, leaf); 1117 } 1118 1119 *SupTree(leaf) = *twig; 1120 return; 1121} 1122 1123void sch_init_lodge(site,wm,leaf) 1124aport_id_t site; 1125int wm; 1126st_handle_t *leaf; 1127{ 1128 st_id_t *root = (st_id_t *)&Scheduler(site)->root; 1129 assert(SchRoot(root) && Alive(Trunk(root))); 1130 if (Sch_Lock(root)) { 1131 st_id_t twig; 1132 Add_Lodge_Twig(&twig,(st_id_t *)leaf,Knot(root)); 1133 wm_init_lodged(wm, (st_handle_t *)&twig); 1134 Sch_Unlock(root); 1135 } else { 1136 sch_msg_snd_init_lodge(root,(st_id_t *)leaf, wm); 1137 } 1138 return; 1139} 1140 1141 1142/* Interface functions called by Engines */ 1143 1144void sch_sync_msg_hdls(leaf_hdl) 1145const st_handle_t *leaf_hdl; 1146{ 1147 int ok; 1148 site_id_t site = Site((st_id_t *)leaf_hdl); 1149 1150 Sch_Unlock(SiteLeaf(site)); 1151 sch_async_msg_hdls(site, 0); 1152 1153 Disable_Int(); 1154 ok = Sch_Lock(SiteLeaf(site)); 1155 Enable_Int(); 1156 assert(ok); 1157 return; 1158} 1159 1160void sch_backtrack(leaf_hdl) 1161const st_handle_t *leaf_hdl; 1162{ 1163 int ok; 1164 st_id_t *leaf = (st_id_t *) leaf_hdl; 1165 st_id_t parent; parent = *SupTree(leaf); 1166 if (Life(Trunk(leaf))==ST_INIT) { /* ## INITIAL connection */ 1167 SetNalive(Trunk(leaf),ST_LODGED); 1168 Smsg_ShortCut_End(leaf, &parent, 1169 sch_msg_hdl_js_trav_up(&parent,leaf,&parent,leaf), 1170 sch_msg_snd_js_trav_up(&parent,leaf,&parent,leaf) 1171 ); 1172 goto _return; 1173 } else { 1174 assert(Alive(Trunk(leaf))); 1175 SetNalive(Trunk(leaf),ST_BACKTRACK); 1176 1177 /* imagine: the leaf is jsroot, and its parent is a worker_boundry 1178 ** node which has to be taken by a leaf which might be currently 1179 ** suspended to this backtracking leaf. This has happened: all of 1180 ** workers become suddenly inactive. Thus added the following check. 1181 */ 1182 if (Suspended(leaf)) { 1183 void relocate_suspended(); 1184 assert(JsRoot(leaf)); 1185 relocate_suspended(leaf); 1186 } 1187 ResetJsRoot(leaf); 1188 if (Scheduler(Site(leaf))->idling) { /* ## Idling */ 1189 /* idling bit remains, as not known yet if idle-tell accepted */ 1190 Smsg_ShortCut_End(leaf, &parent, 1191 sch_msg_hdl_tell_idle(&parent, leaf), 1192 sch_msg_snd_tell_idle(&parent, leaf) 1193 ); 1194 } else { 1195 Smsg_ShortCut_End(leaf, &parent, 1196 sch_msg_hdl_backtrack(&parent, leaf), 1197 sch_msg_snd_backtrack(&parent, leaf) 1198 ); 1199 } 1200_return: 1201 Disable_Int(); 1202 ok = Sch_Lock(leaf); 1203 Enable_Int(); 1204 assert(ok); 1205 return; 1206 } 1207} 1208 1209void sch_cut(leaf_hdl,parent_hdl) 1210const st_handle_t *leaf_hdl, *parent_hdl; 1211{ 1212 st_id_t olf, nlf, parent; 1213 site_id_t site = Site(leaf_hdl); 1214 int ok; 1215 olf = *(st_id_t *) leaf_hdl; 1216 parent = *(st_id_t *) parent_hdl; 1217 1218 if (Suspended(&olf)) { 1219 void relocate_suspended(); 1220 assert(JsRoot(&olf)); 1221 relocate_suspended(&olf); 1222 } 1223 ResetJsRoot(&olf); 1224 Sch_Alloc_Knot(site,&nlf); 1225 Reincarnat(&olf,&nlf); 1226 NewSiteLeaf(&nlf); 1227 Smsg_ShortCut_End(&olf, &parent, 1228 sch_msg_hdl_cut(&parent, &olf, &nlf), 1229 sch_msg_snd_cut(&parent, &olf, &nlf) 1230 ); 1231 Disable_Int(); 1232 ok = Sch_Lock(SiteLeaf(site)); assert(ok); 1233 Enable_Int(); 1234 return; 1235} 1236 1237/* these two sch-interface functions differ from others: 1238** they do return, without checking scheduler message queue 1239*/ 1240 1241void sch_load_report(leaf_hdl) 1242const st_handle_t *leaf_hdl; 1243{ 1244 st_id_t * leaf = (st_id_t *)leaf_hdl; 1245 if (!Rich(Trunk(leaf))) { 1246 assert(!JsRoot(leaf)); 1247 SetRich(Trunk(leaf)); 1248 Smsg_ShortCut_Mid(leaf, SupTree(leaf), 1249 sch_msg_hdl_load_report(SupTree(leaf),leaf), 1250 sch_msg_snd_load_report(SupTree(leaf),leaf) 1251 ); 1252 return; 1253 } else if (Suspended(leaf)) { 1254/* 1255 void loadreport_and_publish(); 1256 st_id_t olf; olf = *leaf; 1257 assert(JsRoot(leaf)); 1258 loadreport_and_publish(&olf); 1259 return; 1260*/ 1261 /* as there exists a bug that a suspended leaf has a chopped 1262 ** common ancestor which should not happen, I have to comment 1263 ** out the above code (lll before 3.5.2 release). 1264 */ 1265 assert(JsRoot(leaf)); 1266 Sch_WakeUp_Suspended(leaf); 1267 return; 1268 } 1269} 1270 1271void loadreport_and_publish(olf) 1272st_id_t *olf; 1273{ 1274 site_id_t site = Site(olf); 1275 int remains, published, ok=0; 1276 st_id_t *nlf; 1277 st_susp_t *x = Suspended(olf); 1278 int max = (Scheduler(site)->root_first)?Scheduler(site)->max_to_publish:9999; 1279 1280 /* calculate the number of suspended leaves */ 1281 while (x) { 1282 ok++; 1283 x = x->next; 1284 } 1285 if (ok > max) max = ok; 1286 x = Suspended(olf); 1287 Suspended(olf) = (st_susp_t *)0; 1288 if (!(published=eng_publish(LeafEngine(olf), max, &remains))) { 1289 /* nothing published. it can happen when some ad hoc parallel chpts 1290 ** are published or engine is crazy with a false load report 1291 */ 1292 nlf = SiteLeaf(site); 1293 Suspended(nlf) = x; 1294 while (!ComnKnot(nlf,olf)) { /* it is safe as no upward messages */ 1295 SetJsRoot(nlf); 1296 nlf = SupTree(nlf); 1297 } 1298 return; 1299 } else { 1300 st_id_t twig; 1301 1302 /* Published alternatives will wholelly be at the disposal of the current 1303 ** allocation. Some can be booked owing to asynchronous smsg-handling, 1304 ** but the relevant installations will not be handled before this function 1305 ** finishes, since the leaf is locked. 1306 */ 1307 assert(!(remains && published<max)); 1308 /* lock the published to simplify the handling */ 1309 nlf = SiteLeaf(site); 1310 do { 1311 nlf = SupTree(nlf); 1312 ok = Sch_Lock(nlf); 1313 } while (!ComnKnot(nlf,olf)); 1314 Suspended(olf) = x; 1315 if (!Alive(Trunk(olf))) { /* already chopped */ 1316 void relocate_suspended(); 1317 relocate_suspended(olf); 1318 nlf = SiteLeaf(site); 1319 do { 1320 nlf = SupTree(nlf); 1321 Sch_Unlock(nlf); 1322 } while (!ComnKnot(nlf,olf)); 1323 return; 1324 } 1325 nlf = SiteLeaf(site); 1326 while (x) { 1327 while (Exhausted(nlf) && !ComnKnot(nlf,olf)) { 1328 nlf = SupTree(nlf); 1329 if (!remains) { 1330 SetPoor(Twig(nlf)); 1331 SetPoor(Trunk(SubTree(nlf))); 1332 } 1333 } 1334 if (Exhausted(nlf)) break; 1335 Bk_NextClause0(nlf); 1336 Add_Lodge_Twig(&twig, &(x->leaf), Knot(nlf)); 1337 eng_donate_state(LeafEngine(SiteLeaf(site)), (st_handle_t *)&twig, 1338 (st_handle_t *)&(x->coma), (st_handle_t *)&(x->leaf)); 1339 Scheduler(site)->state_donate++; 1340 Suspended(olf) = x->next; 1341 Sch_Gc_Suspended(site,x); 1342 x = Suspended(olf); 1343 } 1344 if (Suspended(olf)) { 1345 assert(!remains); 1346 assert(ComnKnot(nlf,olf)); 1347 } 1348 nlf = SiteLeaf(site); 1349 do { 1350 nlf = SupTree(nlf); 1351 Sch_Unlock(nlf); 1352 } while (!ComnKnot(nlf,olf)); 1353 return; 1354 } 1355} 1356 1357void sch_load_publish_one(leaf_hdl, alt, parent_hdl, hybrid) 1358const st_handle_t *leaf_hdl; 1359st_handle_t *parent_hdl; 1360int alt, hybrid; 1361{ 1362 st_id_t * olf = (st_id_t *)leaf_hdl; 1363 st_id_t * parent = (st_id_t *)parent_hdl; 1364 1365 st_id_t nlf; 1366 1367 assert(Rich(Trunk(olf))); 1368 /* make sure the engine follows the convention: 1369 * when an engine rejects a job request, it is expected to 1370 * issue a job-report before it actually publishes anything. 1371 * It is to avoid the situation that suspended request flows 1372 * are buried within ancestors. A job-report will wake the 1373 * suspended request flows. 1374 */ 1375 assert(!JsRoot(olf)||!Suspended(olf)); 1376 Sch_Alloc_Knot(Site(olf), &nlf); 1377 Add_Alive_Twig_Next(parent,&nlf,Knot(olf),Trunk(olf)->prev); 1378 Twig(parent)->info = Trunk(&nlf)->info = Trunk(olf)->info; 1379 if (alt > 0) { 1380 Knot(olf)->nxtcls = Knot(olf)->nxtcls_b = alt; 1381 } else { /* a dummy node */ 1382 SetPsRoot(olf); 1383 if (alt==(-1)) /* a reserve the sequential choice points for 1384 ** the local worker 1385 */ 1386 SetLocal(olf); 1387 } 1388 Hybrid(olf) = hybrid; 1389 Knot(olf)->tip = 0; 1390 *SupTree(&nlf) = *parent; 1391 1392 Sch_Event_Notify3("LF_SPROUT","alt ",SupTree(parent),parent,&nlf); 1393 1394 if (Sch_Lock(&nlf)) { 1395 Sch_Unlock(olf); 1396 NewSiteLeaf(&nlf); 1397 } else { 1398 assert(zero()); 1399 } 1400} 1401 1402/* Scheduler message handlers */ 1403/* Covention: the subject node/leaf, often named as 'self', has been locked, 1404 before the handler is called; 1405 they should be unlocked before the handler returns. 1406*/ 1407 1408 1409/* Up */ 1410static void sch_msg_hdl_backtrack(self, leaf) 1411st_id_t *self, *leaf; 1412{ 1413 void sch_msg_hdl_backtrack_(); 1414 1415 Smsg_Hdl_Notify(SMSG_BACKTRACK,self,leaf); 1416 if (Alive(Trunk(self))) { 1417 sch_msg_hdl_backtrack_(self, leaf); 1418 return; 1419 } else { 1420 assert(Chopped(Trunk(self))); 1421 Sch_Unlock(self); 1422 return; 1423 } 1424} 1425 1426void sch_msg_hdl_backtrack_(self, leaf) 1427st_id_t *self, *leaf; 1428{ 1429 int alt = Bk_NextClause(self); alt = Tk_NextClause(self); 1430 UpdateLmp(self); 1431 AliveTwigs(self)--; 1432 SetNalive(Twig(self),ST_LODGED); 1433 1434/* ## schedule an alternative available 1435** we do not care about special nodes (e.g. proot,sroot) as they 1436** created as dummy one, thus with no alternative 1437*/ 1438 if (alt && (AliveTwigs(self) || !Exhausted(self))) { 1439 Quit_Chain(Twig(self)); 1440 Join_Chain_Next(Twig(self),Trunk(self)->prev); 1441 SetAlive(Twig(self)); 1442 AliveTwigs(self)++; 1443 SetPoor(Twig(self)); 1444 Smsg_ShortCut_End(self, leaf, 1445 sch_msg_hdl_js_success(leaf, self, alt, Twig(self)->info), 1446 sch_msg_snd_js_success(leaf, self, alt, Twig(self)->info) 1447 ); 1448 return; 1449 } else if (alt || (!AliveTwigs(self)&&(ComnSite(self,leaf)||!Local(self)))) { 1450 assert(!SchRoot(self)); 1451 SetNalive(Trunk(self), ST_DYING); 1452 if (!alt && Hybrid(self)) alt = -1; 1453 Smsg_ShortCut_End(self, SupTree(self), 1454 sch_msg_hdl_straighten(SupTree(self),self,leaf,self,alt), 1455 sch_msg_snd_straighten(SupTree(self),self,leaf,self,alt) 1456 ); 1457 return; 1458 } else if (!AliveTwigs(self) && Suspended(self)) { 1459 st_susp_t **x = &Suspended(self); 1460 do { /* only when the local leaf is idling, this loop can finish 1461 without breaking */ 1462 if (ComnSite(self,&((*x)->leaf))) { 1463 st_susp_t *y = *x; 1464 *x = y->next; 1465 SetNalive(Trunk(self), ST_DYING); 1466 if (Hybrid(self)) alt = -1; 1467 Smsg_ShortCut_Mid(self, SupTree(self), 1468 sch_msg_hdl_straighten(SupTree(self),self,&(y->leaf),self,alt), 1469 sch_msg_snd_straighten(SupTree(self),self,&(y->leaf),self,alt) 1470 ); 1471 Sch_Gc_Suspended(Site(self),y); 1472 break; 1473 } else { 1474 x = &((*x)->next); 1475 } 1476 } while (*x); 1477 } 1478 /* ## job-search prologue. */ 1479 if (ComnSite(self,SupTree(self)) && !PoorSpine(self) && !JsRoot(self) && 1480 !(Local(self)&&ComnSite(self,leaf))) { 1481 Smsg_ShortCut_End(self,SupTree(self), 1482 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 1483 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 1484 ); 1485 } else { 1486 st_id_t *coma = self; 1487 SetPoorSpine(self); 1488 Sch_JS_Trav_Down(self,coma,leaf); 1489 Sch_JS_Trav_Up(self,coma,leaf); 1490 } 1491} 1492 1493 1494/* Up */ 1495static void sch_msg_hdl_straighten(self,child,leaf,parent,alt) 1496st_id_t *self, *child, *leaf, *parent; 1497int alt; 1498{ 1499 st_id_t twig; 1500 Smsg_Hdl_Notify(SMSG_STRAIGHTEN,self,child); 1501 if (Alive(Twig(self))) { 1502 AliveTwigs(self)--; 1503 if (!Exhausted(self)||(AliveTwigs(self)||PsRoot(self)||SchRoot(self))) { 1504 if (alt) { 1505 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Twig(self)); 1506 Twig(&twig)->info = Twig(self)->info; 1507 if (JsRoot(self) && Monad(self) && !Suspended(self)) { 1508 SetRich(Twig(&twig)); 1509 Smsg_ShortCut_Mid(&twig,leaf, 1510 sch_msg_hdl_js_trust(leaf,&twig,parent,alt,Twig(&twig)->info), 1511 sch_msg_snd_js_trust(leaf,&twig,parent,alt,Twig(&twig)->info) 1512 ); 1513 Smsg_ShortCut_Mid(&twig,leaf, 1514 sch_msg_hdl_set_js_root(leaf, &twig), 1515 sch_msg_snd_set_js_root(leaf, &twig) 1516 ); 1517 } else { 1518 SetPoor(Twig(&twig)); 1519 Smsg_ShortCut_Mid(&twig,leaf, 1520 sch_msg_hdl_js_trust(leaf,&twig,parent,alt,Twig(&twig)->info), 1521 sch_msg_snd_js_trust(leaf,&twig,parent,alt,Twig(&twig)->info) 1522 ); 1523 } 1524 } else if (!Exhausted(self)) { 1525 alt = Bk_NextClause(self); 1526 alt = Tk_NextClause(self); 1527 if (!Exhausted(self)||(AliveTwigs(self)||PsRoot(self)||SchRoot(self))) { 1528 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Twig(self)); 1529 Twig(&twig)->info = Twig(self)->info; 1530 SetPoor(Twig(self)); 1531 Smsg_ShortCut_Mid(&twig, leaf, 1532 sch_msg_hdl_js_success(leaf,&twig,alt,Twig(&twig)->info), 1533 sch_msg_snd_js_success(leaf,&twig,alt,Twig(&twig)->info) 1534 ); 1535 } else { 1536 SetNalive(Trunk(self),ST_DYING); 1537 Smsg_ShortCut_Mid(self, SupTree(self), 1538 sch_msg_hdl_straighten(SupTree(self),self,leaf,self,alt), 1539 sch_msg_snd_straighten(SupTree(self),self,leaf,self,alt) 1540 ); 1541 } 1542 } else if (PsRoot(self) && !AliveTwigs(self)) { 1543 if (!Local(self) || ComnSite(self,leaf)) { 1544 SetNalive(Trunk(self),ST_DYING); 1545 if (Hybrid(self)) alt = -1; 1546 Smsg_ShortCut_Mid(self, SupTree(self), 1547 sch_msg_hdl_straighten(SupTree(self),self,leaf,self,alt), 1548 sch_msg_snd_straighten(SupTree(self),self,leaf,self,alt) 1549 ); 1550 } else { 1551 if (Suspended(self)) { 1552 st_susp_t **x = &Suspended(self); 1553 do { /* only when the local leaf is idling, this loop can 1554 finish without breaking */ 1555 if (ComnSite(self,&((*x)->leaf))) { 1556 st_susp_t *y = *x; 1557 *x = y->next; 1558 SetNalive(Trunk(self), ST_DYING); 1559 if (Hybrid(self)) alt = -1; 1560 Smsg_ShortCut_Mid(self, SupTree(self), 1561 sch_msg_hdl_straighten(SupTree(self),self,&(y->leaf),self,alt), 1562 sch_msg_snd_straighten(SupTree(self),self,&(y->leaf),self,alt) 1563 ); 1564 Sch_Gc_Suspended(Site(self),y); 1565 break; 1566 } else { 1567 x = &((*x)->next); 1568 } 1569 } while (*x); 1570 } 1571 Add_Lodge_Twig(&twig,leaf,Knot(self)); 1572 Smsg_ShortCut_Mid(&twig, leaf, 1573 sch_msg_hdl_lodged(leaf, &twig), 1574 sch_msg_snd_lodged(leaf, &twig) 1575 ); 1576 } 1577 } else if (Local(self)&&ComnSite(self,leaf)) { 1578 st_susp_t *x; 1579 Sch_Alloc_Suspended(Site(self), x); 1580 x->next = Suspended(self); 1581 x->leaf = *(leaf); 1582 x->coma = *(self); 1583 Suspended(self) = x; 1584 } else if (!JsRoot(self) && !PoorSpine(self) 1585 && ComnSite(self,leaf) 1586 && ComnSite(self,SubTree(self)) 1587 && ComnSite(self,SupTree(self))) { 1588 Smsg_ShortCut_Mid(self, SupTree(self), 1589 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 1590 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 1591 ); 1592 } else { 1593 Add_Lodge_Twig(&twig,leaf,Knot(self)); 1594 Smsg_ShortCut_Mid(&twig, leaf, 1595 sch_msg_hdl_lodged(leaf, &twig), 1596 sch_msg_snd_lodged(leaf, &twig) 1597 ); 1598 } 1599 SetNalive(Twig(self),ST_CHOPPED); 1600 Smsg_ShortCut_End(self, SubTree(self), 1601 sch_msg_hdl_chop(SubTree(self),self,self), 1602 sch_msg_snd_chop(SubTree(self),self,self) 1603 ); 1604 return; 1605 } else { /* need resume sequential chpts: further up */ 1606 SetNalive(Trunk(self),ST_DYING); 1607 SetNalive(Twig(self),ST_DYING); 1608 if (!alt && Hybrid(self)) alt = -1; 1609 Smsg_ShortCut_End(self, SupTree(self), 1610 sch_msg_hdl_straighten(SupTree(self),self,leaf,parent,alt), 1611 sch_msg_snd_straighten(SupTree(self),self,leaf,parent,alt) 1612 ); 1613 return; 1614 } 1615 } else { 1616 assert(!Alive(Trunk(self))); /* i.e. whole subtree chopped */ 1617 if (ComnSite(self,SupTree(self)) && ComnSite(self,leaf) && 1618 !PoorSpine(self) && !PoorSpine(SupTree(self))) { 1619 Smsg_ShortCut_End(self, SupTree(self), 1620 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 1621 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 1622 ); 1623 } else { 1624 Smsg_ShortCut_End(self,SupTree(self), 1625 sch_msg_hdl_lodge(SupTree(self),self,leaf), 1626 sch_msg_snd_lodge(SupTree(self),self,leaf) 1627 ); 1628 } 1629 } 1630} 1631 1632/* Up */ 1633static void sch_msg_hdl_js_prologue(self, child, leaf) 1634st_id_t *self, *child, *leaf; 1635{ 1636 Smsg_Hdl_Notify(SMSG_JS_PROLOGUE, self, child); 1637 if (!Exhausted(self)) { /* it does not care about the twig state */ 1638 st_id_t twig; 1639 int alt = Bk_NextClause(self); /* value not interesting */ 1640 alt = Tk_NextClause(self); 1641 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Trunk(self)->prev); 1642 CheckLmp(&twig); 1643 SetPoor(Twig(&twig)); 1644 Smsg_ShortCut_End(&twig, leaf, 1645 sch_msg_hdl_js_success(leaf,&twig,alt,Twig(&twig)->info), 1646 sch_msg_snd_js_success(leaf,&twig,alt,Twig(&twig)->info) 1647 ); 1648 return; 1649 } 1650 if (Alive(Trunk(self)) && (JsRoot(self) || PoorSpine(self) || 1651 !ComnSite((self),SupTree(self)) || PoorSpine(SupTree(self)) || 1652 (ComnSite(self,leaf) && Local(self)))) { 1653 Smsg_ShortCut_End(self,leaf, 1654 sch_msg_hdl_js_in_vain(leaf,self), 1655 sch_msg_snd_js_in_vain(leaf,self) 1656 ); 1657 return; 1658 } else if (ComnSite((self),SupTree(self))) { 1659 Smsg_ShortCut_End(self, SupTree(self), 1660 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 1661 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 1662 ); 1663 return; 1664 } else { 1665 Smsg_ShortCut_End(self, SupTree(self), 1666 sch_msg_hdl_lodge(SupTree(self),self,leaf), 1667 sch_msg_snd_lodge(SupTree(self),self,leaf) 1668 ); 1669 return; 1670 } 1671} 1672 1673/* Down */ 1674static void sch_msg_hdl_js_success(leaf,parent,nxtcls,info) 1675st_id_t *leaf, *parent; 1676int nxtcls, info; 1677{ 1678 Smsg_Hdl_Notify(SMSG_JS_SUCCESS, leaf,parent); 1679 eng_backtrack(LeafEngine(leaf),(st_handle_t *)parent,(unsigned) nxtcls); 1680 1681 switch (Life(Trunk(leaf))) { 1682 case ST_CUT: 1683 Smsg_ShortCut_Mid(leaf, Corpse(leaf), 1684 sch_msg_hdl_dec_corpse(Corpse(leaf),leaf), 1685 sch_msg_snd_dec_corpse(Corpse(leaf),leaf) 1686 ); 1687 break; 1688 case ST_BACKTRACK: 1689 case ST_LODGED: 1690 case ST_CHOPPED: 1691 if (ComnNode(SupTree(leaf),parent)) 1692 break; 1693 Smsg_ShortCut_Mid(leaf, SupTree(leaf), 1694 sch_msg_hdl_withered(SupTree(leaf),leaf), 1695 sch_msg_snd_withered(SupTree(leaf),leaf) 1696 ); 1697 break; 1698 default: 1699 error("illegal leaf type"); 1700 } 1701 Trunk(leaf)->info = info; 1702 assert(!Suspended(leaf)); 1703 *SupTree(leaf) = *parent; 1704 Sch_Unlock(leaf); 1705 return; 1706} 1707 1708/* Down */ 1709static void sch_msg_hdl_js_trust(leaf,parent,parent_nxtcls,nxtcls,info) 1710st_id_t *leaf, *parent, *parent_nxtcls; 1711int nxtcls, info; 1712{ 1713 Smsg_Hdl_Notify(SMSG_JS_TRUST, leaf,parent); 1714 /* the leaf could in a lodged state when a 'Local' node becomes resumable */ 1715 assert(Life(Trunk(leaf))==ST_BACKTRACK || Life(Trunk(leaf))==ST_LODGED); 1716 assert(!Suspended(leaf)); 1717 Smsg_ShortCut_Mid(leaf, SupTree(leaf), 1718 sch_msg_hdl_withered(SupTree(leaf),leaf), 1719 sch_msg_snd_withered(SupTree(leaf),leaf) 1720 ); 1721 if (!ComnNode(parent_nxtcls,SupTree(leaf))) { 1722 eng_backtrack(LeafEngine(leaf), (st_handle_t *)parent_nxtcls, 0); 1723 } 1724 if (nxtcls>0) { 1725 assert(nxtcls==1); 1726 eng_trust(LeafEngine(leaf),(unsigned) nxtcls); /* keep this order with next line */ 1727 eng_undo_publish(LeafEngine(leaf),(st_handle_t *)parent); 1728 } else { 1729 eng_undo_publish(LeafEngine(leaf), (st_handle_t *)parent); 1730 eng_fail(LeafEngine(leaf)); 1731 } 1732 *SupTree(leaf) = *parent; 1733 Trunk(leaf)->info = info; 1734 if (!Rich(Trunk(leaf))) ResetJsRoot(leaf); 1735 Sch_Unlock(leaf); 1736 return; 1737} 1738 1739 1740static void sch_msg_hdl_dec_corpse(old,new) 1741st_id_t *old, *new; 1742{ 1743 Smsg_Hdl_Notify(SMSG_DEC_CORPSE,old,new); 1744 switch (Life(Trunk(old))) { 1745 case ST_DYING: 1746 SetNalive(Trunk(old), ST_DEAD); 1747 Sch_Unlock(old); 1748 return; 1749 case ST_CHOPPED: 1750 Smsg_ShortCut_End(old, SupTree(old), 1751 sch_msg_hdl_withered(SupTree(old),old), 1752 sch_msg_snd_withered(SupTree(old),old) 1753 ); 1754 Sch_Gc_Knot(old); 1755 return; 1756 default: error("illegal leaf type"); 1757 } 1758} 1759 1760/* Up */ 1761static void sch_msg_hdl_cut(self, olf, leaf) 1762st_id_t *self, *olf, *leaf; 1763{ 1764 st_id_t twig; 1765 Smsg_Hdl_Notify(SMSG_CUT, self, olf); 1766 if (Alive(Twig(self))) { /* the cut wins */ 1767 AliveTwigs(self)--; 1768 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Twig(self)); 1769 Twig(&twig)->info = Twig(self)->info; 1770 if (JsRoot(self) && Monad(self) && !Suspended(self)) { 1771 SetRich(Twig(&twig)); 1772 Smsg_ShortCut_Mid(&twig,leaf, 1773 sch_msg_hdl_cut_ok(leaf,&twig,Twig(&twig)->info), 1774 sch_msg_snd_cut_ok(leaf,&twig,Twig(&twig)->info) 1775 ); 1776 Smsg_ShortCut_Mid(&twig,leaf, 1777 sch_msg_hdl_set_js_root(leaf, &twig), 1778 sch_msg_snd_set_js_root(leaf, &twig) 1779 ); 1780 } else { 1781 SetPoor(Twig(&twig)); 1782 Smsg_ShortCut_Mid(&twig,leaf, 1783 sch_msg_hdl_cut_ok(leaf,&twig,Twig(&twig)->info), 1784 sch_msg_snd_cut_ok(leaf,&twig,Twig(&twig)->info) 1785 ); 1786 } 1787 SetNalive(Twig(self),ST_CHOPPED); 1788 Smsg_ShortCut_End(self, SubTree(self), 1789 sch_msg_hdl_chop(SubTree(self), self, self), 1790 sch_msg_snd_chop(SubTree(self), self, self) 1791 ); 1792 return; 1793 } else if (Exhausted(self)) { 1794 Add_Lodge_Twig(&twig,leaf,Knot(self)); 1795 Smsg_ShortCut_End(&twig,leaf, 1796 sch_msg_hdl_lodged(leaf,&twig), 1797 sch_msg_snd_lodged(leaf,&twig) 1798 ); 1799 return; 1800 } else { 1801 int alt = Bk_NextClause(self); 1802 alt = Tk_NextClause(self); 1803 Add_Alive_Twig_Next(&twig,leaf,Knot(self), Trunk(self)->prev); 1804 CheckLmp(&twig); 1805 SetPoor(Twig(&twig)); 1806 Smsg_ShortCut_End(&twig, leaf, 1807 sch_msg_hdl_js_success(leaf, &twig, alt, Twig(&twig)->info), 1808 sch_msg_snd_js_success(leaf, &twig, alt, Twig(&twig)->info) 1809 ); 1810 return; 1811 } 1812} 1813 1814/* Down */ 1815static void sch_msg_hdl_cut_ok(leaf, parent, info) 1816st_id_t *leaf, *parent; 1817int info; 1818{ 1819 Smsg_Hdl_Notify(SMSG_CUT_OK, leaf, parent); 1820 assert(Life(Trunk(leaf)) == ST_CUT); 1821 Smsg_ShortCut_Mid(leaf,Corpse(leaf), 1822 sch_msg_hdl_dec_corpse(Corpse(leaf),leaf), 1823 sch_msg_snd_dec_corpse(Corpse(leaf),leaf) 1824 ); 1825 *SupTree(leaf) = *parent; 1826 Trunk(leaf)->info = info; 1827 eng_cut_ok(LeafEngine(leaf), (st_handle_t *)parent); 1828 assert(!Suspended(leaf)); 1829 Sch_Unlock(leaf); 1830 return; 1831} 1832 1833/* Up */ 1834static void sch_msg_hdl_init_lodge(root, leaf, wm) 1835st_id_t *root, *leaf; 1836int wm; 1837{ 1838 st_id_t twig; 1839 Smsg_Hdl_Notify(SMSG_INIT_LODGE,root,leaf); 1840 assert(SchRoot(root) && Alive(Trunk(root))); 1841 Add_Lodge_Twig(&twig,leaf,Knot(root)); 1842 wm_init_lodged(wm, (st_handle_t *)&twig); 1843 Sch_Unlock(root); 1844} 1845 1846/* Up */ 1847static void sch_msg_hdl_lodge(self, child, leaf) 1848st_id_t *self, *child, *leaf; 1849{ 1850 Smsg_Hdl_Notify(SMSG_LODGE, self, child); 1851 if (AliveTwigs(self)) { 1852 st_id_t twig; 1853 if (Exhausted(self)) { 1854 Add_Lodge_Twig(&twig,leaf,Knot(self)); 1855 Smsg_ShortCut_End(&twig, leaf, 1856 sch_msg_hdl_lodged(leaf, &twig), 1857 sch_msg_snd_lodged(leaf, &twig) 1858 ); 1859 return; 1860 } else { 1861 int alt = Bk_NextClause(self); /* value not interesting */ 1862 alt = Tk_NextClause(self); 1863 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Trunk(self)->prev); 1864 CheckLmp(&twig); 1865 SetPoor(Twig(&twig)); 1866 Smsg_ShortCut_End(&twig, leaf, 1867 sch_msg_hdl_js_success(leaf,&twig,alt,Twig(&twig)->info), 1868 sch_msg_snd_js_success(leaf,&twig,alt,Twig(&twig)->info) 1869 ); 1870 return; 1871 } 1872 } else if (Alive(Trunk(self))&&Local(self)&&ComnSite(self,leaf)) { 1873 int alt = Hybrid(self) ? (-1):0; 1874 SetNalive(Trunk(self), ST_DYING); 1875 Smsg_ShortCut_End(self,SupTree(self), 1876 sch_msg_hdl_straighten(SupTree(self),self,leaf,self,alt), 1877 sch_msg_snd_straighten(SupTree(self),self,leaf,self,alt) 1878 ); 1879 return; 1880 } else { 1881 Smsg_ShortCut_End(self, SupTree(self), 1882 sch_msg_hdl_lodge(SupTree(self), self, leaf), 1883 sch_msg_snd_lodge(SupTree(self), self, leaf) 1884 ); 1885 return; 1886 } 1887} 1888 1889/* Down */ 1890static void sch_msg_hdl_lodged(leaf, parent) 1891st_id_t *leaf, *parent; 1892{ 1893 Smsg_Hdl_Notify(SMSG_LODGED, leaf, parent); 1894 eng_backtrack(LeafEngine(leaf), (st_handle_t *)parent, 0); 1895 switch (Life(Trunk(leaf))) { 1896 case ST_CUT: 1897 Smsg_ShortCut_Mid(leaf, Corpse(leaf), 1898 sch_msg_hdl_dec_corpse(Corpse(leaf),leaf), 1899 sch_msg_snd_dec_corpse(Corpse(leaf),leaf) 1900 ); 1901 SetNalive(Trunk(leaf),ST_LODGED); 1902 *SupTree(leaf) = *parent; 1903 Smsg_ShortCut_End(leaf, SupTree(leaf), 1904 sch_msg_hdl_js_prologue(SupTree(leaf),leaf,leaf), 1905 sch_msg_snd_js_prologue(SupTree(leaf),leaf,leaf) 1906 ); 1907 return; 1908 case ST_BACKTRACK: 1909 if (ComnNode(SupTree(leaf),parent)) 1910 break; 1911 case ST_CHOPPED: 1912 case ST_LODGED: 1913 Smsg_ShortCut_Mid(leaf, SupTree(leaf), 1914 sch_msg_hdl_withered(SupTree(leaf),leaf), 1915 sch_msg_snd_withered(SupTree(leaf),leaf) 1916 ); 1917 break; 1918 default: 1919 error("illegal leaf type"); 1920 } 1921 SetNalive(Trunk(leaf),ST_LODGED); 1922 *SupTree(leaf) = *parent; 1923 if (Scheduler(Site(leaf))->idling) { 1924 Scheduler(Site(leaf))->idling = 0; 1925 Smsg_ShortCut_End(leaf,SupTree(leaf), 1926 sch_msg_hdl_lodge_idle(SupTree(leaf),leaf,leaf), 1927 sch_msg_snd_lodge_idle(SupTree(leaf),leaf,leaf) 1928 ); 1929 } else { 1930 Smsg_ShortCut_End(leaf,SupTree(leaf), 1931 sch_msg_hdl_js_trav_up(SupTree(leaf),leaf,SupTree(leaf),leaf), 1932 sch_msg_snd_js_trav_up(SupTree(leaf),leaf,SupTree(leaf),leaf) 1933 ); 1934 } 1935} 1936 1937/* Up */ 1938static void sch_msg_hdl_withered(self,child) 1939st_id_t *self, *child; 1940{ 1941 Smsg_Hdl_Notify(SMSG_WITHERED, self,child); 1942 assert(Chopped(Twig(self)) || Lodged(Twig(self))); 1943 Quit_Chain(Twig(self)); 1944 Sch_Gc_Edge(Site(self),Twig(self)); 1945 if (Twigless(self)) { 1946 if (Chopped(Trunk(self))) { 1947 Smsg_ShortCut_End(self, SupTree(self), 1948 sch_msg_hdl_withered(SupTree(self),self), 1949 sch_msg_snd_withered(SupTree(self),self) 1950 ); 1951 Sch_Gc_Knot(self); 1952 return; 1953 } else { 1954 assert(Dying(Trunk(self))); 1955 } 1956 } 1957 Sch_Unlock(self); 1958 return; 1959} 1960 1961 1962/* Down */ 1963static void sch_msg_hdl_chop(self,parent,ancestor) 1964st_id_t *self, *parent, *ancestor; 1965{ 1966 Smsg_Hdl_Notify(SMSG_CHOP,self,parent); 1967 1968 /* ## NODE ## */ 1969 if (IsNode(self)) { 1970 st_edge_t *x = Trunk(self)->next; 1971 st_edge_t *y = (st_edge_t *) 0; 1972 st_id_t twig; twig = *self; 1973 1974 SetNalive(Trunk(self),ST_CHOPPED); 1975 SetExhausted(self); 1976 1977 if (Suspended(self)) { 1978 void relocate_suspended(); 1979 assert(JsRoot(self) || Local(self)); 1980 relocate_suspended(self); 1981 } 1982 /* kill alive / idle branches */ 1983 while (x != Trunk(self)) { 1984 if (Alive(x) || Dying(x) || Idle(x)) { 1985 if (Alive(x)) AliveTwigs(self)--; 1986 SetNalive(x,ST_CHOPPED); 1987 if (!y && ComnSite(self,&(x->tree))) 1988 y = x; 1989 else { 1990 PackEdge(&twig,x); 1991 Smsg_ShortCut_Mid(&twig, SubTree(&twig), 1992 sch_msg_hdl_chop(SubTree(&twig), &twig, ancestor), 1993 sch_msg_snd_chop(SubTree(&twig), &twig, ancestor) 1994 ); 1995 } 1996 } 1997 x = x->next; 1998 } 1999 assert(!AliveTwigs(self)); 2000 if (y) { 2001 PackEdge(&twig,y); 2002 Smsg_ShortCut_End(&twig, SubTree(&twig), 2003 sch_msg_hdl_chop(SubTree(&twig), &twig, ancestor), 2004 sch_msg_snd_chop(SubTree(&twig), &twig, ancestor) 2005 ); 2006 } else { 2007 if (Twigless(self)) { 2008 Smsg_ShortCut_End(self,SupTree(self), 2009 sch_msg_hdl_withered(SupTree(self),self), 2010 sch_msg_snd_withered(SupTree(self),self) 2011 ); 2012 Sch_Gc_Knot(&twig); 2013 } else { 2014 Sch_Unlock(self); 2015 } 2016 } 2017 return; 2018 } 2019 2020 /* ## LEAF ## */ 2021 switch (Life(Trunk(self))) { 2022 case ST_ALIVE: 2023 /* who will chop the only alive subtree ? */ 2024 assert(!Suspended(self)); 2025 Scheduler(Site(self))->lmp = 0; 2026 eng_stop(LeafEngine(self)); 2027 case ST_BACKTRACK: 2028 if (!Scheduler(Site(self))->idling) { 2029 SetNalive(Trunk(self),ST_LODGED); 2030 if (ComnSite(SupTree(self),ancestor)) { 2031 Smsg_ShortCut_End(self, ancestor, 2032 sch_msg_hdl_js_prologue(ancestor, self, self), 2033 sch_msg_snd_js_prologue(ancestor, self, self) 2034 ); 2035 return; 2036 } else { 2037 Smsg_ShortCut_End(self, ancestor, 2038 sch_msg_hdl_js_again(ancestor,self), 2039 sch_msg_snd_js_again(ancestor,self) 2040 ); 2041 return; 2042 } 2043 } 2044 Scheduler(Site(self))->idling = 0; 2045 case ST_IDLE: 2046 SetNalive(Trunk(self),ST_LODGED); 2047 Smsg_ShortCut_End(self,ancestor, 2048 sch_msg_hdl_lodge_idle(ancestor,self,self), 2049 sch_msg_snd_lodge_idle(ancestor,self,self) 2050 ); 2051 return; 2052 case ST_DYING: 2053 SetNalive(Trunk(self),ST_CHOPPED); 2054 Sch_Unlock(self); 2055 return; 2056 case ST_DEAD: { 2057 st_id_t gb; 2058 gb = *self; 2059 Smsg_ShortCut_End(self, SupTree(self), 2060 sch_msg_hdl_withered(SupTree(self), self), 2061 sch_msg_snd_withered(SupTree(self), self) 2062 ); 2063 Sch_Gc_Knot(&gb); 2064 return; 2065 } 2066 default: 2067 error("illegal leaf state"); 2068 } 2069} 2070 2071void relocate_suspended(self) 2072st_id_t *self; 2073{ 2074 st_susp_t *s; 2075 st_id_t *ncoma; 2076 while (s = Suspended(self)) { 2077 ncoma = ComnNode(self, &(s->coma)) ? SupTree(self) : &(s->coma); 2078 Smsg_ShortCut_Mid((self),SupTree(self), 2079 sch_msg_hdl_js_trav_up(SupTree(self), self, ncoma, &(s->leaf)), 2080 sch_msg_snd_js_trav_up(SupTree(self), self, ncoma, &(s->leaf)) 2081 ); 2082 Suspended(self) = s->next; 2083 Sch_Gc_Suspended(Site(self),s); 2084 } 2085} 2086 2087/* Down */ 2088static void sch_msg_hdl_js_in_vain(leaf,jroot) 2089st_id_t *leaf, *jroot; 2090{ 2091 Smsg_Hdl_Notify(SMSG_JS_IN_VAIN, leaf,jroot); 2092 switch (Life(Trunk(leaf))) { 2093 case ST_BACKTRACK: 2094 SetNalive(Trunk(leaf),ST_LODGED); 2095 case ST_LODGED: 2096 if (Scheduler(Site(leaf))->idling) { 2097 Scheduler(Site(leaf))->idling = 0; 2098 Smsg_ShortCut_End(leaf,SupTree(leaf), 2099 sch_msg_hdl_lodge_idle(SupTree(leaf),leaf,leaf), 2100 sch_msg_snd_lodge_idle(SupTree(leaf),leaf,leaf) 2101 ); 2102 return; 2103 } else { 2104 Smsg_ShortCut_End(leaf, SupTree(leaf), 2105 sch_msg_hdl_js_again(SupTree(leaf), leaf), 2106 sch_msg_snd_js_again(SupTree(leaf), leaf) 2107 ); 2108 return; 2109 } 2110 default: 2111 error("illegal leaf state"); 2112 } 2113} 2114 2115/* Up */ 2116static void sch_msg_hdl_js_again(self,leaf) 2117st_id_t *self, *leaf; 2118{ 2119 void sch_msg_hdl_js_trav_up_(); 2120 Smsg_Hdl_Notify(SMSG_JS_AGAIN, self, leaf); 2121 if (Alive(Trunk(self))) { 2122 sch_msg_hdl_js_trav_up_(self,self,leaf); 2123 return; 2124 } else { 2125 Smsg_ShortCut_End(self, SupTree(self), 2126 sch_msg_hdl_lodge(SupTree(self), self, leaf), 2127 sch_msg_snd_lodge(SupTree(self), self, leaf) 2128 ); 2129 return; 2130 } 2131} 2132 2133/* Down */ 2134static void sch_msg_hdl_js_trav_dn(self,parent,coma,leaf) 2135st_id_t *self, *parent, *coma, *leaf; 2136{ 2137 unsigned root_first = Scheduler(Site(self))->root_first; 2138 Smsg_Hdl_Notify(SMSG_JS_TRAV_DN, self,parent); 2139 2140repeat: 2141 if (Alive(Trunk(self))) { 2142 if (IsNode(self)) { 2143/** NODE **/ 2144 if (Knot(self)->nxtcls_b) { 2145 st_id_t lodge; 2146 if (!root_first) { 2147#if defined(NON_DIRECT_CHECK) 2148 Sch_JS_Trav_Down(self,coma,leaf); 2149#else /* NON_DIRECT_CHECK */ 2150 st_edge_t *x = Trunk(self)->prev; 2151 while (x != Trunk(self)) { 2152 if (ComnSite(self,&(x->tree))) { 2153 assert(Alive(x)); 2154 if (!Alive(x) || !Rich(x) || !Sch_Lock(&(x->tree))) break; 2155 if (Knot(&(x->tree))->nxtcls_b) { 2156 Sch_Unlock(self); 2157 self = &(x->tree); 2158 x = Trunk(self)->prev; 2159 } else { 2160 Sch_Unlock(&(x->tree)); 2161 break; 2162 } 2163 } else { 2164 x = x->prev; 2165 } 2166 } 2167#endif /* NON_DIRECT_CHECK */ 2168 } 2169 Bk_NextClause0(self); 2170 Add_Lodge_Twig(&lodge, leaf, Knot(self)); 2171 Sch_JS_Install(self, &lodge, coma, leaf); 2172 assert(zero()); 2173 return; 2174 } 2175 if (root_first) { 2176 SetPoorSpine(self); 2177 } 2178 Sch_JS_Trav_Down(self,coma,leaf); 2179 } else { 2180/** LEAF **/ 2181 if (Rich(Trunk(self))) { 2182 int max = (root_first) ? Scheduler(Site(self))->max_to_publish 2183 : 9999; 2184 int left; 2185 if (!eng_publish(LeafEngine(self), max, &left)) { 2186 st_id_t *nlf = SiteLeaf(Site(self)); 2187 if (!JsRoot(nlf)) SetPoor(Trunk(nlf)); 2188 Sch_JS_Trav_Up(nlf,coma,leaf); 2189 return; 2190 } else { 2191 st_id_t nlf; 2192 /* make sure the engine follows the convention: 2193 * when an engine rejects a job request, it is expected to 2194 * issue a job-report before it actually publishes anything. 2195 * It is to avoid the situation that suspended request flows 2196 * are buried within ancestors. A job-report will wake the 2197 * suspended request flows. 2198 */ 2199 assert(!JsRoot(self)||!Suspended(self)); 2200 nlf = *SiteLeaf(Site(self)); 2201 if (!left) { 2202 SetPoor(Trunk(&nlf)); 2203 SetPoor(Twig(SupTree(&nlf))); 2204 } 2205 { st_id_t *next = SupTree(&nlf); 2206 st_id_t *last = self; 2207 st_id_t *prev; 2208 do { 2209 if (Sch_Lock(next)) { 2210 if (!Exhausted(next)) { 2211 st_id_t twig; 2212 Bk_NextClause0(next); 2213 Add_Lodge_Twig(&twig,leaf,Knot(next)); 2214 eng_donate_state(LeafEngine(&nlf),(st_handle_t *)&twig, 2215 (st_handle_t *)coma, 2216 (st_handle_t *)leaf); 2217 Scheduler(Site(self))->state_donate++; 2218 Sch_Unlock(&twig); 2219 Sch_Unlock(&nlf); 2220 return; 2221 } else { 2222 Sch_Unlock(next); 2223 } 2224 } 2225 prev = next; 2226 next = SupTree(next); 2227 } while (!ComnKnot(prev,last)); 2228 } 2229 if (Sch_Lock(self)) { 2230 Sch_Unlock(&nlf); 2231 goto repeat; 2232 } else 2233 assert(zero()); 2234 } 2235 } 2236 } 2237 } 2238 Sch_JS_Trav_Up(self,coma,leaf); 2239} 2240 2241void sch_msg_hdl_js_trav_up_(self, coma, leaf) 2242st_id_t *self, *coma, *leaf; 2243{ 2244 unsigned root_first = Scheduler(Site(self))->root_first; 2245 if (Alive(Trunk(self))) { 2246 if (!root_first) { 2247 Sch_JS_Trav_Down(self,coma,leaf); 2248 } 2249 if (!Exhausted(self) && ComnNode(self,coma)) { 2250 st_id_t twig; 2251 int alt = Bk_NextClause(self); /* value not interesting */ 2252 alt = Tk_NextClause(self); 2253 Add_Alive_Twig_Next(&twig,leaf,Knot(self),Trunk(self)->prev); 2254 CheckLmp(&twig); 2255 SetPoor(Twig(&twig)); 2256 Smsg_ShortCut_End(&twig, leaf, 2257 sch_msg_hdl_js_success(leaf, &twig, alt, Twig(&twig)->info), 2258 sch_msg_snd_js_success(leaf, &twig, alt, Twig(&twig)->info) 2259 ); 2260 return; 2261 } 2262 if (Bk_NextClause(self)) { 2263 st_id_t lodge; 2264 Add_Lodge_Twig(&lodge,leaf,Knot(self)); 2265 Sch_JS_Install(self, &lodge, coma, leaf); 2266 assert(zero()); 2267 return; 2268 } 2269 if (root_first) { 2270 SetPoorSpine(self); 2271 Sch_JS_Trav_Down(self,coma,leaf); 2272 } 2273 assert(!Rich(Trunk(self)) || JsRoot(self)); 2274 } 2275 Sch_JS_Trav_Up(self,coma,leaf); 2276} 2277 2278/* Up */ 2279static void sch_msg_hdl_js_trav_up(self, child, coma, leaf) 2280st_id_t *self, *child, *coma, *leaf; 2281{ 2282 SetPoor(Twig(self)); 2283 Smsg_Hdl_Notify(SMSG_JS_TRAV_UP, self, child); 2284 sch_msg_hdl_js_trav_up_(self, coma, leaf); 2285} 2286 2287static void sch_msg_hdl_js_install(self,parent,lodge,coma,leaf) 2288st_id_t *self, *parent, *lodge, *coma, *leaf; 2289{ 2290 Smsg_Hdl_Notify(SMSG_JS_INSTALL, self,parent); 2291 if (IsNode(self)) { 2292 Sch_JS_Install(self, lodge, coma, leaf); 2293 /* returns back only if no alive local subtree found */ 2294 } else if (Alive(Trunk(self))||Idle(Trunk(self))) { 2295 /* LEAF */ 2296 eng_donate_state(LeafEngine(self),(st_handle_t *)lodge, 2297 (st_handle_t *)coma,(st_handle_t *)leaf); 2298 Scheduler(Site(self))->state_donate++; 2299 Sch_Unlock(self); 2300 return; 2301 } 2302 Smsg_ShortCut_End(self, lodge, 2303 sch_msg_hdl_js_install_fl(lodge, self, coma, leaf), 2304 sch_msg_snd_js_install_fl(lodge, self, coma, leaf) 2305 ); 2306 return; 2307} 2308 2309 2310static void sch_msg_hdl_engine_migrate(self, leaf) 2311st_id_t *self, *leaf; 2312{ 2313 Smsg_Hdl_Notify(SMSG_ENGINE_MIGRATE, self, leaf); 2314 assert(ComnNode(SubTree(self),leaf) && Lodged(Twig(self))); 2315 if (Exhausted(self)) { 2316 if (ComnSite(self,SupTree(self)) && !PoorSpine(self) && !JsRoot(self)) { 2317 Smsg_ShortCut_End(self,SupTree(self), 2318 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 2319 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 2320 ); 2321 return; 2322 } else { 2323 void sch_msg_hdl_js_trav_up_(); 2324 st_id_t coma; coma = *self; 2325 sch_msg_hdl_js_trav_up_(self,&coma,leaf); 2326 return; 2327 } 2328 } else { 2329 int alt = Tk_NextClause(self); 2330 Quit_Chain(Twig(self)); 2331 Join_Chain_Next(Twig(self),Trunk(self)->prev); 2332 AliveTwigs(self)++; 2333 SetAlive(Twig(self)); 2334 SetPoor(Twig(self)); 2335 CheckLmp(self); 2336 Smsg_ShortCut_End(self,leaf, 2337 sch_msg_hdl_js_success(leaf,self,alt,Twig(self)->info), 2338 sch_msg_snd_js_success(leaf,self,alt,Twig(self)->info) 2339 ); 2340 return; 2341 } 2342} 2343 2344static void sch_msg_hdl_js_install_fl(self, child, coma, leaf) 2345st_id_t *self, *child, *coma, *leaf; 2346{ 2347 Smsg_Hdl_Notify(SMSG_JS_INSTALL_FL, self, child); 2348 if (Exhausted(self)) { 2349 st_id_t garbage; garbage = *self; 2350 Quit_Chain(Twig(self)); 2351 Sch_JS_Trav_Down(self,coma,leaf); 2352 Sch_JS_Trav_Up(self,coma,leaf); 2353 Sch_Gc_Edge(Site(&garbage),Twig(&garbage)); 2354 } else { 2355 st_edge_t *x = Trunk(self)->prev; 2356 while (x != Trunk(self)) { 2357 if (Alive(x) || Idle(x)) { 2358 st_id_t twig; twig = *self; 2359 PackEdge(&twig,x); 2360 sch_msg_snd_js_install(SubTree(&twig),&twig,self,coma,leaf); 2361 Sch_Unlock(self); 2362 return; 2363 } else { 2364 x = x->prev; 2365 } 2366 } 2367 assert(zero()); 2368 } 2369} 2370 2371static void sch_msg_hdl_load_report(self, child) 2372st_id_t *self, *child; 2373{ 2374 Smsg_Hdl_Notify(SMSG_LOAD_REPORT, self, child); 2375 if (!Alive(Twig(self))) { 2376 Sch_Unlock(self); 2377 return; 2378 } 2379 /* the assertion below may not hold for the local leaf: when 2380 ** the child is a local node, and the local leaf, after finishing 2381 ** traversal of the whole subtree, will reset it (trunk) poor, but it 2382 ** will not reset poor the suptree twig as other js_trav leaves as 2383 ** it does not go up, instead, suspends itself at the local node. 2384 */ 2385 /*assert(!Rich(Twig(self)));*/ 2386 SetRich(Twig(self)); 2387 if (JsRoot(self) && Monad(self) && Exhausted(self)) { 2388 assert(Rich(Trunk(self))); 2389 Smsg_ShortCut_Mid(self, SubTree(self), 2390 sch_msg_hdl_set_js_root(SubTree(self), self), 2391 sch_msg_snd_set_js_root(SubTree(self), self) 2392 ); 2393 } 2394 if (Suspended(self)) { 2395 st_susp_t *x; 2396 assert(JsRoot(self) || Local(self)); 2397 while (x = Suspended(self)) { 2398 Smsg_ShortCut_Mid((self),SubTree(self), 2399 sch_msg_hdl_js_trav_dn(SubTree(self), self, &(x->coma), &(x->leaf)), 2400 sch_msg_snd_js_trav_dn(SubTree(self), self, &(x->coma), &(x->leaf)) 2401 ); 2402 Suspended(self) = x->next; 2403 Sch_Gc_Suspended(Site(self),x); 2404 } 2405 } 2406 if (!Rich(Trunk(self))) { /* further report up */ 2407 assert(!JsRoot(self)); 2408 SetRich(Trunk(self)); 2409 Smsg_ShortCut_End(self, SupTree(self), 2410 sch_msg_hdl_load_report(SupTree(self), self), 2411 sch_msg_snd_load_report(SupTree(self), self) 2412 ); 2413 return; 2414 } else { 2415 Sch_Unlock(self); 2416 return; 2417 } 2418} 2419 2420/* Down */ 2421static void sch_msg_hdl_set_js_root(self, parent) 2422st_id_t *self, *parent; 2423{ 2424 Smsg_Hdl_Notify(SMSG_SET_JS_ROOT, self, parent); 2425 if (Rich(Trunk(self))) { 2426 SetJsRoot(self); 2427 /* assert(!Suspended(self) || Local(self)); */ 2428 if (Monad(self) && Exhausted(self) && !Suspended(self)) { 2429 st_id_t twig; 2430 st_edge_t *x = Trunk(self)->next; 2431 while (x != Trunk(self)) { 2432 if (Alive(x)) { 2433 twig = *self; 2434 PackEdge(&twig,x); 2435 Smsg_ShortCut_End(&twig, SubTree(&twig), 2436 sch_msg_hdl_set_js_root(SubTree(&twig), &twig), 2437 sch_msg_snd_set_js_root(SubTree(&twig), &twig) 2438 ); 2439 return; 2440 } 2441 x = x->next; 2442 } 2443 assert(zero()); 2444 } 2445 } 2446 Sch_Unlock(self); 2447 return; 2448} 2449 2450/* Up */ 2451static void sch_msg_hdl_stop_idle(self,leaf) 2452st_id_t *self, *leaf; 2453{ 2454 Smsg_Hdl_Notify(SMSG_STOP_IDLE, self, leaf); 2455 if (!Alive(Trunk(self))) { 2456 if (Chopped(Trunk(self))) { 2457 Sch_Unlock(self); 2458 return; 2459 } else { 2460 assert(Dying(Trunk(self))); 2461 assert(Idle(Twig(self))); 2462 SetNalive(Twig(self),ST_LODGED); 2463 if (ComnSite(self,SupTree(self)) && !PoorSpine(self) && 2464 !PoorSpine(SupTree(self))) { 2465 Smsg_ShortCut_End(self, SupTree(self), 2466 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 2467 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 2468 ); 2469 return; 2470 } else { 2471 Smsg_ShortCut_End(self, SupTree(self), 2472 sch_msg_hdl_lodge(SupTree(self),self,leaf), 2473 sch_msg_snd_lodge(SupTree(self),self,leaf) 2474 ); 2475 return; 2476 } 2477 } 2478 } else { 2479 int alt = Bk_NextClause(self); 2480 alt = Tk_NextClause(self); 2481 /* the below assert relies on the assumption that an exhausted 2482 ** monad leaf not allowed to become idle. 2483 */ 2484 assert(alt || AliveTwigs(self) || Local(self)); 2485 assert(Idle(Twig(self))); 2486 SetNalive(Twig(self),ST_LODGED); 2487 if (alt && (AliveTwigs(self)||!Exhausted(self))) { 2488 Quit_Chain(Twig(self)); 2489 Join_Chain_Next(Twig(self),Trunk(self)->prev); 2490 AliveTwigs(self)++; 2491 SetAlive(Twig(self)); 2492 SetPoor(Twig(self)); 2493 Smsg_ShortCut_End(self, leaf, 2494 sch_msg_hdl_js_success(leaf, self, alt, Twig(self)->info), 2495 sch_msg_snd_js_success(leaf, self, alt, Twig(self)->info) 2496 ); 2497 return; 2498 } else if (alt || (!AliveTwigs(self)&&ComnSite(self,leaf))) { 2499 SetNalive(Trunk(self),ST_DYING); 2500 if (!alt && Hybrid(self)) alt = -1; 2501 Smsg_ShortCut_End(self, SupTree(self), 2502 sch_msg_hdl_straighten(SupTree(self),self,leaf,self,alt), 2503 sch_msg_snd_straighten(SupTree(self),self,leaf,self,alt) 2504 ); 2505 return; 2506 } else if (ComnSite(self,SupTree(self)) && !PoorSpine(self) && 2507 !PoorSpine(SupTree(self))) { 2508 Smsg_ShortCut_End(self, SupTree(self), 2509 sch_msg_hdl_js_prologue(SupTree(self),self,leaf), 2510 sch_msg_snd_js_prologue(SupTree(self),self,leaf) 2511 ); 2512 return; 2513 } else { 2514 st_id_t *coma = self; 2515 SetPoorSpine(self); 2516 Sch_JS_Trav_Down(self,coma,leaf); 2517 Sch_JS_Trav_Up(self,coma,leaf); 2518 } 2519 } 2520} 2521 2522/* Up */ 2523static void sch_msg_hdl_tell_idle(self,leaf) 2524st_id_t *self, *leaf; 2525{ 2526 Smsg_Hdl_Notify(SMSG_TELL_IDLE, self, leaf); 2527 if (Alive(Twig(self))) { 2528 if (Monad(self) && Exhausted(self)) { 2529 /* cant become idle, has to take over sequential chpts */ 2530 void sch_msg_hdl_backtrack_(); 2531 sch_msg_hdl_backtrack_(self,leaf); 2532 return; 2533 } 2534 UpdateLmp(self); 2535 AliveTwigs(self)--; 2536 SetNalive(Twig(self),ST_IDLE); 2537 Smsg_ShortCut_End(self, leaf, 2538 sch_msg_hdl_idle_told(leaf, self), 2539 sch_msg_snd_idle_told(leaf, self) 2540 ); 2541 return; 2542 } else { 2543 Sch_Unlock(self); 2544 return; 2545 } 2546} 2547 2548/* Up */ 2549static void sch_msg_hdl_lodge_idle(self,child,leaf) 2550st_id_t *self, *child, *leaf; 2551{ 2552 Smsg_Hdl_Notify(SMSG_LODGE_IDLE,self,child); 2553 if (Alive(Trunk(self))) { 2554 st_id_t idle; 2555 Add_Lodge_Twig(&idle,leaf,Knot(self)); 2556 SetNalive(Twig(&idle),ST_IDLE); 2557 Smsg_ShortCut_End(&idle, leaf, 2558 sch_msg_hdl_idle_told(leaf, &idle), 2559 sch_msg_snd_idle_told(leaf, &idle) 2560 ); 2561 return; 2562 } else { 2563 assert(!SchRoot(self)); 2564 Smsg_ShortCut_End(self,SupTree(self), 2565 sch_msg_hdl_lodge_idle(SupTree(self),self,leaf), 2566 sch_msg_snd_lodge_idle(SupTree(self),self,leaf) 2567 ); 2568 return; 2569 } 2570} 2571 2572/* Down */ 2573static void sch_msg_hdl_idle_told(leaf, parent) 2574st_id_t *leaf, *parent; 2575{ 2576 Smsg_Hdl_Notify(SMSG_IDLE_TOLD,leaf,parent); 2577 switch (Life(Trunk(leaf))) { 2578 case ST_BACKTRACK: 2579 if (Scheduler(Site(leaf))->idling) 2580 /* Note: this bit is not reset when telling idle. 2581 ** Therefore, if it becomes reset in the meantime, 2582 ** it must have consumed a waking request. 2583 */ 2584 Scheduler(Site(leaf))->idling = 0; 2585 else 2586 Scheduler(Site(leaf))->waking = 1; 2587 if (ComnNode(SupTree(leaf),parent)) 2588 break; 2589 case ST_LODGED: 2590 Smsg_ShortCut_Mid(leaf, SupTree(leaf), 2591 sch_msg_hdl_withered(SupTree(leaf), leaf), 2592 sch_msg_snd_withered(SupTree(leaf), leaf) 2593 ); 2594 break; 2595 2596 default: 2597 error("illegal leaf type"); 2598 } 2599 *SupTree(leaf) = *parent; 2600 SetNalive(Twig(leaf),ST_IDLE); 2601 if (Scheduler(Site(leaf))->waking) { 2602 Scheduler(Site(leaf))->waking = 0; 2603 /* emulate a backtrack */ 2604 SetNalive(Trunk(leaf),ST_BACKTRACK); 2605 Smsg_ShortCut_End(leaf, SupTree(leaf), 2606 sch_msg_hdl_stop_idle(SupTree(leaf),leaf), 2607 sch_msg_snd_stop_idle(SupTree(leaf),leaf) 2608 ); 2609 return; 2610 } else { 2611 eng_backtrack(LeafEngine(leaf), (st_handle_t *)parent, 0); 2612 Sch_Unlock(leaf); 2613 return; 2614 } 2615} 2616 2617 2618static void sch_msg_hdl_idle_eng(leaf, leaf0) 2619st_id_t *leaf, *leaf0; 2620{ 2621 Smsg_Hdl_Notify(SMSG_IDLE_ENG, leaf, leaf0); 2622 if (Knot(SiteLeaf(Site(leaf)))!=Knot(leaf)) { 2623 sch_msg_snd_idle_eng(SiteLeaf(Site(leaf)),leaf); 2624 Sch_Unlock(leaf); 2625 return; 2626 } 2627 if (Scheduler(Site(leaf))->waking) { 2628 Scheduler(Site(leaf))->waking = 0; 2629 Sch_Unlock(leaf); 2630 return; 2631 } 2632 Scheduler(Site(leaf))->idling = 1; 2633 if (Alive(Trunk(leaf))) { 2634 if (JsRoot(leaf)) { 2635 Sch_WakeUp_Suspended(leaf); 2636 Sch_Unlock(leaf); 2637 return; 2638 } else { 2639 int left; 2640 if (!eng_publish(LeafEngine(leaf),99999, &left) || !left) { 2641 SetPoor(Trunk(SiteLeaf(Site(leaf)))); 2642 SetPoor(Twig(SupTree(SiteLeaf(Site(leaf))))); 2643 } 2644 } 2645 } 2646 if (Life(Trunk(leaf)) != ST_CUT) { 2647 Smsg_ShortCut_End(leaf, SupTree(leaf), 2648 sch_msg_hdl_reduce_wk_up(SupTree(leaf), leaf), 2649 sch_msg_snd_reduce_wk_up(SupTree(leaf), leaf) 2650 ); 2651 return; 2652 } else { 2653 st_id_t *olf = Corpse(leaf); 2654 Smsg_ShortCut_Mid(olf, SupTree(olf), 2655 sch_msg_hdl_reduce_wk_up(SupTree(olf), olf), 2656 sch_msg_snd_reduce_wk_up(SupTree(olf), olf) 2657 ); 2658 Sch_Unlock(leaf); 2659 return; 2660 } 2661} 2662 2663static void sch_msg_hdl_reduce_wk_up(self,child) 2664st_id_t *self, *child; 2665{ 2666 Smsg_Hdl_Notify(SMSG_REDUCE_WK_UP,self,child); 2667 if (Alive(Trunk(self)) && JsRoot(self)) { 2668 if (Suspended(self)) { 2669 Sch_WakeUp_Suspended(self); 2670 Sch_Unlock(self); 2671 return; 2672 } 2673 if (!Alive(Twig(self)) && Monad(self) && Exhausted(self)) { 2674 st_edge_t *x = Trunk(self)->next; 2675 while (x != Trunk(self)) { 2676 if (Alive(x)) { 2677 if (!Rich(x)) break; 2678 else { 2679 st_id_t twig; 2680 twig = *self; 2681 PackEdge(&twig,x); 2682 Smsg_ShortCut_End(&twig, SubTree(&twig), 2683 sch_msg_hdl_reduce_wk_dn(SubTree(&twig),&twig), 2684 sch_msg_snd_reduce_wk_dn(SubTree(&twig),&twig) 2685 ); 2686 return; 2687 } 2688 } 2689 x = x->next; 2690 } 2691 } 2692 Sch_Unlock(self); 2693 return; 2694 } else { 2695 assert(!Suspended(self)); 2696 Smsg_ShortCut_End(self,SupTree(self), 2697 sch_msg_hdl_reduce_wk_up(SupTree(self),self), 2698 sch_msg_snd_reduce_wk_up(SupTree(self),self) 2699 ); 2700 return; 2701 } 2702} 2703 2704static void sch_msg_hdl_reduce_wk_dn(self, parent) 2705st_id_t *self, *parent; 2706{ 2707 Smsg_Hdl_Notify(SMSG_REDUCE_WK_DN, self, parent); 2708 if (!Alive(Trunk(self))) { 2709 Smsg_ShortCut_End(self,SupTree(self), 2710 sch_msg_hdl_reduce_wk_up(SupTree(self),self), 2711 sch_msg_snd_reduce_wk_up(SupTree(self),self) 2712 ); 2713 return; 2714 } 2715 if (JsRoot(self)) { 2716 if (Suspended(self)) { 2717 Sch_WakeUp_Suspended(self); 2718 Sch_Unlock(self); 2719 return; 2720 } 2721 if (Monad(self) && Exhausted(self)) { 2722 st_edge_t *x = Trunk(self)->next; 2723 while (x != Trunk(self)) { 2724 if (Alive(x)) { 2725 if (!Rich(x)) break; 2726 else { 2727 st_id_t twig; 2728 twig = *self; 2729 PackEdge(&twig,x); 2730 Smsg_ShortCut_End(&twig, SubTree(&twig), 2731 sch_msg_hdl_reduce_wk_dn(SubTree(&twig),&twig), 2732 sch_msg_snd_reduce_wk_dn(SubTree(&twig),&twig) 2733 ); 2734 return; 2735 } 2736 } 2737 x = x->next; 2738 } 2739 } 2740 } 2741 Sch_Unlock(self); 2742 return; 2743} 2744 2745 2746 2747static void sch_msg_hdl_wake_eng(leaf, leaf0) 2748st_id_t *leaf, *leaf0; 2749{ 2750 Smsg_Hdl_Notify(SMSG_WAKE_ENG, leaf, leaf0); 2751 if (Knot(SiteLeaf(Site(leaf)))!=Knot(leaf)) { 2752 sch_msg_snd_wake_eng(SiteLeaf(Site(leaf)),leaf); 2753 Sch_Unlock(leaf); 2754 return; 2755 } 2756 if (Idle(Trunk(leaf))) { 2757 /* emulate a backtrack */ 2758 SetNalive(Trunk(leaf),ST_BACKTRACK); 2759 Smsg_ShortCut_End(leaf, SupTree(leaf), 2760 sch_msg_hdl_stop_idle(SupTree(leaf),leaf), 2761 sch_msg_snd_stop_idle(SupTree(leaf),leaf) 2762 ); 2763 return; 2764 } 2765 if (Scheduler(Site(leaf))->idling) { 2766 Scheduler(Site(leaf))->idling = 0; 2767 Sch_Unlock(leaf); 2768 return; 2769 } 2770 if (Scheduler(Site(leaf))->waking) { 2771#if defined(SDEBUG) 2772#else /* SDEBUG */ 2773 (void) fprintf(stderr, "Warning: waking requests overlapped !"); 2774#endif /* SDEBUG */ 2775 Sch_Unlock(leaf); 2776 return; 2777 } else if (Lodged(Trunk(leaf))) { 2778 Scheduler(Site(leaf))->waking = 1; 2779 Sch_Unlock(leaf); 2780 return; 2781 } else 2782 (void) fprintf(stderr, "Warning: waking a non-idle engine"); 2783} 2784 2785/* Down */ 2786static void sch_msg_hdl_lmp(self, parent) 2787st_id_t *self, *parent; 2788{ 2789 Smsg_Hdl_Notify(SMSG_LMP, self, parent); 2790 if (Alive(Trunk(self))) { 2791 SetEldest(Trunk(self)); 2792 if (IsLeaf(self)) { 2793 if (Scheduler(Site(self))->lmp) { 2794 Scheduler(Site(self))->lmp = 0; 2795 eng_lmp(LeafEngine(self)); 2796 } 2797 } else if (AliveTwigs(self)) { 2798 /* when equal 0, this the case of engine idling */ 2799 st_id_t twig; 2800 st_edge_t *x = Trunk(self)->next; 2801 while (x != Trunk(self)) { 2802 if (Alive(x)) { 2803 twig = *self; 2804 PackEdge(&twig,x); 2805 SetEldest(x); 2806 Smsg_ShortCut_End(&twig, SubTree(&twig), 2807 sch_msg_hdl_lmp(SubTree(&twig), &twig), 2808 sch_msg_snd_lmp(SubTree(&twig), &twig) 2809 ); 2810 return; 2811 } 2812 x = x->next; 2813 } 2814 assert(zero()); 2815 } 2816 } 2817 Sch_Unlock(self); 2818 return; 2819} 2820 2821 2822void sch_idle_eng(site) 2823site_id_t site; 2824{ 2825 /* 2826 ** 1. to fit with a general tracing utility, the leaf doubled; 2827 ** 2. the short-up optimization is skipped here. 2828 */ 2829 sch_msg_snd_idle_eng(SiteLeaf(site), SiteLeaf(site)); 2830 return; 2831} 2832 2833void sch_wake_eng(site) 2834site_id_t site; 2835{ 2836 /* 2837 ** 1. to fit with a general tracing utility, the leaf doubled; 2838 ** 2. the short-up optimization is skipped here. 2839 */ 2840 sch_msg_snd_wake_eng(SiteLeaf(site), SiteLeaf(site)); 2841 return; 2842} 2843 2844void sch_reduce_worker(site) 2845aport_id_t site; 2846{ 2847 st_id_t *leaf = SiteLeaf(site); 2848 assert(Alive(Trunk(leaf))); 2849 if (JsRoot(leaf)) { 2850 Sch_WakeUp_Suspended(leaf); 2851 return; 2852 } 2853 Smsg_ShortCut_Mid(leaf,SupTree(leaf), 2854 sch_msg_hdl_reduce_wk_up(SupTree(leaf),leaf), 2855 sch_msg_snd_reduce_wk_up(SupTree(leaf),leaf) 2856 ); 2857 return; 2858} 2859 2860void sch_engine_migrate(leaf_hdl,where_hdl) 2861const st_handle_t *leaf_hdl, *where_hdl; 2862{ 2863 st_id_t *leaf = (st_id_t *)leaf_hdl; 2864 st_id_t *where = (st_id_t *)where_hdl; 2865 assert(!Alive(Trunk(leaf))&&!ComnNode(SupTree(leaf),where)); 2866 Smsg_ShortCut_Mid(leaf,SupTree(leaf), 2867 sch_msg_hdl_withered(SupTree(leaf),leaf), 2868 sch_msg_snd_withered(SupTree(leaf),leaf) 2869 ); 2870 *SupTree(leaf) = *where; 2871 Smsg_ShortCut_Mid(leaf,where, 2872 sch_msg_hdl_engine_migrate(where,leaf), 2873 sch_msg_snd_engine_migrate(where,leaf) 2874 ); 2875 return; 2876} 2877 2878 2879/*ARGSUSED*/ 2880void eng_lmp(engine) 2881const eng_handle_t engine; 2882{ 2883} 2884 2885#if defined(PROLOG_LMP) 2886int sch_lmp(leaf) 2887const st_handle_t *leaf; 2888{ 2889 if (Eldest(Trunk((st_id_t *) leaf))) 2890 return(1); 2891 Scheduler(Site(leaf))->lmp = 1; 2892 return(0); 2893} 2894#endif /* PROLOG_LMP */ 2895 2896 2897 2898void smsg_stat_init(site) 2899site_id_t site; 2900{ 2901 int i; 2902 2903 Scheduler(site)->state_donate = 0; 2904 Scheduler(site)->smsg_count_hdl = 0; 2905 Scheduler(site)->smsg_count_snd = 0; 2906 Scheduler(site)->smsg_count_intra = 0; 2907 Scheduler(site)->smsg_count_intra_shortcut = 0; 2908 for (i = SMSG_MAXNUM; i>=0; i--) 2909 Scheduler(site)->smsg_subcount[i] = 0; 2910 2911 smsg_name[SMSG_INIT_LODGE] = "INIT_LODGE "; 2912 smsg_name[SMSG_BACKTRACK] = "BACKTRACK "; 2913 smsg_name[SMSG_STRAIGHTEN] = "STRAIGHTEN "; 2914 smsg_name[SMSG_CUT] = "CUT "; 2915 smsg_name[SMSG_CUT_OK] = "CUT_OK "; 2916 smsg_name[SMSG_CHOP] = "CHOP "; 2917 smsg_name[SMSG_WITHERED] = "WITHERED "; 2918 smsg_name[SMSG_LODGE] = "LODGE "; 2919 smsg_name[SMSG_LODGED] = "LODGED "; 2920 smsg_name[SMSG_DEC_CORPSE] = "DEC_CORPSE "; 2921 smsg_name[SMSG_JS_PROLOGUE] = "JS_PROLOGUE "; 2922 smsg_name[SMSG_JS_TRAV_UP] = "JS_TRAV_UP "; 2923 smsg_name[SMSG_JS_TRAV_DN] = "JS_TRAV_DN "; 2924 smsg_name[SMSG_JS_INSTALL] = "JS_INSTALL "; 2925 smsg_name[SMSG_JS_INSTALL_FL] = "JS_INSTALL_FL"; 2926 smsg_name[SMSG_JS_SUCCESS] = "JS_SUCCESS "; 2927 smsg_name[SMSG_JS_TRUST] = "JS_TRUST "; 2928 smsg_name[SMSG_JS_IN_VAIN] = "JS_IN_VAIN "; 2929 smsg_name[SMSG_JS_AGAIN] = "JS_AGAIN "; 2930 smsg_name[SMSG_LOAD_REPORT] = "LOAD_REPORT "; 2931 smsg_name[SMSG_SET_JS_ROOT] = "SET_JS_ROOT "; 2932 smsg_name[SMSG_IDLE_ENG] = "IDLE_ENG "; 2933 smsg_name[SMSG_WAKE_ENG] = "WAKE_ENG "; 2934 smsg_name[SMSG_TELL_IDLE] = "TELL_IDLE "; 2935 smsg_name[SMSG_IDLE_TOLD] = "IDLE_TOLD "; 2936 smsg_name[SMSG_LODGE_IDLE] = "LODGE_IDLE "; 2937 smsg_name[SMSG_STOP_IDLE] = "STOP_IDLE "; 2938 smsg_name[SMSG_LMP] = "LMP "; 2939 smsg_name[SMSG_REDUCE_WK_UP] = "REDUCE_WK_UP "; 2940 smsg_name[SMSG_REDUCE_WK_DN] = "REDUCE_WK_DN "; 2941 smsg_name[SMSG_ENGINE_MIGRATE] = "ENGINE_MIGRATE"; 2942 smsg_name[SMSG_MAXNUM] = "MAXNUM "; 2943 2944 return; 2945} 2946 2947int zero() { 2948 int i; 2949 i = 0; 2950 return(i); 2951} 2952 2953void sch_break() {} 2954 2955scheduler_t *site_scheduler(site) 2956aport_id_t site; 2957{ 2958 return(Scheduler(site)); 2959} 2960 2961int get_smsg_max() 2962{ 2963 return(SMSG_MAXNUM); 2964} 2965 2966 2967/* 2968sch_empty_queue0() 2969{ 2970 static amsg_t msg; 2971 static smsg00_t *data; 2972 static amsg_type_t mdt_type; 2973 static amsg_count_t mdt_count; 2974 return amsg_peek( scheduler->port, 2975 &msg, 2976 (amsg_data_t * *)&data, 2977 &mdt_type, 2978 &mdt_count 2979 ); 2980} 2981 2982sch_empty_queue() 2983{ 2984 amsg_ret_t ret; 2985 int event; 2986 2987 Disable_Int(); 2988 ret = sch_empty_queue0(); 2989 event = sch_msg_event(); 2990 Enable_Int(); 2991 assert(ret != AMSG_OK || event); 2992 return(ret != AMSG_OK || event); 2993} 2994*/ 2995