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: sch_util.c 26** Author: Liang-Liang Li 27** Description: Utilities for Prolog manipulations of the scheduler data 28** structures. 29***********************************************************************/ 30 31#include <stdio.h> 32 33#include "config.h" 34#include "sepia.h" 35#include <pds.h> 36#include "types.h" 37#include "embed.h" 38#include "error.h" 39#include "mem.h" 40#include "dict.h" 41 42/* The scheduler tree definitions and macros */ 43#define ST_HANDLE_DS_DEFINED 1 44 45#include "sch_types.h" 46#include "sch_macros.h" 47 48extern char * smsg_name[]; 49extern void sch_wake_eng(); 50extern void sch_idle_eng(); 51 52/* 53** mapping keys to their scheduler setting instructions. 54*/ 55 56#define SCHSET_ROOT2BOTTOM 0x00010000 /* root_first */ 57#define SCHSET_BOTTOM2ROOT 0x00020000 /* bottom_first */ 58#define SCHSET_LEFT2RIGHT 0x00040000 /* left_first */ 59#define SCHSET_RIGHT2LEFT 0x00080000 /* right_first */ 60#define SCHSET_MAX2PUBLISH 0x00100000 /* max_to_publish */ 61#define SCHSET_RESETCOUNTS 0x00200000 /* msg_counts */ 62#define SCHSET_IDLING 0x00400000 /* idle_eng */ 63#define SCHSET_WAKING 0x00800000 /* wake_eng */ 64#define SCHSET_ASYNC_HDL 0x01000000 /* async_hdl */ 65#define SCHSET_SYNC_HDL 0x02000000 /* sync_hdl */ 66#define SCHSET_LOAD_REPORT_E 0x10000000 /* load_report_eager */ 67#define SCHSET_LOAD_REPORT_L 0x20000000 /* load_report_lazy */ 68#define SCHSET_MAXVALUE 0x000fffff /* max_value */ 69/* 70** int p_sch_set(Int: wid, List: instructions) 71** int p_sch_get(Int: wid, Var/List: info) 72*/ 73 74int p_sch_set(v_wid, t_wid, v_inst, t_inst) 75value v_wid; 76type t_wid; 77value v_inst; 78type t_inst; 79{ 80 char *key; 81 int instruction = 0; 82 pword *cur_mc, *tmp, *cur_tail; 83 pword first; 84 85 Check_Integer(t_wid); 86 87 first.tag = t_inst; 88 first.val = v_inst; 89 cur_mc = &first; 90 91 while (IsList(cur_mc->tag)) { 92 cur_tail = cur_mc->val.ptr + 1; 93 cur_mc = cur_mc->val.ptr; 94 Dereference_(cur_mc); 95 if (IsList(cur_mc->tag)) { 96 tmp = cur_mc->val.ptr; 97 Dereference_(tmp); 98 Get_Name(tmp->val,tmp->tag,key); 99 if (strcmp(key,"max_to_publish") == 0) { 100 tmp = cur_mc->val.ptr+1; 101 Dereference_(tmp); 102 if (IsList(tmp->tag)) { 103 tmp = tmp->val.ptr; 104 Dereference_(tmp); 105 if (IsInteger(tmp->tag)) { 106 instruction |= SCHSET_MAX2PUBLISH; 107 instruction |= SCHSET_MAXVALUE & tmp->val.nint; 108 } 109 } 110 } 111 } else { 112 Get_Name(cur_mc->val, cur_mc->tag, key); 113 if (strcmp(key,"root_first") == 0) 114 instruction |= SCHSET_ROOT2BOTTOM; 115 else if (strcmp(key,"bottom_first") == 0) 116 instruction |= SCHSET_BOTTOM2ROOT; 117 else if (strcmp(key,"left_first") == 0) 118 instruction |= SCHSET_LEFT2RIGHT; 119 else if (strcmp(key,"right_first") == 0) 120 instruction |= SCHSET_RIGHT2LEFT; 121 else if (strcmp(key,"reset_msg_counts") == 0) 122 instruction |= SCHSET_RESETCOUNTS; 123 else if (strcmp(key,"idle_eng") == 0) 124 instruction |= SCHSET_IDLING; 125 else if (strcmp(key,"wake_eng") == 0) 126 instruction |= SCHSET_WAKING; 127 else if (strcmp(key,"async_hdl") == 0) 128 instruction |= SCHSET_ASYNC_HDL; 129 else if (strcmp(key,"sync_hdl") == 0) 130 instruction |= SCHSET_SYNC_HDL; 131 else if (strcmp(key,"load_report_eager") == 0) 132 instruction |= SCHSET_LOAD_REPORT_E; 133 else if (strcmp(key,"load_report_lazy") == 0) 134 instruction |= SCHSET_LOAD_REPORT_L; 135 } 136 cur_mc = cur_tail; 137 } 138 Check_Nil(cur_mc->tag); 139 140 if (instruction) { 141 void wm_set_worker_info(); 142 wm_set_worker_info((int) v_wid.nint, 1, sizeof(int), (void_ptr) &instruction); 143 } 144 Succeed_; 145} 146 147int p_sch_get(v_wid, t_wid, v_info, t_info) 148value v_wid; 149type t_wid; 150value v_info; 151type t_info; 152{ 153 /* 154 ** The info output is [States, Statistics]. 155 ** 156 ** Transform the scheduler info into a plain prolog list INFO: 157 ** struct scheduler { 158 ** aport_id_t port; ## States ## 159 ** struct st_handle_ds leaf; 160 ** eng_handle_t engine; 161 ** struct susp_buffer_ds susp_buffer; 162 ** struct edge_buffer_ds edge_buffer; 163 ** int max_to_publish; 164 ** unsigned root_first:1; 165 ** unsigned left_first:1; 166 ** unsigned idling :1; 167 ** unsigned waking :1; 168 ** unsigned sync_hdl :1; 169 ** unsigned async_hdl :1; 170 ** unsigned lmp :1; 171 ** unsigned load_report_eager:1; 172 ** int state_donate; ## Statistics ## 173 ** int smsg_count_hdl; 174 ** int smsg_count_snd; 175 ** int smsg_count_intra; 176 ** int smsg_count_intra_shortcut; 177 ** int smsg_subcount[40+1]; 178 ** }; 179 */ 180 scheduler_t scheduler_data[1]; 181 pword *cur_mc, *prev_mc, *cur_tail, *cur_head, *statistics; 182 int i, bufsize = sizeof(scheduler_t); 183 extern void wm_get_worker_info(); 184 Check_Integer(t_wid); 185 wm_get_worker_info((int) v_wid.nint, 1, bufsize, (void_ptr) scheduler_data); 186 187 prev_mc = NULL; 188 /* smsg_subcount */ 189 /* [[n1,v1],[n2,v2] ...] */ 190 for (i = get_smsg_max()-1; i>0; i--) { 191 cur_mc = TG; 192 Push_List_Frame() 193 cur_head = TG; 194 Push_List_Frame() 195 Make_List(cur_mc,cur_head); 196 Make_String(cur_head,smsg_name[i]) 197 cur_tail = cur_head + 1; 198 cur_head = TG; 199 Push_List_Frame() 200 Make_List(cur_tail,cur_head); 201 Make_Integer(cur_head,scheduler_data->smsg_subcount[i]) 202 cur_tail = cur_head + 1; 203 Make_Nil(cur_tail) 204 cur_tail = cur_mc + 1; 205 if (prev_mc == NULL) 206 Make_Nil(cur_tail) 207 else { 208 Make_List(cur_tail, prev_mc); 209 } 210 prev_mc = cur_mc; 211 } 212 /* [smsg_count_intra_shortcut, v] */ 213 cur_mc = TG; 214 Push_List_Frame() 215 cur_head = TG; 216 Push_List_Frame() 217 Make_List(cur_mc,cur_head); 218 Make_String(cur_head,"smsg_count_intra_shortcut") 219 cur_tail = cur_head + 1; 220 cur_head = TG; 221 Push_List_Frame() 222 Make_List(cur_tail,cur_head); 223 Make_Integer(cur_head,scheduler_data->smsg_count_intra_shortcut) 224 cur_tail = cur_head + 1; 225 Make_Nil(cur_tail) 226 cur_tail = cur_mc + 1; 227 Make_List(cur_tail, prev_mc); 228 prev_mc = cur_mc; 229 230 /* [smsg_count_intra, v] */ 231 cur_mc = TG; 232 Push_List_Frame() 233 cur_head = TG; 234 Push_List_Frame() 235 Make_List(cur_mc,cur_head); 236 Make_String(cur_head,"smsg_count_intra") 237 cur_tail = cur_head + 1; 238 cur_head = TG; 239 Push_List_Frame() 240 Make_List(cur_tail,cur_head); 241 Make_Integer(cur_head,scheduler_data->smsg_count_intra) 242 cur_tail = cur_head + 1; 243 Make_Nil(cur_tail) 244 cur_tail = cur_mc + 1; 245 Make_List(cur_tail, prev_mc); 246 prev_mc = cur_mc; 247 248 /* [smsg_count_snd,v] */ 249 cur_mc = TG; 250 Push_List_Frame() 251 cur_head = TG; 252 Push_List_Frame() 253 Make_List(cur_mc,cur_head); 254 Make_String(cur_head,"smsg_count_snd") 255 cur_tail = cur_head + 1; 256 cur_head = TG; 257 Push_List_Frame() 258 Make_List(cur_tail,cur_head); 259 Make_Integer(cur_head,scheduler_data->smsg_count_snd) 260 cur_tail = cur_head + 1; 261 Make_Nil(cur_tail) 262 cur_tail = cur_mc + 1; 263 Make_List(cur_tail, prev_mc); 264 prev_mc = cur_mc; 265 266 /* [smsg_count_hdl, v] */ 267 cur_mc = TG; 268 Push_List_Frame() 269 cur_head = TG; 270 Push_List_Frame() 271 Make_List(cur_mc,cur_head); 272 Make_String(cur_head,"smsg_count_hdl") 273 cur_tail = cur_head + 1; 274 cur_head = TG; 275 Push_List_Frame() 276 Make_List(cur_tail,cur_head); 277 Make_Integer(cur_head,scheduler_data->smsg_count_hdl) 278 cur_tail = cur_head + 1; 279 Make_Nil(cur_tail) 280 cur_tail = cur_mc + 1; 281 Make_List(cur_tail, prev_mc); 282 prev_mc = cur_mc; 283 284 /* [state_donate, v] */ 285 cur_mc = TG; 286 Push_List_Frame() 287 cur_head = TG; 288 Push_List_Frame() 289 Make_List(cur_mc,cur_head); 290 Make_String(cur_head,"state_donate") 291 cur_tail = cur_head + 1; 292 cur_head = TG; 293 Push_List_Frame() 294 Make_List(cur_tail,cur_head); 295 Make_Integer(cur_head,scheduler_data->state_donate) 296 cur_tail = cur_head + 1; 297 Make_Nil(cur_tail) 298 cur_tail = cur_mc + 1; 299 Make_List(cur_tail, prev_mc); 300 statistics = cur_mc; 301 302 /* [lmp, v] */ 303 cur_mc = TG; 304 Push_List_Frame() 305 cur_head = TG; 306 Push_List_Frame() 307 Make_List(cur_mc,cur_head); 308 Make_String(cur_head,"lmp") 309 cur_tail = cur_head + 1; 310 cur_head = TG; 311 Push_List_Frame() 312 Make_List(cur_tail,cur_head); 313 Make_Integer(cur_head,scheduler_data->lmp) 314 cur_tail = cur_head + 1; 315 Make_Nil(cur_tail) 316 cur_tail = cur_mc + 1; 317 Make_Nil(cur_tail); 318 prev_mc = cur_mc; 319 320 /* [async_hdl, v] */ 321 cur_mc = TG; 322 Push_List_Frame() 323 cur_head = TG; 324 Push_List_Frame() 325 Make_List(cur_mc,cur_head); 326 Make_String(cur_head,"async_hdl") 327 cur_tail = cur_head + 1; 328 cur_head = TG; 329 Push_List_Frame() 330 Make_List(cur_tail,cur_head); 331 Make_Integer(cur_head,scheduler_data->async_hdl) 332 cur_tail = cur_head + 1; 333 Make_Nil(cur_tail) 334 cur_tail = cur_mc + 1; 335 Make_List(cur_tail, prev_mc); 336 prev_mc = cur_mc; 337 338 /* [load_report_eager, v] */ 339 cur_mc = TG; 340 Push_List_Frame() 341 cur_head = TG; 342 Push_List_Frame() 343 Make_List(cur_mc,cur_head); 344 Make_String(cur_head,"load_report_eager") 345 cur_tail = cur_head + 1; 346 cur_head = TG; 347 Push_List_Frame() 348 Make_List(cur_tail,cur_head); 349 Make_Integer(cur_head,scheduler_data->load_report_eager) 350 cur_tail = cur_head + 1; 351 Make_Nil(cur_tail) 352 cur_tail = cur_mc + 1; 353 Make_List(cur_tail, prev_mc); 354 prev_mc = cur_mc; 355 356 /* [waking, v] */ 357 cur_mc = TG; 358 Push_List_Frame() 359 cur_head = TG; 360 Push_List_Frame() 361 Make_List(cur_mc,cur_head); 362 Make_String(cur_head,"waking") 363 cur_tail = cur_head + 1; 364 cur_head = TG; 365 Push_List_Frame() 366 Make_List(cur_tail,cur_head); 367 Make_Integer(cur_head,scheduler_data->waking) 368 cur_tail = cur_head + 1; 369 Make_Nil(cur_tail) 370 cur_tail = cur_mc + 1; 371 Make_List(cur_tail, prev_mc); 372 prev_mc = cur_mc; 373 374 /* [idling, v] */ 375 cur_mc = TG; 376 Push_List_Frame() 377 cur_head = TG; 378 Push_List_Frame() 379 Make_List(cur_mc,cur_head); 380 Make_String(cur_head,"idling") 381 cur_tail = cur_head + 1; 382 cur_head = TG; 383 Push_List_Frame() 384 Make_List(cur_tail,cur_head); 385 Make_Integer(cur_head,scheduler_data->idling) 386 cur_tail = cur_head + 1; 387 Make_Nil(cur_tail) 388 cur_tail = cur_mc + 1; 389 Make_List(cur_tail, prev_mc); 390 prev_mc = cur_mc; 391 392 /* [left_first, v] */ 393 cur_mc = TG; 394 Push_List_Frame() 395 cur_head = TG; 396 Push_List_Frame() 397 Make_List(cur_mc,cur_head); 398 Make_String(cur_head,"left_first") 399 cur_tail = cur_head + 1; 400 cur_head = TG; 401 Push_List_Frame() 402 Make_List(cur_tail,cur_head); 403 Make_Integer(cur_head,scheduler_data->left_first) 404 cur_tail = cur_head + 1; 405 Make_Nil(cur_tail) 406 cur_tail = cur_mc + 1; 407 Make_List(cur_tail, prev_mc); 408 prev_mc = cur_mc; 409 410 /* [root_first, v] */ 411 cur_mc = TG; 412 Push_List_Frame() 413 cur_head = TG; 414 Push_List_Frame() 415 Make_List(cur_mc,cur_head); 416 Make_String(cur_head,"root_first") 417 cur_tail = cur_head + 1; 418 cur_head = TG; 419 Push_List_Frame() 420 Make_List(cur_tail,cur_head); 421 Make_Integer(cur_head,scheduler_data->root_first) 422 cur_tail = cur_head + 1; 423 Make_Nil(cur_tail) 424 cur_tail = cur_mc + 1; 425 Make_List(cur_tail, prev_mc); 426 prev_mc = cur_mc; 427 428 /* [max_to_publish, v] */ 429 cur_mc = TG; 430 Push_List_Frame() 431 cur_head = TG; 432 Push_List_Frame() 433 Make_List(cur_mc,cur_head); 434 Make_String(cur_head,"max_to_publish") 435 cur_tail = cur_head + 1; 436 cur_head = TG; 437 Push_List_Frame() 438 Make_List(cur_tail,cur_head); 439 Make_Integer(cur_head,scheduler_data->max_to_publish) 440 cur_tail = cur_head + 1; 441 Make_Nil(cur_tail) 442 cur_tail = cur_mc + 1; 443 Make_List(cur_tail, prev_mc); 444 prev_mc = cur_mc; 445 446 /* [edge_buffer, v] */ 447 cur_mc = TG; 448 Push_List_Frame() 449 cur_head = TG; 450 Push_List_Frame() 451 Make_List(cur_mc,cur_head); 452 Make_String(cur_head,"edge_buffer") 453 cur_tail = cur_head + 1; 454 cur_head = TG; 455 Push_List_Frame() 456 Make_List(cur_tail,cur_head); 457 Make_Integer(cur_head,scheduler_data->edge_buffer.count) 458 cur_tail = cur_head + 1; 459 Make_Nil(cur_tail) 460 cur_tail = cur_mc + 1; 461 Make_List(cur_tail, prev_mc); 462 prev_mc = cur_mc; 463 464 /* [susp_buffer, v] */ 465 cur_mc = TG; 466 Push_List_Frame() 467 cur_head = TG; 468 Push_List_Frame() 469 Make_List(cur_mc,cur_head); 470 Make_String(cur_head,"susp_buffer") 471 cur_tail = cur_head + 1; 472 cur_head = TG; 473 Push_List_Frame() 474 Make_List(cur_tail,cur_head); 475 Make_Integer(cur_head,scheduler_data->susp_buffer.count) 476 cur_tail = cur_head + 1; 477 Make_Nil(cur_tail) 478 cur_tail = cur_mc + 1; 479 Make_List(cur_tail, prev_mc); 480 prev_mc = cur_mc; 481 482 /* [engine, v] */ 483 cur_mc = TG; 484 Push_List_Frame() 485 cur_head = TG; 486 Push_List_Frame() 487 Make_List(cur_mc,cur_head); 488 Make_String(cur_head,"engine") 489 cur_tail = cur_head + 1; 490 cur_head = TG; 491 Push_List_Frame() 492 Make_List(cur_tail,cur_head); 493 Make_Integer(cur_head,scheduler_data->engine) 494 cur_tail = cur_head + 1; 495 Make_Nil(cur_tail) 496 cur_tail = cur_mc + 1; 497 Make_List(cur_tail, prev_mc); 498 prev_mc = cur_mc; 499 500 /* [leaf, v] */ 501 cur_mc = TG; 502 Push_List_Frame() 503 cur_head = TG; 504 Push_List_Frame() 505 Make_List(cur_mc,cur_head); 506 Make_String(cur_head,"leaf") 507 cur_tail = cur_head + 1; 508 cur_head = TG; 509 Push_List_Frame() 510 Make_List(cur_tail,cur_head); 511 Make_Integer(cur_head, scheduler_data->leaf.site) 512 cur_tail = cur_head + 1; 513 cur_head = TG; 514 Push_List_Frame() 515 Make_List(cur_tail,cur_head); 516 Make_Integer(cur_head, scheduler_data->leaf.edge) 517 cur_tail = cur_head + 1; 518 cur_head = TG; 519 Push_List_Frame() 520 Make_List(cur_tail,cur_head); 521 Make_Integer(cur_head, scheduler_data->leaf.knot) 522 cur_tail = cur_head + 1; 523 Make_Nil(cur_tail) 524 cur_tail = cur_mc + 1; 525 Make_List(cur_tail, prev_mc); 526 prev_mc = cur_mc; 527 528 /* [port, v] */ 529 cur_mc = TG; 530 Push_List_Frame() 531 cur_head = TG; 532 Push_List_Frame() 533 Make_List(cur_mc,cur_head); 534 Make_String(cur_head,"port") 535 cur_tail = cur_head + 1; 536 cur_head = TG; 537 Push_List_Frame() 538 Make_List(cur_tail,cur_head); 539 Make_Integer(cur_head,scheduler_data->port) 540 cur_tail = cur_head + 1; 541 Make_Nil(cur_tail) 542 cur_tail = cur_mc + 1; 543 Make_List(cur_tail, prev_mc); 544 prev_mc = cur_mc; 545 546 /* pack states and statistics together */ 547 cur_mc = TG; 548 Push_List_Frame() 549 Make_List(cur_mc, prev_mc); 550 cur_head = TG; 551 Push_List_Frame() 552 cur_tail = cur_mc + 1; 553 Make_List(cur_tail,cur_head); 554 Make_List(cur_head, statistics); 555 cur_tail = cur_head+1; 556 Make_Nil(cur_tail) 557 558 Return_Unify_List(v_info, t_info, cur_mc) 559} 560 561 562void sch_get_info(site,infosize,infoval) 563aport_id_t site; 564int * infosize; 565void_ptr * infoval; 566{ 567 scheduler_t * site_scheduler(); 568 *infoval = (void_ptr) site_scheduler(site); 569 *infosize = sizeof(scheduler_t); 570 return; 571} 572 573void sch_set_info(site,infoval) 574aport_id_t site; 575void_ptr infoval; 576{ 577 scheduler_t * site_scheduler(); 578 scheduler_t *s = (scheduler_t *) site_scheduler(site); 579 int i, instruction = * (int *) infoval; 580 581 if (instruction&SCHSET_ROOT2BOTTOM) 582 s->root_first = 1; 583 if (instruction&SCHSET_BOTTOM2ROOT) 584 s->root_first = 0; 585 if (instruction&SCHSET_LEFT2RIGHT) 586 s->left_first = 1; 587 if (instruction&SCHSET_RIGHT2LEFT) 588 s->left_first = 0; 589 if (instruction&SCHSET_MAX2PUBLISH) 590 s->max_to_publish = instruction&SCHSET_MAXVALUE; 591 if (instruction&SCHSET_RESETCOUNTS) { 592 s->state_donate = 0; 593 s->smsg_count_hdl = 0; 594 s->smsg_count_snd = 0; 595 s->smsg_count_intra = 0; 596 s->smsg_count_intra_shortcut = 0; 597 for (i = get_smsg_max()-1; i>0; i--) 598 s->smsg_subcount[i] = 0; 599 } 600 if (instruction&SCHSET_ASYNC_HDL) 601 s->async_hdl = 1; 602 if (instruction&SCHSET_SYNC_HDL) 603 s->async_hdl = 0; 604 if (instruction&SCHSET_IDLING) 605 sch_idle_eng(site); 606 if (instruction&SCHSET_WAKING) 607 sch_wake_eng(site); 608 if (instruction&SCHSET_LOAD_REPORT_E) 609 s->load_report_eager = 1; 610 if (instruction&SCHSET_LOAD_REPORT_L) 611 s->load_report_eager = 0; 612 return; 613} 614 615/* int p_schtrace_on() */ 616 617int p_sch_trace_on() 618{ 619 (void) global_flags(0,SCH_TRACE_FLAG); 620 Sch_Trace_Begin(); 621 Succeed_; 622} 623