COMPILATION LISTING OF SEGMENT mrd_util_ Compiled by: Multics PL/I Compiler, Release 29, of July 28, 1986 Compiled at: Honeywell Bull, Phoenix AZ, SysM Compiled on: 09/21/87 1956.9 mst Mon Options: optimize map 1 /****^ *********************************************************** 2* * * 3* * Copyright, (C) Honeywell Bull Inc., 1987 * 4* * * 5* * Copyright, (C) Honeywell Information Systems Inc., 1982 * 6* * * 7* * Copyright (c) 1972 by Massachusetts Institute of * 8* * Technology and Honeywell Information Systems, Inc. * 9* * * 10* *********************************************************** */ 11 12 13 14 /****^ HISTORY COMMENTS: 15* 1) change(87-09-15,Parisek), approve(87-09-21,MECR0008), 16* audit(87-09-21,GDixon), install(87-09-21,MR12.1-1114): 17* On any_other conditions report condition name, reset the message segment 18* header, unlock the message segment if locked and return to caller with an 19* error code instead of terminating the process. (phx20928) 20* END HISTORY COMMENTS */ 21 22 23 /* format: style4 */ 24 mrd_util_: 25 procedure; 26 27 /* MRD_UTIL_ - This procedure contains all code which must deal with a 28* message coordinator "message" segment in a consistent fashion. This is 29* the only program which locks and unlocks these segments. */ 30 31 /* Coded by Dennis Capps, July 1972 32* Modified by J. C. Whitmore, Aug 1975 to return event chan on each 33* read_status call. 34* Rewritten 751223 by PG 35* Modified 6/8/83 by E. N. Kittlitz to fix uninitialized variable used by 36* cleanup. 37* Modified 1985-03-11 by E. Swenson to fix locking code and add cleanup 38* handler. 39**/ 40 41 /* builtins */ 42 43 dcl (addr, clock, divide, index, min, null, string, substr) builtin; 44 45 /* parameters */ 46 47 dcl (tp ptr, /* ptr to Stream Data Block */ 48 workp ptr, /* ptr to I/O workspace for transfer */ 49 first_char fixed bin, /* Offset from base of users workspace */ 50 nchar fixed bin, /* Number of characters to be transferred */ 51 nchart fixed bin, /* Number of characters actually transferred */ 52 state fixed bin, /* 0 -- end of data,1 -- more to message. */ 53 code fixed bin (35), /* error code */ 54 reqsw fixed bin, /* what to abort */ 55 request char (*) /* What kind of protocol request */ 56 ) parameter; 57 58 /* Automatic */ 59 60 dcl dont_flood bit (1) aligned init ("0"b); /* TRUE = may go into output wait */ 61 dcl lock_ptr ptr init (null); /* ptr to message seg we have locked */ 62 dcl lock_set bit (1) aligned init (""b); /* ON if we have lock set */ 63 dcl mask bit (36) aligned init (""b), /* IPS Mask */ 64 my_name char (32) varying, 65 ourmp ptr, /* Pointer to message seg for this function */ 66 recursion fixed bin initial (0), 67 hismp ptr, /* Pointer to message seg for destination func. */ 68 messp ptr, 69 messp1 ptr, 70 thatp ptr, /* Used in transferring characters. */ 71 thisp ptr, /* Used in transferring characters. */ 72 chainp ptr, /* Points to head & tail info for current chain */ 73 mp ptr, 74 wake_up_chan fixed bin (71), /* How to tell him message deposited */ 75 event_mess fixed bin (71), /* Give inkling of whats happening */ 76 i fixed bin, /* A temporary index */ 77 autocode fixed bin (35), /* Error code */ 78 this_message fixed bin, /* Message block currently under inspection */ 79 begin_this fixed bin, /* First block of this message */ 80 end_this fixed bin, /* last block of this message */ 81 prev_message fixed bin, /* Message block previously under inspection */ 82 time fixed bin (71), /* Current time (postmark) */ 83 n fixed bin, /* Temporaries of a dedicated nature */ 84 no_of_blocks fixed bin, 85 len fixed bin; 86 dcl ipc_mask_code fixed bin (35); 87 dcl ipc_unmask_code fixed bin (35); 88 89 dcl 1 ci aligned like condition_info; /* Condition info */ 90 dcl 1 message_type, 91 2 continue bit (1), /* Message continued in next block */ 92 2 introduction bit (1), /* This is an introductory message */ 93 2 farewell bit (1), /* " " farewell " */ 94 2 sentinel bit (1), /* Don't print time at front of this one */ 95 2 unused bit (32); 96 dcl 1 terminate_info structure aligned, 97 2 version fixed bin, 98 2 code fixed bin (35); 99 100 /* based */ 101 102 dcl 1 chain based (chainp), 103 2 chain_head fixed bin, /* first_message or first_proto */ 104 2 chain_tail fixed bin; /* last_message or last_proto */ 105 106 dcl based_mess char (len) based (thatp), /* For transferring characters */ 107 char_array (buff_len) char (1) based (thisp), /* For updating thisp */ 108 char_event_mess char (8) based, /* Goes with event_mess */ 109 this_batch char (len) based (thisp); /* For transferring characters */ 110 111 dcl 1 SDB based (tp) aligned, /* one entry in list of stream control blocks */ 112 2 dim_name char (32), /* the name of this DIM */ 113 2 device_name_list ptr, /* threaded list of device id's */ 114 2 next_device ptr, /* pointer to next entry in threaded list */ 115 2 device_name_size fixed bin, /* number of chars in device name */ 116 2 device_name char (32), /* device id */ 117 2 pad1 fixed bin, 118 2 ipc_ep ptr, /* to normal event list for read block */ 119 2 proto_ep ptr, /* to protocol event list for att & det */ 120 2 nextp ptr, /* pointer to next stream block in chain */ 121 2 ourmess ptr, /* Pointer to mseg for this function */ 122 2 hismess ptr, /* Pointer to mseg for message coord'r */ 123 2 source char (32), /* symbolic name of I/O source */ 124 2 stream char (32), /* symbolic name of I/O stream */ 125 2 source_index fixed bin, /* in MRT */ 126 2 stream_index fixed bin, 127 2 flags, 128 3 valid bit (1) unal, /* "1"b = entry-in-use, "0"b = not_in_use */ 129 3 read bit (1) unal, /* "1"b = stream attached for reading. */ 130 3 write bit (1) unal, /* "1"b = stream attached for writing. */ 131 3 active bit (1) unal, /* For compatibility with message_coordr_ */ 132 3 more bit (1) unal, /* "1"b = More text in this message than we've given */ 133 3 unused bit (31) unal, 134 2 prev_trans, 135 3 first_block fixed bin, 136 3 end_block fixed bin, 137 3 current_block fixed bin, 138 3 offset fixed bin; 139 140 /* Entries */ 141 142 dcl continue_to_signal_ entry (fixed bin (35)), 143 find_condition_info_ entry (ptr, ptr, fixed bin(35)), 144 get_process_id_ entry () returns (bit (36) aligned), 145 hcs_$fs_get_path_name entry (ptr, char (*), fixed bin, char (*), fixed bin (35)), 146 hcs_$reset_ips_mask entry (bit (36) aligned, bit (36) aligned), 147 hcs_$set_ips_mask entry (bit (36) aligned, bit (36) aligned), 148 hcs_$wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35)), 149 ipc_$drain_chn entry (fixed bin (71), fixed bin (35)), 150 ipc_$mask_ev_calls entry (fixed bin (35)), 151 ipc_$unmask_ev_calls entry (fixed bin (35)), 152 phcs_$ring_0_message ext entry (char (*)), 153 set_lock_$lock entry (bit (36) aligned, fixed bin, fixed bin (35)), 154 set_lock_$unlock entry (bit (36) aligned, fixed bin (35)); 155 dcl terminate_process_ entry (char (*), ptr); 156 157 /* internal static */ 158 159 dcl (my_process_id bit (36) aligned initial ((18)"10"b), 160 thirty_seconds fixed bin init (30) options (constant), /* How long before set_lock_ gives up */ 161 NL char (1) initial (" 162 "), 163 LIMIT fixed bin init (10), /* Max # lines queued but not printed */ 164 OWAIT fixed bin init (123) /* Err code to mrdim_ => output wait */ 165 ) internal static; 166 167 /* external static */ 168 169 dcl error_table_$argerr fixed bin (35) external; 170 dcl error_table_$lock_wait_time_exceeded fixed bin (35) external; 171 dcl error_table_$invalid_lock_reset fixed bin (35) external; 172 dcl error_table_$locked_by_this_process fixed bin (35) external; 173 dcl error_table_$no_message fixed bin (35) external; 174 dcl error_table_$unable_to_do_io fixed bin (35) external; 175 176 /* Conditions */ 177 178 dcl any_other condition; 179 dcl cleanup condition; 180 181 /* Program */ 182 183 protocol: entry (tp, workp, first_char, nchar, nchart, request, code); 184 185 /* This entry helps a function to do certain things to make the 186* interaction with the message coordinator go smoothly */ 187 188 my_name = "mrd_util_$protocol"; 189 string (message_type) = ""b; 190 hismp = SDB.hismess; 191 addr (event_mess) -> char_event_mess = request; 192 193 if request = "attach" then do; 194 my_process_id = get_process_id_ (); /* this is the first call to this program... */ 195 wake_up_chan = hismp -> syscon_mseg.proto_el.channel; 196 message_type.introduction = "1"b; 197 chainp = addr (hismp -> syscon_mseg.first_proto); 198 end; 199 else if request = "sentinel" then do; 200 wake_up_chan = hismp -> syscon_mseg.ipc_el.channel; 201 message_type.sentinel = "1"b; 202 chainp = addr (hismp -> syscon_mseg.first_message); 203 end; 204 else if request = "detach" then do; 205 wake_up_chan = hismp -> syscon_mseg.proto_el.channel; 206 message_type.farewell = "1"b; 207 chainp = addr (hismp -> syscon_mseg.first_proto); 208 end; 209 else do; 210 code = error_table_$argerr; 211 return; 212 end; 213 go to common_write; 214 215 /* This is the ordinary entry for writing. */ 216 217 write_dont_flood: 218 entry (tp, workp, first_char, nchar, nchart, state, code); 219 dont_flood = "1"b; 220 221 write: entry (tp, workp, first_char, nchar, nchart, state, code); 222 223 mask = ""b; 224 on any_other 225 call ANY_OTHER_HANDLER (); 226 227 my_name = "mrd_util_$write"; 228 string (message_type) = ""b; 229 hismp = SDB.hismess; 230 wake_up_chan = hismp -> syscon_mseg.ipc_el.channel; 231 addr (event_mess) -> char_event_mess = "normal"; 232 chainp = addr (hismp -> syscon_mseg.first_message); 233 ourmp = SDB.ourmess; 234 235 if dont_flood 236 & (hismp -> syscon_mseg.current_process_id ^= ourmp -> syscon_mseg.current_process_id) 237 & (ourmp -> syscon_mseg.mescount >= LIMIT | ourmp -> syscon_mseg.output_wait) 238 then do; 239 ourmp -> syscon_mseg.output_wait = "1"b; 240 code = OWAIT; 241 return; 242 end; 243 ourmp -> syscon_mseg.mescount = ourmp -> syscon_mseg.mescount + 1; 244 245 common_write: 246 ourmp = SDB.ourmess; 247 nchart = 0; /* A couple of initializations. */ 248 code = 0; 249 250 lock_set = "0"b; /* for cleanup handler */ 251 lock_ptr = null (); /* for cleanup handler */ 252 ipc_mask_code, ipc_unmask_code = -1; 253 254 on condition (cleanup) 255 call CLEAN_UP (); 256 257 call LOCK (hismp, code); /* lock the message segment (shared amoung many processes) */ 258 if code ^= 0 then return; 259 260 /* Now that the seg is locked, calculate how many blocks we need 261* for this message. Grab them. Unlock the seg and we can fill them at our leisure. */ 262 no_of_blocks = divide (nchar + buff_len - 1, buff_len, 17, 0); 263 264 message_type.continue = "1"b; 265 do n = 1 to no_of_blocks; 266 if hismp -> syscon_mseg.first_free_buffer = 0 then do; 267 hismp -> syscon_mseg.last_assigned_buffer = hismp -> syscon_mseg.last_assigned_buffer + 1; 268 this_message = hismp -> syscon_mseg.last_assigned_buffer; 269 end; 270 else do; 271 this_message = hismp -> syscon_mseg.first_free_buffer; 272 hismp -> syscon_mseg.first_free_buffer = 273 hismp -> syscon_mseg.message (this_message).next_message; 274 end; 275 if n = 1 then begin_this = this_message; 276 else hismp -> syscon_mseg.message (prev_message).next_message = this_message; 277 prev_message = this_message; 278 hismp -> syscon_mseg.message (this_message).next_message = 0; 279 string (hismp -> syscon_mseg.message (this_message).flags) = string (message_type); 280 end; 281 282 hismp -> syscon_mseg.message (this_message).flags.continue = "0"b; 283 end_this = this_message; 284 call UNLOCK (hismp); 285 286 /* Now fill in the message blocks */ 287 len = min (nchar, buff_len); 288 thisp = workp; 289 thisp = addr (char_array (first_char + 1)); /* +1 because its really an offset */ 290 time = clock (); 291 this_message = begin_this; 292 293 do n = 1 to no_of_blocks; 294 hismp -> syscon_mseg.message (this_message).time_sent = time; 295 hismp -> syscon_mseg.message (this_message).from_source = SDB.source; 296 hismp -> syscon_mseg.message (this_message).from_stream = SDB.stream; 297 hismp -> syscon_mseg.message (this_message).source_index = SDB.source_index; 298 hismp -> syscon_mseg.message (this_message).stream_index = SDB.stream_index; 299 hismp -> syscon_mseg.message (this_message).message_body = this_batch; 300 hismp -> syscon_mseg.message (this_message).length = len; 301 302 thisp = addr (char_array (len + 1)); /* Update pointer & indeces */ 303 nchart = nchart + len; 304 len = min (nchar - nchart, buff_len); 305 this_message = hismp -> syscon_mseg.message (this_message).next_message; 306 end; 307 308 /* Lock the segment again, stick in the message, &unlock */ 309 call LOCK (hismp, code); 310 if code ^= 0 then do; /* Woops. Cannot lock seg to chain in. */ 311 nchart = 0; /* Pretend we didn't write at all */ 312 return; /* Some storage in message seg will be lost. */ 313 end; 314 315 call VALIDATE_CHAIN (hismp, chainp, "write-2"); 316 317 if chain.chain_head = 0 /* Hook this into the proper message queue */ 318 then chain.chain_head = begin_this; 319 else hismp -> syscon_mseg.message (chain.chain_tail).next_message = begin_this; 320 321 chain.chain_tail = end_this; 322 323 call UNLOCK (hismp); 324 325 /* Now wakeup other guy so he knows to look for what we just gave him. */ 326 327 call hcs_$wakeup (hismp -> syscon_mseg.current_process_id, 328 wake_up_chan, event_mess, autocode); 329 return; 330 331 discard_remainder: 332 entry (tp, state, code); 333 334 mask = ""b; 335 on any_other 336 call ANY_OTHER_HANDLER (); 337 338 my_name = "mrd_util_$discard_remainder"; 339 ourmp = SDB.ourmess; 340 begin_this = SDB.prev_trans.first_block; 341 end_this = SDB.prev_trans.end_block; 342 code = 0; 343 344 go to free_current_chain; 345 346 read: entry (tp, workp, first_char, nchar, nchart, request, mp, state, code); 347 348 mask = ""b; 349 on any_other 350 call ANY_OTHER_HANDLER (); 351 352 my_name = "mrd_util_$read"; 353 messp1 = mp; 354 nchart = 0; 355 code = 0; 356 end_this = SDB.prev_trans.end_block; 357 begin_this = SDB.prev_trans.first_block; 358 ourmp = SDB.ourmess; 359 if request = "proto" then chainp = addr (ourmp -> syscon_mseg.first_proto); 360 else chainp = addr (ourmp -> syscon_mseg.first_message); 361 if SDB.flags.more then goto get_message; 362 363 /* Unhook the blocks for this message (locking the seg first) */ 364 365 lock_set = "0"b; /* for cleanup handler */ 366 lock_ptr = null (); /* for cleanup handler */ 367 ipc_mask_code, ipc_unmask_code = -1; 368 369 on condition (cleanup) 370 call CLEAN_UP (); 371 372 call LOCK (ourmp, code); 373 if code ^= 0 then return; 374 375 call VALIDATE_CHAIN (ourmp, chainp, "read-1"); 376 377 SDB.prev_trans.offset = 0; 378 379 if chain.chain_head = 0 then do; /* Nothing in queue */ 380 code = error_table_$no_message; 381 go to read_return; 382 end; 383 384 SDB.prev_trans.first_block, 385 SDB.prev_trans.current_block, 386 begin_this, this_message = chain.chain_head; 387 388 no_of_blocks = 1; 389 390 do while (ourmp -> syscon_mseg.message (this_message).continue); 391 this_message = ourmp -> syscon_mseg.message (this_message).next_message; 392 no_of_blocks = no_of_blocks + 1; 393 end; 394 395 SDB.prev_trans.end_block, 396 end_this = this_message; 397 chain.chain_head = ourmp -> syscon_mseg.message (this_message).next_message; 398 if end_this = chain.chain_tail then chain.chain_tail = 0; 399 400 call UNLOCK (ourmp); 401 402 messp = addr (ourmp -> syscon_mseg.message (begin_this)); 403 messp1 -> message_block.time_sent = message_block.time_sent; 404 messp1 -> message_block.from_source = message_block.from_source; 405 messp1 -> message_block.from_stream = message_block.from_stream; 406 messp1 -> message_block.source_index = message_block.source_index; 407 messp1 -> message_block.stream_index = message_block.stream_index; 408 string (messp1 -> message_block.flags) = string (message_block.flags); 409 410 get_message: 411 412 /**** Extract the message */ 413 414 thisp = workp; 415 thisp = addr (char_array (first_char + 1)); 416 this_message = SDB.prev_trans.current_block; 417 len = min (nchar, ourmp -> syscon_mseg.message (this_message).length - SDB.prev_trans.offset); 418 thatp = addr (ourmp -> syscon_mseg.message (this_message).message_body); 419 thatp = addr (thatp -> char_array (SDB.prev_trans.offset + 1)); 420 421 do while (ourmp -> syscon_mseg.message (this_message).continue); 422 i = index (based_mess, NL); 423 if i ^= 0 then len = i; 424 this_batch = based_mess; 425 nchart = nchart + len; 426 if SDB.prev_trans.offset + len = ourmp -> syscon_mseg.message (this_message).length then 427 do; 428 SDB.prev_trans.offset = 0; 429 this_message, 430 SDB.prev_trans.current_block = ourmp -> syscon_mseg.message (this_message).next_message; 431 end; 432 else do; SDB.prev_trans.offset = SDB.prev_trans.offset + len; goto theres_more; end; 433 if nchart = nchar then goto theres_more; 434 thatp = addr (ourmp -> syscon_mseg.message (this_message).message_body); 435 thisp = addr (char_array (len + 1)); 436 len = min (nchar - nchart, ourmp -> syscon_mseg.message (this_message).length); 437 end; 438 439 i = index (based_mess, NL); 440 if i ^= 0 then len = i; 441 this_batch = based_mess; 442 nchart = nchart + len; 443 SDB.prev_trans.offset = SDB.prev_trans.offset + len; 444 if SDB.prev_trans.offset ^= ourmp -> syscon_mseg.message (this_message).length 445 then do; 446 theres_more: 447 state = 1; 448 SDB.flags.more = "1"b; 449 return; 450 end; 451 452 /* Put used blocks back on the free storage list */ 453 454 free_current_chain: 455 SDB.flags.more = "0"b; 456 state = 0; 457 458 if begin_this = 0 459 then return; 460 461 if end_this = 0 then do; 462 call COMPLAIN (ourmp, "inconsistent threads"); 463 call SAVE_STATE (ourmp); 464 return; 465 end; 466 467 call LOCK (ourmp, code); 468 if code ^= 0 then return; 469 470 ourmp -> syscon_mseg.message (end_this).next_message = ourmp -> syscon_mseg.first_free_buffer; 471 ourmp -> syscon_mseg.first_free_buffer = begin_this; 472 473 read_return: 474 SDB.prev_trans.first_block = 0; 475 SDB.prev_trans.end_block = 0; 476 call UNLOCK (ourmp); 477 return; 478 479 read_status: entry (tp, statusp, code); 480 481 /**** entry to look at read ahead */ 482 483 dcl 1 status_struct aligned based (statusp), 484 2 ev_chan fixed bin (71), 485 2 input_available bit (1); 486 487 dcl statusp ptr; 488 489 ourmp = SDB.ourmess; /* get ptr to our msg seg */ 490 chainp = addr (ourmp -> syscon_mseg.first_message); /* get ptr to chain of messages */ 491 492 status_struct.ev_chan = ourmp -> syscon_mseg.ipc_el.channel; 493 494 if chain.chain_head = 0 then /* no chain, no input now */ 495 status_struct.input_available = "0"b; /* say no input */ 496 else status_struct.input_available = "1"b; 497 498 return; 499 500 abort: entry (tp, reqsw, state, code); 501 502 mask = ""b; 503 on any_other 504 call ANY_OTHER_HANDLER (); 505 506 my_name = "mrd_util_$abort"; 507 508 ourmp = SDB.ourmess; 509 hismp = SDB.hismess; 510 511 lock_set = "0"b; /* for cleanup handler */ 512 lock_ptr = null (); /* for cleanup handler */ 513 ipc_mask_code, ipc_unmask_code = -1; 514 515 on condition (cleanup) 516 call CLEAN_UP (); 517 518 if reqsw = 1 | reqsw = 3 then do; /* reset_read ==> wipe out messages in our seg */ 519 call LOCK (ourmp, code); 520 if code ^= 0 then return; 521 522 ourmp -> syscon_mseg.first_message, 523 ourmp -> syscon_mseg.last_message, 524 ourmp -> syscon_mseg.first_proto, 525 ourmp -> syscon_mseg.last_proto = 0; 526 call ipc_$drain_chn (ourmp -> syscon_mseg.ipc_el.channel, autocode); 527 call ipc_$drain_chn (ourmp -> syscon_mseg.proto_el.channel, autocode); 528 call UNLOCK (ourmp); 529 end; 530 531 if reqsw = 2 | reqsw = 3 then do; /* reset_write ==> wipe out messages from us in mc's seg */ 532 call LOCK (hismp, code); 533 if code ^= 0 then return; 534 535 do i = 1 to 2; /* look in both chains */ 536 prev_message = 0; 537 if i = 1 then chainp = addr (hismp -> syscon_mseg.first_message); 538 else chainp = addr (hismp -> syscon_mseg.first_proto); 539 540 call VALIDATE_CHAIN (hismp, chainp, "abort-1"); 541 542 this_message = chain.chain_head; 543 544 do while (this_message ^= 0); /* look for messages from us */ 545 if hismp -> syscon_mseg.message (this_message).from_source = SDB.source then 546 if hismp -> syscon_mseg.message (this_message).from_stream = SDB.stream then 547 do; /* found one */ 548 begin_this = this_message; 549 /* Loop looking for end of message */ 550 do while (hismp -> syscon_mseg.message (this_message).continue); 551 this_message = hismp -> syscon_mseg.message (this_message).next_message; 552 end; 553 end_this = this_message; 554 555 if prev_message = 0 then chain_head, this_message = 556 hismp -> syscon_mseg.message (end_this).next_message; 557 else hismp -> syscon_mseg.message (prev_message).next_message, this_message = 558 hismp -> syscon_mseg.message (end_this).next_message; 559 560 if end_this = chain_tail then chain_tail = prev_message; 561 hismp -> syscon_mseg.message (end_this).next_message = hismp -> syscon_mseg.first_free_buffer; 562 hismp -> syscon_mseg.first_free_buffer = begin_this; 563 end; 564 565 else do; 566 skipover: do while (hismp -> syscon_mseg.message (this_message).continue); 567 this_message = hismp -> syscon_mseg.message (this_message).next_message; 568 end; 569 this_message = hismp -> syscon_mseg.message (this_message).next_message; 570 end; 571 else go to skipover; /* sources don't match */ 572 end; 573 call VALIDATE_CHAIN (hismp, chainp, "abort-2"); 574 end; 575 576 ourmp -> syscon_mseg.mescount = 0; 577 ourmp -> syscon_mseg.output_wait = "0"b; 578 call UNLOCK (hismp); 579 end; 580 581 return; 582 583 LOCK: 584 procedure (bv_lock_ptr, bv_lock_code); 585 586 /* parameters */ 587 588 dcl (bv_lock_ptr ptr, 589 bv_lock_code fixed bin (35)) parameter; 590 591 /* automatic */ 592 593 dcl lock_code fixed bin (35); 594 595 lock_set = "0"b; /* we're not really locked yet */ 596 lock_ptr = bv_lock_ptr; /* remember which lock we're locking */ 597 598 call ipc_$mask_ev_calls (ipc_mask_code); /* mask ipc calls */ 599 call hcs_$set_ips_mask (""b, mask); /* mask ips interrupts */ 600 601 locking_loop: 602 call set_lock_$lock (lock_ptr -> syscon_mseg.mlock, thirty_seconds, lock_code); 603 if lock_code ^= 0 then 604 if lock_code = error_table_$lock_wait_time_exceeded then do; 605 call SAVE_STATE (lock_ptr); 606 lock_ptr -> syscon_mseg.mlock = "0"b; /* This is naughty but may save a crash. */ 607 call COMPLAIN (lock_ptr, "had to blast lock"); 608 goto locking_loop; 609 end; 610 else if lock_code = error_table_$invalid_lock_reset then do; 611 call COMPLAIN (lock_ptr, "reset bad lock"); 612 call SAVE_STATE (lock_ptr); 613 end; 614 else if lock_code = error_table_$locked_by_this_process then do; 615 call COMPLAIN (lock_ptr, "killing process due to mylock error"); 616 call SAVE_STATE (lock_ptr); 617 terminate_info.version = 0; 618 terminate_info.code = lock_code; 619 do while ("1"b); 620 call terminate_process_ ("fatal_error", 621 addr (terminate_info)); 622 end; 623 end; 624 else do; 625 bv_lock_code = lock_code; 626 call hcs_$reset_ips_mask (mask, mask); 627 call ipc_$unmask_ev_calls (ipc_unmask_code); 628 return; 629 end; 630 631 lock_ptr -> syscon_mseg.locked_by_pid = my_process_id; 632 lock_set = "1"b; 633 bv_lock_code = 0; 634 return; 635 636 end LOCK; 637 638 UNLOCK: 639 procedure (bv_unlock_ptr); 640 641 /* parameters */ 642 643 dcl bv_unlock_ptr ptr parameter; 644 645 /* automatic */ 646 647 dcl unlock_ptr ptr; 648 649 /* program */ 650 651 unlock_ptr = bv_unlock_ptr; /* remember what we're unlocking */ 652 lock_set = "0"b; /* Turn off now to avoid bad window */ 653 lock_ptr = null (); 654 call set_lock_$unlock (unlock_ptr -> syscon_mseg.mlock, autocode); 655 call hcs_$reset_ips_mask (mask, mask); 656 call ipc_$unmask_ev_calls (ipc_unmask_code); 657 return; 658 659 end UNLOCK; 660 661 SAVE_STATE: 662 procedure (bv_seg_ptr); 663 664 /* parameters */ 665 666 dcl bv_seg_ptr ptr parameter; 667 668 /* automatic */ 669 670 dcl (p, segp) ptr; 671 672 /* program */ 673 674 segp = bv_seg_ptr; 675 segp -> syscon_mseg.last_assigned_buffer = segp -> syscon_mseg.last_assigned_buffer + 1; 676 p = addr (segp -> syscon_mseg.message (segp -> syscon_mseg.last_assigned_buffer)); 677 p -> debug_info.flag = -1; 678 p -> debug_info.time = clock (); 679 p -> debug_info.last_pid = segp -> syscon_mseg.locked_by_pid; 680 p -> debug_info.first_msg = segp -> syscon_mseg.first_message; 681 p -> debug_info.last_msg = segp -> syscon_mseg.last_message; 682 p -> debug_info.first_pro = segp -> syscon_mseg.first_proto; 683 p -> debug_info.last_pro = segp -> syscon_mseg.last_proto; 684 p -> debug_info.free_chain = segp -> syscon_mseg.first_free_buffer; 685 686 end SAVE_STATE; 687 688 VALIDATE_CHAIN: 689 procedure (bv_seg_ptr, bv_chain_ptr, bv_where); 690 691 /* parameters */ 692 693 dcl (bv_chain_ptr ptr, 694 bv_seg_ptr ptr, 695 bv_where char (*)) parameter; 696 697 /* automatic */ 698 699 dcl (last_msgx, msgs_scanned, msgx) fixed bin; 700 dcl (chain_ptr, msgp, segp) ptr; 701 dcl why char (64) varying; 702 703 /* based */ 704 705 dcl 1 chain based (chain_ptr) aligned, 706 2 head fixed bin, 707 2 tail fixed bin; 708 709 /* program */ 710 711 segp = bv_seg_ptr; 712 chain_ptr = bv_chain_ptr; 713 714 if chain.head = 0 & chain.tail = 0 then return; 715 716 if chain.head = 0 & chain.tail ^= 0 then do; 717 why = "(head = 0 but tail ^= 0)"; 718 go to die; 719 end; 720 721 if chain.head ^= 0 & chain.tail = 0 then do; 722 why = "(head ^= 0 but tail = 0)"; 723 go to die; 724 end; 725 726 last_msgx = -1; 727 msgs_scanned = 0; 728 do msgx = chain.head repeat (msgp -> message_block.next_message) while (msgx ^= 0); 729 if msgs_scanned > 4662 then do; 730 why = "(loop in chain)"; 731 go to die; 732 end; 733 msgs_scanned = msgs_scanned + 1; 734 if msgx <= 0 | msgx > min (segp -> syscon_mseg.last_assigned_buffer, 4662) 735 then do; 736 why = "(msg index out of range)"; 737 go to die; 738 end; 739 if last_msgx = msgx then do; 740 why = "(chain loops onto self)"; 741 go to die; 742 end; 743 msgp = addr (segp -> syscon_mseg.message (msgx)); 744 last_msgx = msgx; 745 end; 746 747 if chain.tail ^= last_msgx then do; 748 why = "(chain.tail doesn't point to last msg)"; 749 go to die; 750 end; 751 752 return; 753 754 die: 755 call SAVE_STATE (segp); 756 call RESET_HEADER (segp); 757 call COMPLAIN (segp, bv_where || " " || why); 758 759 end VALIDATE_CHAIN; 760 761 COMPLAIN: 762 procedure (bv_complaint_ptr, bv_complaint); 763 764 /* parameters */ 765 766 dcl (bv_complaint char (*), 767 bv_complaint_ptr ptr) parameter; 768 769 /* automatic */ 770 771 dcl complaint_ptr ptr, 772 dname char (168), 773 dname_len fixed bin, 774 ename char (32); 775 776 /* program */ 777 778 complaint_ptr = bv_complaint_ptr; 779 call hcs_$fs_get_path_name (complaint_ptr, dname, dname_len, ename, (0)); 780 call phcs_$ring_0_message (my_name || ": " || bv_complaint || " in " || ename); 781 782 end COMPLAIN; 783 784 RESET_HEADER: 785 procedure (bv_reset_ptr); 786 787 /* parameters */ 788 789 dcl bv_reset_ptr ptr parameter; 790 791 /* automatic */ 792 793 dcl reset_ptr ptr; 794 795 /* program */ 796 797 reset_ptr = bv_reset_ptr; 798 reset_ptr -> syscon_mseg.first_message = 0; /* zap msg chain */ 799 reset_ptr -> syscon_mseg.last_message = 0; 800 reset_ptr -> syscon_mseg.first_proto = 0; /* zap protocol chain */ 801 reset_ptr -> syscon_mseg.last_proto = 0; 802 reset_ptr -> syscon_mseg.first_free_buffer = 0; /* zap free chain */ 803 reset_ptr -> syscon_mseg.last_assigned_buffer = 0; 804 805 end RESET_HEADER; 806 807 RETURN: 808 /**** any_other handler comes here. */ 809 return; 810 811 ANY_OTHER_HANDLER: 812 procedure (); 813 814 /**** This procedure is the any_other handler for mrd_util_. We report the 815* find of condition, reset the message segment header elements, unlock 816* the message segment if locked and return to mrd_ with an error status 817* code. */ 818 819 call find_condition_info_ (null, addr(ci), code); 820 if code = 0 then do; 821 call COMPLAIN (lock_ptr, "Condition encountered: "||ci.condition_name); 822 if ci.condition_name = "out_of_bounds" then do; 823 if lock_ptr ^= null & lock_ptr ^= hismp then 824 call RESET_HEADER (lock_ptr); 825 /* lock_ptr probably mc.message pointer anyway */ 826 else call RESET_HEADER (hismp); /* mc.message */ 827 end; 828 end; 829 if lock_ptr ^= null then call UNLOCK (lock_ptr); 830 code = error_table_$unable_to_do_io; 831 goto RETURN; 832 end ANY_OTHER_HANDLER; 833 834 CLEAN_UP: 835 procedure (); 836 837 if lock_set then 838 do; 839 call set_lock_$unlock (lock_ptr -> syscon_mseg.mlock, (0)); 840 lock_set = "0"b; 841 lock_ptr = null (); 842 end; 843 844 if substr (mask, 36, 1) = "1"b then /* we were masked */ 845 call hcs_$reset_ips_mask (mask, mask); 846 847 if ipc_mask_code ^= -1 & ipc_unmask_code = -1 then 848 call ipc_$unmask_ev_calls (ipc_unmask_code); 849 850 return; 851 end CLEAN_UP; 852 853 /* format: off */ 854 /* BEGIN INCLUDE FILE ... condition_info.incl.pl1 */ 1 2 1 3 /* Structure for find_condition_info_. 1 4* 1 5* Written 1-Mar-79 by M. N. Davidoff. 1 6**/ 1 7 1 8 /* automatic */ 1 9 1 10 declare condition_info_ptr pointer; 1 11 1 12 /* based */ 1 13 1 14 declare 1 condition_info aligned based (condition_info_ptr), 1 15 2 mc_ptr pointer, /* pointer to machine conditions at fault time */ 1 16 2 version fixed binary, /* Must be 1 */ 1 17 2 condition_name char (32) varying, /* name of condition */ 1 18 2 info_ptr pointer, /* pointer to the condition data structure */ 1 19 2 wc_ptr pointer, /* pointer to wall crossing machine conditions */ 1 20 2 loc_ptr pointer, /* pointer to location where condition occured */ 1 21 2 flags unaligned, 1 22 3 crawlout bit (1), /* on if condition occured in lower ring */ 1 23 3 pad1 bit (35), 1 24 2 pad2 bit (36), 1 25 2 user_loc_ptr pointer, /* ptr to most recent nonsupport loc before condition occurred */ 1 26 2 pad3 (4) bit (36); 1 27 1 28 /* internal static */ 1 29 1 30 declare condition_info_version_1 1 31 fixed binary internal static options (constant) initial (1); 1 32 1 33 /* END INCLUDE FILE ... condition_info.incl.pl1 */ 854 855 /* ====== BEGIN INCLUDE SEGMENT syscon_mseg.incl.pl1 ====================================== */ 2 2 2 3 2 4 2 5 /****^ HISTORY COMMENTS: 2 6* 1) change(87-09-02,Parisek), approve(87-09-03,MECR0005), 2 7* audit(87-09-02,GDixon), install(87-09-03,MR12.1-1098): 2 8* Increase quit_bits from 72 bits to 504 bits so more than 72 sources 2 9* may enable quit without error. (phx20974) 2 10* END HISTORY COMMENTS */ 2 11 2 12 2 13 /* Message Coordinator message segment declaration. Each daemon process 2 14* enqueues its messages in a segment like this one. 2 15* 2 16* The segment consists of a header followed by many message blocks, 2 17* each capable of holding a message of 132 characters plus 2 18* information on when the message was sent, who it's from, etc. 2 19* These blocks are "allocated" only as needed and placed on a free 2 20* storage list when freed. Blocks in use are chained together in a 2 21* first-in-first-out queue. */ 2 22 2 23 dcl buff_len fixed bin init (132) internal static; 2 24 2 25 dcl 1 syscon_mseg aligned based, /* This header is of length 24 dec 30 oct words */ 2 26 2 mlock bit (36) aligned, 2 27 2 current_process_id bit (36), 2 28 2 ipc_el, /* mrdim_ blocks on this list for normal reads */ 2 29 3 n fixed bin, 2 30 3 pad fixed bin, 2 31 3 channel fixed bin (71), 2 32 2 proto_el, /* mrdim_ blocks on this list for attach and detach */ 2 33 3 n fixed bin, 2 34 3 pad fixed bin, 2 35 3 channel fixed bin (71), 2 36 2 flags unaligned, 2 37 3 test_mode bit (1), /* ON if running in test environment */ 2 38 3 receiver_woken bit (1), /* ON if wakeup sent but not received yet */ 2 39 3 unused bit (34), 2 40 2 first_message fixed bin, /* index of head of message chain */ 2 41 2 last_message fixed bin, /* index of tail of message chain */ 2 42 2 first_proto fixed bin, /* index of head of protocol chain */ 2 43 2 last_proto fixed bin, /* index of tail of protocol chain */ 2 44 2 first_free_buffer fixed bin, /* head of free chain */ 2 45 2 last_assigned_buffer fixed bin, /* high water mark of buffers ever used */ 2 46 2 no_of_streams fixed bin, 2 47 2 quit_bits bit (504), /* used in mc.message to mark a source waiting to be quit */ 2 48 2 locked_by_pid bit (36), /* process id of locker */ 2 49 2 mescount fixed bin, /* Count of unprinted messages */ 2 50 2 output_wait bit (1), /* TRUE if in output wait - mc_wakeups resets */ 2 51 2 pad fixed bin, 2 52 2 message (1) like message_block aligned; /* the array of messages */ 2 53 2 54 dcl 1 message_block aligned based (messp), /* 56 dec 70 oct words */ 2 55 2 time_sent fixed bin (71), 2 56 2 from_source char (32), 2 57 2 from_stream char (32), 2 58 2 source_index fixed bin, /* index in MRT */ 2 59 2 stream_index fixed bin, /* .. */ 2 60 2 next_message fixed bin, /* foward pointer of message chain */ 2 61 2 flags unal, 2 62 3 continue bit (1), /* ON if message continued in next block */ 2 63 3 introduction bit (1), /* ON if message is an introduction */ 2 64 3 farewell bit (1), /* ON if message is farewell */ 2 65 3 sentinel bit (1), /* ON if special formatting wanted */ 2 66 3 trace bit (1), /* used only by dump_msg */ 2 67 3 unused bit (31) unal, 2 68 2 length fixed bin, /* number of characters in body */ 2 69 2 message_body char (132); /* text of message */ 2 70 2 71 dcl 1 debug_info based aligned, 2 72 2 flag fixed bin (71), 2 73 2 time fixed bin (71), 2 74 2 last_pid bit (36), 2 75 2 first_msg fixed bin, 2 76 2 last_msg fixed bin, 2 77 2 first_pro fixed bin, 2 78 2 last_pro fixed bin, 2 79 2 free_chain fixed bin; 2 80 2 81 /* ------ END INCLUDE SEGMENT syscon_mseg.incl.pl1 -------------------------------------- */ 855 856 /* format: on */ 857 858 /* BEGIN MESSAGE DOCUMENTATION 859* 860* Message: 861* mrd_util_$ENTRY: CALL_CODE (MESSAGE) in ENAME 862* 863* S: $beep 864* 865* T: $run 866* 867* M: A problem has been discovered in the threading of the message 868* coordinator segment ENAME. CALL_CODE identifies the particular 869* call that failed, and MESSAGE identifies the reason for the failure. 870* Entry identifies the entrypoint in mrd_util_ that was called. 871* All pending messages in ENAME are discarded. 872* Debugging information is written into ENAME, and may be displayed 873* using the dump_syscon_mseg tool. 874* The message coordinator recovers from these errors and continues, 875* possibly with the loss of some input or output. 876* If ENAME is mc.message, some daemon output may be lost. 877* If ENAME is anything else, some input to that daemon may be lost, and 878* the operator should communicate with the daemon immediately, in case this has happened. 879* $err 880* 881* A: $inform 882* Save all console and message coordinator terminal output. 883* 884* Message: 885* mrd_util_$ENTRY: had to blast lock in ENAME 886* 887* S: $beep 888* 889* T: $run 890* 891* M: The lock in the message coordinator segment ENAME did not 892* unlock within thirty seconds. The lock is reset forcibly, 893* and locked to the calling process. 894* ENTRY identifies the entrypoint in mrd_util_ that was called. 895* Debugging information is written into ENAME, and may be displayed 896* using the dump_syscon_mseg tool. 897* Further errors may result if 898* the process that originally locked the segment left it in 899* an inconsistent state, or if it later starts up again. 900* 901* A: $inform 902* Save all console and message coordinator terminal output. 903* 904* Message: 905* mrd_util_$ENTRY: reset bad lock in ENAME 906* 907* S: $beep 908* 909* T: $run 910* 911* M: The message coordinator segment ENAME was locked to a 912* nonexistent process. The lock is reset and locked to the calling 913* process. ENTRY identifies the entrypoint in mrd_util_ that 914* was called. 915* Debugging information is written into ENAME, and may be displayed 916* using the dump_syscon_mseg tool. 917* Further errors may be reported if ENAME was in an inconsistent state. 918* 919* A: $inform 920* Save all console and message coordinator terminal output. 921* 922* Message: 923* mrd_util_$ENTRY: killing process due to mylock error in ENAME 924* 925* S: $term 926* 927* T: $run 928* 929* M: While trying to lock the message coordinator segment ENAME, 930* the lock was found to already be locked to the calling process. 931* ENTRY identifies the entrypoint in mrd_util_ that was called. 932* Debugging information is written into ENAME, and may be displayed 933* using the dump_syscon_mseg tool. 934* $err 935* 936* A: $inform 937* Save all console and message coordinator terminal output. 938* 939* Message: 940* mrd_util_$ENTRY: inconsistent threads in ENAME 941* 942* S: $beep 943* 944* T: $run 945* 946* M: While trying to add unused blocks to the free chain 947* in the message coordinator segment ENAME, an error was discovered. 948* ENTRY identifies the entrypoint in mrd_util_ that was called. 949* Debugging information is written into ENAME, and may be displayed 950* using the dump_syscon_mseg tool. 951* $err 952* 953* A: $inform 954* Save all console and message coordinator terminal output. 955* 956* Message: 957* Error: CONDITION in mrd_util_$ENTRY 958* 959* S: $beep 960* 961* T: $run 962* 963* M: CONDITION was signalled during a call to the entrypoint 964* ENTRY in mrd_util_. 965* A message coordinator dump is taken. 966* If the calling process had a message coordinator segment locked, that 967* segment is checked for consistency, and the lock is unlocked. 968* mrd_util_ then returns to its caller without retrying the operation that failed. 969* $err 970* 971* A: $inform 972* Save all console and message coordinator terminal output. 973* 974* END MESSAGE DOCUMENTATION */ 975 976 end mrd_util_; SOURCE FILES USED IN THIS COMPILATION. LINE NUMBER DATE MODIFIED NAME PATHNAME 0 09/21/87 1954.4 mrd_util_.pl1 >spec>install>1114>mrd_util_.pl1 854 1 06/28/79 1204.8 condition_info.incl.pl1 >ldd>include>condition_info.incl.pl1 855 2 09/04/87 2012.1 syscon_mseg.incl.pl1 >ldd>include>syscon_mseg.incl.pl1 NAMES DECLARED IN THIS COMPILATION. IDENTIFIER OFFSET LOC STORAGE CLASS DATA TYPE ATTRIBUTES AND REFERENCES (* indicates a set context) NAMES DECLARED BY DECLARE STATEMENT. LIMIT constant fixed bin(17,0) initial dcl 159 ref 235 NL constant char(1) initial unaligned dcl 159 ref 422 439 OWAIT constant fixed bin(17,0) initial dcl 159 ref 240 SDB based structure level 1 dcl 111 addr builtin function dcl 43 ref 191 197 202 207 231 232 289 302 359 360 402 415 418 419 434 435 490 537 538 620 620 676 743 819 819 any_other 000220 stack reference condition dcl 178 ref 224 335 349 503 autocode 000145 automatic fixed bin(35,0) dcl 63 set ref 327* 526* 527* 654* based_mess based char unaligned dcl 106 ref 422 424 439 441 begin_this 000147 automatic fixed bin(17,0) dcl 63 set ref 275* 291 317 319 340* 357* 384* 402 458 471 548* 562 buff_len constant fixed bin(17,0) initial dcl 2-23 ref 262 262 287 304 bv_chain_ptr parameter pointer dcl 693 ref 688 712 bv_complaint parameter char unaligned dcl 766 ref 761 780 bv_complaint_ptr parameter pointer dcl 766 ref 761 778 bv_lock_code parameter fixed bin(35,0) dcl 588 set ref 583 625* 633* bv_lock_ptr parameter pointer dcl 588 ref 583 596 bv_reset_ptr parameter pointer dcl 789 ref 784 797 bv_seg_ptr parameter pointer dcl 693 in procedure "VALIDATE_CHAIN" ref 688 711 bv_seg_ptr parameter pointer dcl 666 in procedure "SAVE_STATE" ref 661 674 bv_unlock_ptr parameter pointer dcl 643 ref 638 651 bv_where parameter char unaligned dcl 693 ref 688 757 chain based structure level 1 unaligned dcl 102 in procedure "mrd_util_" chain based structure level 1 dcl 705 in procedure "VALIDATE_CHAIN" chain_head based fixed bin(17,0) level 2 dcl 102 set ref 317 317* 379 384 397* 494 542 555* chain_ptr 000276 automatic pointer dcl 700 set ref 712* 714 714 716 716 721 721 728 747 chain_tail 1 based fixed bin(17,0) level 2 dcl 102 set ref 319 321* 398 398* 560 560* chainp 000136 automatic pointer dcl 63 set ref 197* 202* 207* 232* 315* 317 317 319 321 359* 360* 375* 379 384 397 398 398 490* 494 537* 538* 540* 542 555 560 560 573* channel 10 based fixed bin(71,0) level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 195 205 527* channel 4 based fixed bin(71,0) level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 200 230 492 526* char_array based char(1) array unaligned dcl 106 set ref 289 302 415 419 435 char_event_mess based char(8) unaligned dcl 106 set ref 191* 231* ci 000162 automatic structure level 1 dcl 89 set ref 819 819 cleanup 000226 stack reference condition dcl 179 ref 254 369 515 clock builtin function dcl 43 ref 290 678 code parameter fixed bin(35,0) dcl 47 in procedure "mrd_util_" set ref 183 210* 217 221 240* 248* 257* 258 309* 310 331 342* 346 355* 372* 373 380* 467* 468 479 500 519* 520 532* 533 819* 820 830* code 1 000216 automatic fixed bin(35,0) level 2 in structure "terminate_info" dcl 96 in procedure "mrd_util_" set ref 618* complaint_ptr 000100 automatic pointer dcl 771 set ref 778* 779* condition_info based structure level 1 dcl 1-14 condition_name 3 000162 automatic varying char(32) level 2 dcl 89 set ref 821 822 continue 71 based bit(1) array level 4 in structure "syscon_mseg" packed unaligned dcl 2-25 in procedure "mrd_util_" set ref 282* 390 421 550 566 continue 000214 automatic bit(1) level 2 in structure "message_type" packed unaligned dcl 90 in procedure "mrd_util_" set ref 264* current_block 65 based fixed bin(17,0) level 3 dcl 111 set ref 384* 416 429* current_process_id 1 based bit(36) level 2 dcl 2-25 set ref 235 235 327* debug_info based structure level 1 dcl 2-71 divide builtin function dcl 43 ref 262 dname 000102 automatic char(168) unaligned dcl 771 set ref 779* dname_len 000154 automatic fixed bin(17,0) dcl 771 set ref 779* dont_flood 000100 automatic bit(1) initial dcl 60 set ref 60* 219* 235 ename 000155 automatic char(32) unaligned dcl 771 set ref 779* 780 end_block 64 based fixed bin(17,0) level 3 dcl 111 set ref 341 356 395* 475* end_this 000150 automatic fixed bin(17,0) dcl 63 set ref 283* 321 341* 356* 395* 398 461 470 553* 555 557 560 561 error_table_$argerr 000044 external static fixed bin(35,0) dcl 169 ref 210 error_table_$invalid_lock_reset 000050 external static fixed bin(35,0) dcl 171 ref 610 error_table_$lock_wait_time_exceeded 000046 external static fixed bin(35,0) dcl 170 ref 603 error_table_$locked_by_this_process 000052 external static fixed bin(35,0) dcl 172 ref 614 error_table_$no_message 000054 external static fixed bin(35,0) dcl 173 ref 380 error_table_$unable_to_do_io 000056 external static fixed bin(35,0) dcl 174 ref 830 ev_chan based fixed bin(71,0) level 2 dcl 483 set ref 492* event_mess 000142 automatic fixed bin(71,0) dcl 63 set ref 191 231 327* farewell 0(02) 000214 automatic bit(1) level 2 packed unaligned dcl 90 set ref 206* find_condition_info_ 000012 constant entry external dcl 142 ref 819 first_block 63 based fixed bin(17,0) level 3 dcl 111 set ref 340 357 384* 473* first_char parameter fixed bin(17,0) dcl 47 ref 183 217 221 289 346 415 first_free_buffer 17 based fixed bin(17,0) level 2 dcl 2-25 set ref 266 271 272* 470 471* 561 562* 684 802* first_message 13 based fixed bin(17,0) level 2 dcl 2-25 set ref 202 232 360 490 522* 537 680 798* first_msg 5 based fixed bin(17,0) level 2 dcl 2-71 set ref 680* first_pro 7 based fixed bin(17,0) level 2 dcl 2-71 set ref 682* first_proto 15 based fixed bin(17,0) level 2 dcl 2-25 set ref 197 207 359 522* 538 682 800* flag based fixed bin(71,0) level 2 dcl 2-71 set ref 677* flags 71 based structure array level 3 in structure "syscon_mseg" packed unaligned dcl 2-25 in procedure "mrd_util_" set ref 279* flags 62 based structure level 2 in structure "SDB" dcl 111 in procedure "mrd_util_" flags 25 based structure level 2 in structure "message_block" packed unaligned dcl 2-54 in procedure "mrd_util_" set ref 408* 408 free_chain 11 based fixed bin(17,0) level 2 dcl 2-71 set ref 684* from_source 2 based char(32) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" set ref 404* 404 from_source 46 based char(32) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 295* 545 from_stream 12 based char(32) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" set ref 405* 405 from_stream 56 based char(32) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 296* 545 get_process_id_ 000014 constant entry external dcl 142 ref 194 hcs_$fs_get_path_name 000016 constant entry external dcl 142 ref 779 hcs_$reset_ips_mask 000020 constant entry external dcl 142 ref 626 655 844 hcs_$set_ips_mask 000022 constant entry external dcl 142 ref 599 hcs_$wakeup 000024 constant entry external dcl 142 ref 327 head based fixed bin(17,0) level 2 dcl 705 ref 714 716 721 728 hismess 36 based pointer level 2 dcl 111 ref 190 229 509 hismp 000124 automatic pointer dcl 63 set ref 190* 195 197 200 202 205 207 229* 230 232 235 257* 266 267 267 268 271 272 272 276 278 279 282 284* 294 295 296 297 298 299 300 305 309* 315* 319 323* 327 509* 532* 537 538 540* 545 545 550 551 555 557 557 561 561 562 566 567 569 573* 578* 823 826* i 000144 automatic fixed bin(17,0) dcl 63 set ref 422* 423 423 439* 440 440 535* 537* index builtin function dcl 43 ref 422 439 input_available 2 based bit(1) level 2 dcl 483 set ref 494* 496* introduction 0(01) 000214 automatic bit(1) level 2 packed unaligned dcl 90 set ref 196* ipc_$drain_chn 000026 constant entry external dcl 142 ref 526 527 ipc_$mask_ev_calls 000030 constant entry external dcl 142 ref 598 ipc_$unmask_ev_calls 000032 constant entry external dcl 142 ref 627 656 847 ipc_el 2 based structure level 2 dcl 2-25 ipc_mask_code 000157 automatic fixed bin(35,0) dcl 86 set ref 252* 367* 513* 598* 847 ipc_unmask_code 000160 automatic fixed bin(35,0) dcl 87 set ref 252* 367* 513* 627* 656* 847 847* last_assigned_buffer 20 based fixed bin(17,0) level 2 dcl 2-25 set ref 267* 267 268 675* 675 676 734 803* last_message 14 based fixed bin(17,0) level 2 dcl 2-25 set ref 522* 681 799* last_msg 6 based fixed bin(17,0) level 2 dcl 2-71 set ref 681* last_msgx 000272 automatic fixed bin(17,0) dcl 699 set ref 726* 739 744* 747 last_pid 4 based bit(36) level 2 dcl 2-71 set ref 679* last_pro 10 based fixed bin(17,0) level 2 dcl 2-71 set ref 683* last_proto 16 based fixed bin(17,0) level 2 dcl 2-25 set ref 522* 683 801* len 000156 automatic fixed bin(17,0) dcl 63 set ref 287* 299 300 302 303 304* 417* 422 423* 424 424 425 426 432 435 436* 439 440* 441 441 442 443 length 72 based fixed bin(17,0) array level 3 dcl 2-25 set ref 300* 417 426 436 444 lock_code 000250 automatic fixed bin(35,0) dcl 593 set ref 601* 603 603 610 614 618 625 lock_ptr 000102 automatic pointer initial dcl 61 set ref 61* 251* 366* 512* 596* 601 605* 606 607* 611* 612* 615* 616* 631 653* 821* 823 823 823* 829 829* 839 841* lock_set 000104 automatic bit(1) initial dcl 62 set ref 62* 250* 365* 511* 595* 632* 652* 837 840* locked_by_pid 40 based bit(36) level 2 dcl 2-25 set ref 631* 679 mask 000105 automatic bit(36) initial dcl 63 set ref 63* 223* 334* 348* 502* 599* 626* 626* 655* 655* 844 844* 844* mescount 41 based fixed bin(17,0) level 2 dcl 2-25 set ref 235 243* 243 576* message 44 based structure array level 2 dcl 2-25 set ref 402 676 743 message_block based structure level 1 dcl 2-54 message_body 73 based char(132) array level 3 dcl 2-25 set ref 299* 418 434 message_type 000214 automatic structure level 1 packed unaligned dcl 90 set ref 189* 228* 279 messp 000126 automatic pointer dcl 63 set ref 402* 403 404 405 406 407 408 messp1 000130 automatic pointer dcl 63 set ref 353* 403 404 405 406 407 408 min builtin function dcl 43 ref 287 304 417 436 734 mlock based bit(36) level 2 dcl 2-25 set ref 601* 606* 654* 839* more 62(04) based bit(1) level 3 packed unaligned dcl 111 set ref 361 448* 454* mp parameter pointer dcl 63 ref 346 353 msgp 000300 automatic pointer dcl 700 set ref 743* 745 msgs_scanned 000273 automatic fixed bin(17,0) dcl 699 set ref 727* 729 733* 733 msgx 000274 automatic fixed bin(17,0) dcl 699 set ref 728* 728* 734 734 739 743 744* my_name 000106 automatic varying char(32) dcl 63 set ref 188* 227* 338* 352* 506* 780 my_process_id 000010 internal static bit(36) initial dcl 159 set ref 194* 631 n 000154 automatic fixed bin(17,0) dcl 63 set ref 265* 275* 293* nchar parameter fixed bin(17,0) dcl 47 ref 183 217 221 262 287 304 346 417 433 436 nchart parameter fixed bin(17,0) dcl 47 set ref 183 217 221 247* 303* 303 304 311* 346 354* 425* 425 433 436 442* 442 next_message 70 based fixed bin(17,0) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 272 276* 278* 305 319* 391 397 429 470* 551 555 557 557* 561* 567 569 next_message 24 based fixed bin(17,0) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" ref 745 no_of_blocks 000155 automatic fixed bin(17,0) dcl 63 set ref 262* 265 293 388* 392* 392 null builtin function dcl 43 ref 61 251 366 512 653 819 819 823 829 841 offset 66 based fixed bin(17,0) level 3 dcl 111 set ref 377* 417 419 426 428* 432* 432 443* 443 444 ourmess 34 based pointer level 2 dcl 111 ref 233 245 339 358 489 508 ourmp 000120 automatic pointer dcl 63 set ref 233* 235 235 235 239 243 243 245* 339* 358* 359 360 372* 375* 390 391 397 400* 402 417 418 421 426 429 434 436 444 462* 463* 467* 470 470 471 476* 489* 490 492 508* 519* 522 522 522 522 526 527 528* 576 577 output_wait 42 based bit(1) level 2 dcl 2-25 set ref 235 239* 577* p 000260 automatic pointer dcl 670 set ref 676* 677 678 679 680 681 682 683 684 phcs_$ring_0_message 000034 constant entry external dcl 142 ref 780 prev_message 000151 automatic fixed bin(17,0) dcl 63 set ref 276 277* 536* 555 557 560 prev_trans 63 based structure level 2 dcl 111 proto_el 6 based structure level 2 dcl 2-25 recursion 000122 automatic fixed bin(17,0) initial dcl 63 set ref 63* reqsw parameter fixed bin(17,0) dcl 47 ref 500 518 518 531 531 request parameter char unaligned dcl 47 ref 183 191 193 199 204 346 359 reset_ptr 000100 automatic pointer dcl 793 set ref 797* 798 799 800 801 802 803 segp 000302 automatic pointer dcl 700 in procedure "VALIDATE_CHAIN" set ref 711* 734 743 754* 756* 757* segp 000262 automatic pointer dcl 670 in procedure "SAVE_STATE" set ref 674* 675 675 676 676 679 680 681 682 683 684 sentinel 0(03) 000214 automatic bit(1) level 2 packed unaligned dcl 90 set ref 201* set_lock_$lock 000036 constant entry external dcl 142 ref 601 set_lock_$unlock 000040 constant entry external dcl 142 ref 654 839 source 40 based char(32) level 2 dcl 111 ref 295 545 source_index 66 based fixed bin(17,0) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 297* source_index 60 based fixed bin(17,0) level 2 in structure "SDB" dcl 111 in procedure "mrd_util_" ref 297 source_index 22 based fixed bin(17,0) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" set ref 406* 406 state parameter fixed bin(17,0) dcl 47 set ref 217 221 331 346 446* 456* 500 status_struct based structure level 1 dcl 483 statusp parameter pointer dcl 487 ref 479 492 494 496 stream 50 based char(32) level 2 dcl 111 ref 296 545 stream_index 23 based fixed bin(17,0) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" set ref 407* 407 stream_index 67 based fixed bin(17,0) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 298* stream_index 61 based fixed bin(17,0) level 2 in structure "SDB" dcl 111 in procedure "mrd_util_" ref 298 string builtin function dcl 43 set ref 189* 228* 279* 279 408* 408 substr builtin function dcl 43 ref 844 syscon_mseg based structure level 1 dcl 2-25 tail 1 based fixed bin(17,0) level 2 dcl 705 ref 714 716 721 747 terminate_info 000216 automatic structure level 1 dcl 96 set ref 620 620 terminate_process_ 000042 constant entry external dcl 155 ref 620 thatp 000132 automatic pointer dcl 63 set ref 418* 419* 419 422 424 434* 439 441 thirty_seconds 000000 constant fixed bin(17,0) initial dcl 159 set ref 601* this_batch based char unaligned dcl 106 set ref 299 424* 441* this_message 000146 automatic fixed bin(17,0) dcl 63 set ref 268* 271* 272 275 276 277 278 279 282 283 291* 294 295 296 297 298 299 300 305* 305 384* 390 391* 391 395 397 416* 417 418 421 426 429 429* 434 436 444 542* 544 545 545 548 550 551* 551 553 555* 557* 566 567* 567 569* 569 thisp 000134 automatic pointer dcl 63 set ref 288* 289* 289 299 302* 302 410* 415* 415 424 435* 435 441 time 000152 automatic fixed bin(71,0) dcl 63 in procedure "mrd_util_" set ref 290* 294 time 2 based fixed bin(71,0) level 2 in structure "debug_info" dcl 2-71 in procedure "mrd_util_" set ref 678* time_sent based fixed bin(71,0) level 2 in structure "message_block" dcl 2-54 in procedure "mrd_util_" set ref 403* 403 time_sent 44 based fixed bin(71,0) array level 3 in structure "syscon_mseg" dcl 2-25 in procedure "mrd_util_" set ref 294* tp parameter pointer dcl 47 ref 183 190 217 221 229 233 245 295 296 297 298 331 339 340 341 346 356 357 358 361 377 384 384 395 416 417 419 426 428 429 432 432 443 443 444 448 454 473 475 479 489 500 508 509 545 545 unlock_ptr 000100 automatic pointer dcl 647 set ref 651* 654 version 000216 automatic fixed bin(17,0) level 2 dcl 96 set ref 617* wake_up_chan 000140 automatic fixed bin(71,0) dcl 63 set ref 195* 200* 205* 230* 327* why 000304 automatic varying char(64) dcl 701 set ref 717* 722* 730* 736* 740* 748* 757 workp parameter pointer dcl 47 ref 183 217 221 288 346 410 NAMES DECLARED BY DECLARE STATEMENT AND NEVER REFERENCED. condition_info_ptr automatic pointer dcl 1-10 condition_info_version_1 internal static fixed bin(17,0) initial dcl 1-30 continue_to_signal_ 000000 constant entry external dcl 142 NAMES DECLARED BY EXPLICIT CONTEXT. ANY_OTHER_HANDLER 003306 constant entry internal dcl 811 ref 224 335 349 503 CLEAN_UP 003452 constant entry internal dcl 834 ref 254 369 515 COMPLAIN 003127 constant entry internal dcl 761 ref 462 607 611 615 757 821 LOCK 002341 constant entry internal dcl 583 ref 257 309 372 467 519 532 RESET_HEADER 003265 constant entry internal dcl 784 ref 756 823 826 RETURN 002340 constant label dcl 807 ref 831 SAVE_STATE 002641 constant entry internal dcl 661 ref 463 605 612 616 754 UNLOCK 002572 constant entry internal dcl 638 ref 284 323 400 476 528 578 829 VALIDATE_CHAIN 002675 constant entry internal dcl 688 ref 315 375 540 573 abort 001751 constant entry external dcl 500 common_write 000513 constant label dcl 245 ref 213 die 003050 constant label dcl 754 ref 718 723 731 737 741 749 discard_remainder 001047 constant entry external dcl 331 free_current_chain 001612 constant label dcl 454 ref 344 get_message 001413 constant label dcl 410 ref 361 locking_loop 002371 constant label dcl 601 ref 608 mrd_util_ 000231 constant entry external dcl 24 protocol 000246 constant entry external dcl 183 read 001134 constant entry external dcl 346 read_return 001670 constant label dcl 473 ref 381 read_status 001710 constant entry external dcl 479 skipover 002302 constant label dcl 566 ref 545 theres_more 001602 constant label dcl 446 ref 432 433 write 000411 constant entry external dcl 221 write_dont_flood 000371 constant entry external dcl 217 THERE WERE NO NAMES DECLARED BY CONTEXT OR IMPLICATION. STORAGE REQUIREMENTS FOR THIS PROGRAM. Object Text Link Symbol Defs Static Start 0 0 4242 4322 3610 4252 Length 4620 3610 60 261 432 2 BLOCK NAME STACK SIZE TYPE WHY NONQUICK/WHO SHARES STACK FRAME mrd_util_ 324 external procedure is an external procedure. on unit on line 224 64 on unit on unit on line 254 64 on unit on unit on line 335 64 on unit on unit on line 349 64 on unit on unit on line 369 64 on unit on unit on line 503 64 on unit on unit on line 515 64 on unit LOCK internal procedure shares stack frame of external procedure mrd_util_. UNLOCK 72 internal procedure is called by several nonquick procedures. SAVE_STATE internal procedure shares stack frame of external procedure mrd_util_. VALIDATE_CHAIN internal procedure shares stack frame of external procedure mrd_util_. COMPLAIN 148 internal procedure is called during a stack extension. RESET_HEADER 66 internal procedure is called by several nonquick procedures. ANY_OTHER_HANDLER 90 internal procedure is called by several nonquick procedures. CLEAN_UP 72 internal procedure is called by several nonquick procedures. STORAGE FOR INTERNAL STATIC VARIABLES. LOC IDENTIFIER BLOCK NAME 000010 my_process_id mrd_util_ STORAGE FOR AUTOMATIC VARIABLES. STACK FRAME LOC IDENTIFIER BLOCK NAME COMPLAIN 000100 complaint_ptr COMPLAIN 000102 dname COMPLAIN 000154 dname_len COMPLAIN 000155 ename COMPLAIN RESET_HEADER 000100 reset_ptr RESET_HEADER UNLOCK 000100 unlock_ptr UNLOCK mrd_util_ 000100 dont_flood mrd_util_ 000102 lock_ptr mrd_util_ 000104 lock_set mrd_util_ 000105 mask mrd_util_ 000106 my_name mrd_util_ 000120 ourmp mrd_util_ 000122 recursion mrd_util_ 000124 hismp mrd_util_ 000126 messp mrd_util_ 000130 messp1 mrd_util_ 000132 thatp mrd_util_ 000134 thisp mrd_util_ 000136 chainp mrd_util_ 000140 wake_up_chan mrd_util_ 000142 event_mess mrd_util_ 000144 i mrd_util_ 000145 autocode mrd_util_ 000146 this_message mrd_util_ 000147 begin_this mrd_util_ 000150 end_this mrd_util_ 000151 prev_message mrd_util_ 000152 time mrd_util_ 000154 n mrd_util_ 000155 no_of_blocks mrd_util_ 000156 len mrd_util_ 000157 ipc_mask_code mrd_util_ 000160 ipc_unmask_code mrd_util_ 000162 ci mrd_util_ 000214 message_type mrd_util_ 000216 terminate_info mrd_util_ 000250 lock_code LOCK 000260 p SAVE_STATE 000262 segp SAVE_STATE 000272 last_msgx VALIDATE_CHAIN 000273 msgs_scanned VALIDATE_CHAIN 000274 msgx VALIDATE_CHAIN 000276 chain_ptr VALIDATE_CHAIN 000300 msgp VALIDATE_CHAIN 000302 segp VALIDATE_CHAIN 000304 why VALIDATE_CHAIN THE FOLLOWING EXTERNAL OPERATORS ARE USED BY THIS PROGRAM. r_e_as alloc_char_temp cat_realloc_chars call_ext_out_desc call_ext_out call_int_this_desc call_int_this call_int_other_desc call_int_other return_mac tra_ext_1 enable_op shorten_stack ext_entry ext_entry_desc int_entry int_entry_desc clock_mac THE FOLLOWING EXTERNAL ENTRIES ARE CALLED BY THIS PROGRAM. find_condition_info_ get_process_id_ hcs_$fs_get_path_name hcs_$reset_ips_mask hcs_$set_ips_mask hcs_$wakeup ipc_$drain_chn ipc_$mask_ev_calls ipc_$unmask_ev_calls phcs_$ring_0_message set_lock_$lock set_lock_$unlock terminate_process_ THE FOLLOWING EXTERNAL VARIABLES ARE USED BY THIS PROGRAM. error_table_$argerr error_table_$invalid_lock_reset error_table_$lock_wait_time_exceeded error_table_$locked_by_this_process error_table_$no_message error_table_$unable_to_do_io LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC 60 000220 61 000221 62 000223 63 000224 24 000230 183 000237 188 000265 189 000272 190 000273 191 000300 193 000305 194 000311 195 000320 196 000323 197 000325 198 000327 199 000330 200 000334 201 000336 202 000340 203 000342 204 000343 205 000347 206 000351 207 000353 208 000355 210 000356 211 000361 213 000362 217 000363 219 000404 221 000406 223 000424 224 000425 227 000447 228 000454 229 000455 230 000462 231 000464 232 000466 233 000470 235 000472 239 000505 240 000507 241 000511 243 000512 245 000513 247 000520 248 000521 250 000522 251 000523 252 000525 254 000530 257 000552 258 000562 262 000564 264 000571 265 000573 266 000601 267 000604 268 000605 269 000607 271 000610 272 000611 275 000614 276 000622 277 000627 278 000630 279 000632 280 000634 282 000636 283 000643 284 000645 287 000653 288 000661 289 000664 290 000670 291 000672 293 000674 294 000703 295 000711 296 000720 297 000724 298 000726 299 000730 300 000736 302 000740 303 000743 304 000744 305 000752 306 000754 309 000756 310 000766 311 000770 312 000772 315 000773 317 001000 319 001005 321 001013 323 001016 327 001024 329 001042 331 001043 334 001062 335 001063 338 001105 339 001112 340 001117 341 001121 342 001123 344 001124 346 001125 348 001155 349 001156 352 001200 353 001205 354 001211 355 001212 356 001213 357 001217 358 001221 359 001223 360 001234 361 001236 365 001241 366 001242 367 001244 369 001247 372 001271 373 001301 375 001303 377 001310 379 001314 380 001316 381 001321 384 001322 388 001326 390 001330 391 001337 392 001341 393 001342 395 001343 397 001351 398 001354 400 001361 402 001367 403 001374 404 001376 405 001402 406 001405 407 001407 408 001411 410 001413 415 001417 416 001423 417 001427 418 001440 419 001442 421 001446 422 001455 423 001470 424 001472 425 001477 426 001502 428 001511 429 001512 431 001515 432 001516 432 001520 433 001521 434 001525 435 001531 436 001534 437 001544 439 001545 440 001560 441 001562 442 001567 443 001572 444 001575 446 001602 448 001604 449 001611 454 001612 456 001617 458 001620 461 001622 462 001624 463 001643 464 001645 467 001646 468 001656 470 001660 471 001666 473 001670 475 001674 476 001675 477 001703 479 001704 489 001721 490 001726 492 001730 494 001733 496 001740 498 001743 500 001744 502 001764 503 001765 506 002007 508 002014 509 002021 511 002023 512 002024 513 002026 515 002031 518 002053 519 002061 520 002071 522 002073 526 002100 527 002111 528 002123 531 002131 532 002137 533 002147 535 002151 536 002157 537 002160 538 002166 540 002171 542 002176 544 002200 545 002202 548 002223 550 002225 551 002235 552 002237 553 002240 555 002242 557 002252 560 002264 561 002272 562 002277 563 002301 566 002302 567 002311 568 002313 569 002314 572 002316 573 002317 574 002324 576 002326 577 002330 578 002331 581 002337 807 002340 583 002341 595 002343 596 002344 598 002347 599 002356 601 002371 603 002404 605 002411 606 002413 607 002414 608 002436 610 002437 611 002441 612 002461 613 002463 614 002464 615 002466 616 002505 617 002507 618 002510 620 002512 622 002535 623 002536 625 002537 626 002541 627 002550 628 002557 631 002560 632 002564 633 002566 634 002570 638 002571 651 002577 652 002603 653 002605 654 002607 655 002617 656 002630 657 002640 661 002641 674 002643 675 002646 676 002647 677 002653 678 002655 679 002657 680 002662 681 002664 682 002666 683 002670 684 002672 686 002674 688 002675 711 002706 712 002712 714 002715 716 002727 717 002733 718 002740 721 002741 722 002745 723 002752 726 002753 727 002755 728 002756 729 002762 730 002765 731 002772 733 002773 734 002774 736 003005 737 003012 739 003013 740 003016 741 003023 743 003024 744 003030 745 003032 747 003035 748 003041 749 003046 752 003047 754 003050 756 003052 757 003060 759 003124 761 003126 778 003142 779 003146 780 003177 782 003262 784 003264 797 003272 798 003276 799 003277 800 003300 801 003301 802 003302 803 003303 805 003304 811 003305 819 003313 820 003333 821 003336 822 003370 823 003377 826 003417 829 003426 830 003442 831 003446 834 003451 837 003457 839 003462 840 003473 841 003475 844 003477 847 003513 850 003531 ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved