1 #ifndef EXEC_TASKS_H 2 #define EXEC_TASKS_H 3 4 /* 5 exec task definitions (V51) 6 7 Copyright © 2002-2025 The MorphOS Development Team, All Rights Reserved. 8 */ 9 10 #ifndef EXEC_NODES_H 11 # include <exec/nodes.h> 12 #endif 13 14 #ifndef EXEC_LISTS_H 15 # include <exec/lists.h> 16 #endif 17 18 #ifndef EXEC_PORTS_H 19 # include <exec/ports.h> 20 #endif 21 22 #pragma pack(2) 23 24 25 struct ETask; 26 27 struct Task 28 { 29 struct Node tc_Node; 30 UBYTE tc_Flags; 31 UBYTE tc_State; 32 BYTE tc_IDNestCnt; 33 BYTE tc_TDNestCnt; 34 ULONG tc_SigAlloc; 35 ULONG tc_SigWait; 36 ULONG tc_SigRecvd; 37 ULONG tc_SigExcept; 38 #if 0 39 UWORD tc_TrapAlloc; 40 UWORD tc_TrapAble; 41 #else 42 struct ETask *tc_ETask; 43 #endif 44 APTR tc_ExceptData; 45 APTR tc_ExceptCode; 46 APTR tc_TrapData; 47 APTR tc_TrapCode; 48 APTR tc_SPReg; 49 APTR tc_SPLower; 50 APTR tc_SPUpper; 51 VOID (*tc_Switch)(VOID); /*** OBSOLETE ***/ 52 VOID (*tc_Launch)(VOID); /*** OBSOLETE ***/ 53 struct List tc_MemEntry; 54 APTR tc_UserData; 55 }; 56 57 /* 58 * Please use these macros in the future to declare, define and reference 59 * task codestarts. That way we can easily change the way SysBase is passed 60 * to a task to avoid ABSEXECBASE. 61 * 62 * ABOX_TASKPROTO(void,TaskStart,void *); 63 * ABOX_TASK(void,TaskStart,void *Arg1) 64 * { 65 * ABOX_DEFTASKSYSBASE; 66 * } 67 * 68 * NewCreateTask(TASKTAG_PC,ABOX_TASKREF(TaskStart),TASKTAG_PPC_ARG1,Arg1,...,TAG_DONE); 69 */ 70 #define ABOX_TASKREF(n) n##_start 71 #define ABOX_TASKPROTO(t,n,...) t n##_start(__VA_ARGS__) 72 #define ABOX_TASK(t,n,...) t n##_start(__VA_ARGS__) 73 #define ABOX_GETTASKSYSBASE MyEmulHandle->SuperHandle->GlobalSysBase 74 #define ABOX_DEFTASKSYSBASE struct ExecBase *SysBase=ABOX_GETTASKSYSBASE 75 76 #define TB_PROCTIME 0 77 #define TB_ETASK 3 78 #define TB_STACKCHK 4 79 #define TB_EXCEPT 5 80 #define TB_SWITCH 6 81 #define TB_LAUNCH 7 82 83 #define TF_PROCTIME (1 << TB_PROCTIME) 84 #define TF_ETASK (1 << TB_ETASK) 85 #define TF_STACKCHK (1 << TB_STACKCHK) 86 #define TF_EXCEPT (1 << TB_EXCEPT) 87 #define TF_SWITCH (1 << TB_SWITCH) 88 #define TF_LAUNCH (1 << TB_LAUNCH) 89 90 #define TS_INVALID 0 91 #define TS_ADDED 1 92 #define TS_RUN 2 93 #define TS_READY 3 94 #define TS_WAIT 4 95 #define TS_EXCEPT 5 96 #define TS_REMOVED 6 97 98 #define SIGB_ABORT 0 99 #define SIGB_CHILD 1 100 #define SIGB_BLIT 4 101 #define SIGB_SINGLE 4 102 #define SIGB_INTUITION 5 103 #define SIGB_NET 7 104 #define SIGB_DOS 8 105 106 #define SIGF_ABORT (1 << SIGB_ABORT) 107 #define SIGF_CHILD (1 << SIGB_CHILD) 108 #define SIGF_BLIT (1 << SIGB_BLIT) 109 #define SIGF_SINGLE (1 << SIGB_SINGLE) 110 #define SIGF_INTUITION (1 << SIGB_INTUITION) 111 #define SIGF_NET (1 << SIGB_NET) 112 #define SIGF_DOS (1 << SIGB_DOS) 113 114 115 struct TaskTrapMessage 116 { 117 struct Message Message; /* Message Header */ 118 struct Task *Task; /* connected Task */ 119 ULONG Version; /* version of the structure */ 120 ULONG Type; /* Exception Type */ 121 ULONG DAR; /* Exception Address Register */ 122 ULONG DSISR; /* Exception DSISR Reg */ 123 124 /* This is undiscovered land... 125 * never assume a size of this structure 126 */ 127 }; 128 129 #define VERSION_TASKTRAPMESSAGE 0x0 130 131 /* Added in exec 50.67 */ 132 /* 133 * Exec has now a more sophisticated 68k(emulation) trap management. 134 * In reality it's just a new system wide traphandler who sends logserver 135 * the msg and if this msg is replied it uses the new emulation state. 136 */ 137 struct TaskTrapMessage_68k 138 { 139 struct Message Message; /* Message Header */ 140 struct Task *Task; /* connected Task */ 141 ULONG Version; /* version of the structure */ 142 ULONG Type; /* Exception Type */ 143 ULONG Format; /* Exception Stackframe Format */ 144 void *Address; /* Hit Address */ 145 ULONG FLSW; 146 struct EmulHandle *MyEmulHandle; 147 }; 148 149 #define VERSION_TASKTRAPMESSAGE_68K 0x0 150 151 152 struct ETask 153 { 154 struct Message Message; 155 struct Task *Parent; 156 ULONG UniqueID; 157 struct MinList Children; 158 UWORD TrapAlloc; 159 UWORD TrapAble; 160 ULONG Result1; 161 void *Result2; 162 struct MsgPort MsgPort; 163 164 /* Don't touch!!!!!!!!!..there'll be an interface 165 * sooner than later. 166 * New Entries...most of the above entries 167 * are only there for structure compatability. 168 * They have no meaning as the OS never supported 169 * them. 170 */ 171 172 /* A Task Pool for the task. 173 */ 174 void *MemPool; 175 176 /* PPC's Stack Lower Ptr 177 * The initial stack is allocated through 178 * AllocVec, so a FreeVec(ETask->PPCSPLower); 179 * would work. 180 * If you use PPCStackSwap you must allocate 181 * your stack block with AllocVec(); 182 */ 183 void *PPCSPLower; 184 185 /* PPC's Stack Upper Ptr 186 */ 187 void *PPCSPUpper; 188 void *PPCRegFrame; 189 void *PPCLibData; 190 191 /* On a PPC exception this msgport 192 * is sent an exception msg.... 193 * the task is stopped until somebody 194 * wakes it up again. 195 * (asynchron exception interface) 196 * If this Port is NULL the message is 197 * sent to SysBase->ex_PPCTrapMsgPort. 198 */ 199 struct MsgPort *PPCTrapMsgPort; 200 struct TaskTrapMessage *PPCTrapMessage; 201 202 /* This is undiscovered land... 203 * never assume a size of this structure 204 */ 205 }; 206 207 struct TaskInitExtension 208 { 209 /* Must be filled with TRAP_PPCTASK 210 */ 211 UWORD Trap; 212 UWORD Extension; /* Must be set to 0 */ 213 struct TagItem *Tags; 214 }; 215 216 #define TASKTAG_DUMMY (TAG_USER + 0x100000) 217 218 /* Ptr to an ULONG Errorfield where a better error description 219 * can be stored. 220 */ 221 #define TASKTAG_ERROR (TASKTAG_DUMMY + 0x0) 222 223 /* Code type 224 * can be stored. 225 */ 226 #define TASKTAG_CODETYPE (TASKTAG_DUMMY + 0x1) 227 228 /* Start PC 229 * code must be of TASKTAG_CODETYPE 230 */ 231 #define TASKTAG_PC (TASKTAG_DUMMY + 0x2) 232 233 /* Final PC 234 * code must be of TASKTAG_CODETYPE 235 */ 236 #define TASKTAG_FINALPC (TASKTAG_DUMMY + 0x3) 237 238 /* Stacksize...Default 8192 239 */ 240 #define TASKTAG_STACKSIZE (TASKTAG_DUMMY + 0x4) 241 242 /* Std Stacksize... 243 * Default(use the stack defined by tc_SPLower..tc_SPUpper) 244 */ 245 #define TASKTAG_STACKSIZE_M68K (TASKTAG_DUMMY + 0x5) 246 247 /* 248 * specify task name, name is copied 249 */ 250 #define TASKTAG_NAME (TASKTAG_DUMMY + 0x6) 251 252 /* 253 * tc_UserData 254 */ 255 #define TASKTAG_USERDATA (TASKTAG_DUMMY + 0x7) 256 257 /* 258 * Task priority 259 */ 260 #define TASKTAG_PRI (TASKTAG_DUMMY + 0x8) 261 262 /* 263 * Pool's Puddlesize 264 */ 265 #define TASKTAG_POOLPUDDLE (TASKTAG_DUMMY + 0x9) 266 267 /* 268 * Pool's ThreshSize 269 */ 270 #define TASKTAG_POOLTHRESH (TASKTAG_DUMMY + 0xa) 271 272 273 /* PPC First Argument..gpr3 274 */ 275 #define TASKTAG_PPC_ARG1 (TASKTAG_DUMMY + 0x10) 276 277 /* PPC First Argument..gpr4 278 */ 279 #define TASKTAG_PPC_ARG2 (TASKTAG_DUMMY + 0x11) 280 281 /* PPC First Argument..gpr5 282 */ 283 #define TASKTAG_PPC_ARG3 (TASKTAG_DUMMY + 0x12) 284 285 /* PPC First Argument..gpr6 286 */ 287 #define TASKTAG_PPC_ARG4 (TASKTAG_DUMMY + 0x13) 288 289 /* PPC First Argument..gpr7 290 */ 291 #define TASKTAG_PPC_ARG5 (TASKTAG_DUMMY + 0x14) 292 293 /* PPC First Argument..gpr8 294 */ 295 #define TASKTAG_PPC_ARG6 (TASKTAG_DUMMY + 0x15) 296 297 /* PPC First Argument..gpr9 298 */ 299 #define TASKTAG_PPC_ARG7 (TASKTAG_DUMMY + 0x16) 300 301 /* PPC First Argument..gpr10 302 */ 303 #define TASKTAG_PPC_ARG8 (TASKTAG_DUMMY + 0x17) 304 305 306 307 /* 308 * Startup message to be passed to task/process, ReplyMsg'd at RemTask() 309 * ti_Data: struct Message * 310 */ 311 #define TASKTAG_STARTUPMSG (TASKTAG_DUMMY + 0x18) 312 313 /* 314 * Create internal MsgPort for task/process, deleted at RemTask() 315 * ti_Data: struct MsgPort **, can be NULL 316 */ 317 #define TASKTAG_TASKMSGPORT (TASKTAG_DUMMY + 0x19) 318 319 /* 320 * Set unitial tc_Flags 321 * ti_Data: UBYTE 322 */ 323 #define TASKTAG_FLAGS (TASKTAG_DUMMY + 0x1a) 324 325 326 /* 327 * Extra memory to allocate after task structure, the extra memory is 328 * cleared 329 * ti_Data: ULONG 330 */ 331 #define TASKTAG_TCBEXTRASIZE (TASKTAG_DUMMY + 0x1c) 332 333 334 335 336 #define CODETYPE_M68K 0x0 337 /* 338 * System V4 ABI 339 */ 340 #define CODETYPE_PPC 0x1 341 342 343 #define TASKERROR_OK 0 344 #define TASKERROR_NOMEMORY 1 345 346 347 /* 348 * Stack swap structure as passed to StackSwap() and PPCStackSwap() 349 */ 350 struct StackSwapStruct 351 { 352 APTR stk_Lower; /* Lowest byte of stack */ 353 ULONG stk_Upper; /* Upper end of stack (size + Lowest) */ 354 APTR stk_Pointer; /* Stack pointer at switch point */ 355 }; 356 357 struct PPCStackSwapArgs 358 { 359 ULONG Args[8]; /* The C register arguments from gpr3..gpr11 */ 360 }; 361 362 363 364 /* 365 * NewGetTaskAttrsA(), NewSetTaskAttrsA() tags 366 */ 367 368 #define TASKINFOTYPE_ALLTASK 0x0 369 #define TASKINFOTYPE_NAME 0x1 370 #define TASKINFOTYPE_PRI 0x2 371 #define TASKINFOTYPE_TYPE 0x3 372 #define TASKINFOTYPE_STATE 0x4 373 #define TASKINFOTYPE_FLAGS 0x5 374 #define TASKINFOTYPE_SIGALLOC 0x6 375 #define TASKINFOTYPE_SIGWAIT 0x7 376 #define TASKINFOTYPE_SIGRECVD 0x8 377 #define TASKINFOTYPE_SIGEXCEPT 0x9 378 #define TASKINFOTYPE_EXCEPTDATA 0xa 379 #define TASKINFOTYPE_EXCEPTCODE 0xb 380 #define TASKINFOTYPE_TRAPDATA 0xc 381 #define TASKINFOTYPE_TRAPCODE 0xd 382 #define TASKINFOTYPE_STACKSIZE_M68K 0xe 383 #define TASKINFOTYPE_STACKSIZE 0xf 384 #define TASKINFOTYPE_USEDSTACKSIZE_M68K 0x10 385 #define TASKINFOTYPE_USEDSTACKSIZE 0x11 386 #define TASKINFOTYPE_TRAPMSGPORT 0x12 387 #define TASKINFOTYPE_STARTUPMSG 0x13 388 #define TASKINFOTYPE_TASKMSGPORT 0x14 389 #define TASKINFOTYPE_POOLPTR 0x15 390 #define TASKINFOTYPE_POOLMEMFLAGS 0x16 391 #define TASKINFOTYPE_POOLPUDDLESIZE 0x17 392 #define TASKINFOTYPE_POOLTHRESHSIZE 0x18 393 394 /* 395 * Task Scheduler statistics (exec 50.42) 396 */ 397 #define TASKINFOTYPE_NICE 0x19 398 #define TASKINFOTYPE_AGETICKS 0x1a 399 #define TASKINFOTYPE_CPUTIME 0x1b 400 #define TASKINFOTYPE_LASTSECCPUTIME 0x1c 401 #define TASKINFOTYPE_RECENTCPUTIME 0x1d 402 #define TASKINFOTYPE_VOLUNTARYCSW 0x1e 403 #define TASKINFOTYPE_INVOLUNTARYCSW 0x1f 404 #define TASKINFOTYPE_LASTSECVOLUNTARYCSW 0x20 405 #define TASKINFOTYPE_LASTSECINVOLUNTARYCSW 0x21 406 /* Added in exec 50.45 */ 407 #define TASKINFOTYPE_LAUNCHTIMETICKS 0x22 408 #define TASKINFOTYPE_LAUNCHTIMETICKS1978 0x23 409 #define TASKINFOTYPE_PID_CLI 0x24 410 /* Added in exec 50.54 */ 411 #define TASKINFOTYPE_SPLOWER 0x26 412 #define TASKINFOTYPE_SPUPPER 0x27 413 #define TASKINFOTYPE_SPLOWER_M68K 0x28 414 #define TASKINFOTYPE_SPUPPER_M68K 0x29 415 #define TASKINFOTYPE_NAMECOPY 0x2a 416 /* 417 * Get/Set task tc_UserData 418 * Data: ULONG start 419 * DataSize: sizeof(ULONG) 420 * Added in exec 50.63 421 */ 422 #define TASKINFOTYPE_USERDATA 0x2b 423 /* 424 * Tag used to restart a suspended task 425 * Data: ULONG start 426 * DataSize: sizeof(ULONG) 427 * Set 'start' to nonzero to really start the task. 428 * Returns sizeof(ULONG) if suspended task was successfully restarted. 429 * NOTE: The task will get run immediately if it has higher priority 430 * than the caller and the task switching has not been disabled. 431 * Added in exec 50.63 432 */ 433 #define TASKINFOTYPE_RESURRECT_TASK 0x2c 434 /* 435 * Get/Set task emulhandle 436 * Data: APTR emulhandle 437 * DataSize: sizeof(APTR) 438 * Added in exec 50.63 439 */ 440 #define TASKINFOTYPE_EMULHANDLE 0x2d 441 /* 442 * Get task exception count 443 * Data: ULONG count 444 * DataSize: sizeof(ULONG) 445 * Added in exec 50.67 446 */ 447 #define TASKINFOTYPE_EXCEPTIONCOUNT 0x2e 448 /* 449 * Get task hit count 450 * Data: ULONG count 451 * DataSize: sizeof(ULONG) 452 * Added in exec 50.67 453 */ 454 #define TASKINFOTYPE_HITCOUNT 0x2f 455 /* 456 * Get/Set task max hit count. 457 * If more hits happen the task is put to sleep. 458 * Data: ULONG count 459 * DataSize: sizeof(ULONG) 460 * Added in exec 51.3 461 */ 462 #define TASKINFOTYPE_MAXHITCOUNT 0x30 463 /* 464 * Get task alert count 465 * Data: ULONG count 466 * DataSize: sizeof(ULONG) 467 * Added in exec 51.13 468 */ 469 #define TASKINFOTYPE_ALERTCOUNT 0x31 470 /* 471 * Get/Set task max alert count. 472 * If more alerts happen the task is put to sleep. 473 * Data: ULONG count 474 * DataSize: sizeof(ULONG) 475 * Added in exec 51.13 476 */ 477 #define TASKINFOTYPE_MAXALERTCOUNT 0x32 478 479 /* 480 * Get task unique ID. 481 * This ID is unique to every task. 482 * Data: ULONG id 483 * DataSize: sizeof(ULONG) 484 * Added in exec 51.14 485 */ 486 #define TASKINFOTYPE_PID 0x33 487 488 /* 489 * Returns task stack history. This is safe to call for the task itself, and 490 * using it on foreign tasks may give unpredictable results. At minimum the 491 * results will get stale unless if you properly extract information while 492 * keeping task scheduling locked. 493 * 494 * This info type is used to fetch struct TaskStackHistoryEntry records 495 * that hold the call stack of the task. Pass pointer to the struct 496 * TaskStacHistoryEntry array. The DataSize is used the pass the total size 497 * of the array, and the return value will contain the amount of data filled 498 * to the array. The return size is the total size of the filled array, so 499 * divide by sizeof(struct TaskStackHistoryEntry) to get number of entries. 500 * 501 * You can skip stack frames by using TASKINFOTAG_STACKHISTORY_SKIPFRAMES 502 * tag. Pass a number of frames to skip, default is 0, where no skipping is 503 * done. If you're calling NewGetTaskAttrs function yourself for your own 504 * task from a debug dump function, you might want to use skip value of 505 * 1 to omit the debug function itself from the stack history. 506 * 507 * Data: struct TaskStackHistoryEntry * 508 * DataSize: numentries * sizeof(struct TaskStackHistoryEntry) 509 * Added in exec 51.54 510 */ 511 #define TASKINFOTYPE_PPC_STACKHISTORY 0x34 512 513 #define TASKINFOTYPE_68K_NEWFRAME 0x50 514 515 #define TASKINFOTYPE_PPC_SRR0 0x100 516 #define TASKINFOTYPE_PPC_SRR1 0x101 517 #define TASKINFOTYPE_PPC_LR 0x102 518 #define TASKINFOTYPE_PPC_CTR 0x103 519 #define TASKINFOTYPE_PPC_CR 0x104 520 #define TASKINFOTYPE_PPC_XER 0x105 521 #define TASKINFOTYPE_PPC_GPR 0x106 522 #define TASKINFOTYPE_PPC_FPR 0x107 523 #define TASKINFOTYPE_PPC_FPSCR 0x108 524 #define TASKINFOTYPE_PPC_VSCR 0x109 525 #define TASKINFOTYPE_PPC_VPR 0x10a 526 #define TASKINFOTYPE_PPC_VSAVE 0x10b 527 #define TASKINFOTYPE_PPC_FRAME 0x10c 528 #define TASKINFOTYPE_PPC_FRAMESIZE 0x10d 529 #define TASKINFOTYPE_PPC_NEWFRAME 0x10e 530 531 #define TASKINFOTAG_DUMMY (TAG_USER + 0x110000) 532 /* Used with TASKINFOTYPE_ALLTASK 533 */ 534 #define TASKINFOTAG_HOOK (TASKINFOTAG_DUMMY + 0x0) 535 /* Used with TASKINFOTYPE_PPC_GPR,TASKINFOTYPE_PPC_FPR,TASKINFOTYPE_PPC_VMX 536 * to define the copy area 537 */ 538 #define TASKINFOTAG_REGSTART (TASKINFOTAG_DUMMY + 0x1) 539 /* Used with TASKINFOTYPE_PPC_GPR,TASKINFOTYPE_PPC_FPR,TASKINFOTYPE_PPC_VMX 540 * to define the copy area 541 */ 542 #define TASKINFOTAG_REGCOUNT (TASKINFOTAG_DUMMY + 0x2) 543 544 /* 545 * NewSetTaskAttrsA(..,&TaskFrame68k,sizeof(struct TaskFrame68k),TASKINFOTYPE_68K_NEWFRAME,...); 546 * 547 */ 548 struct TaskFrame68k 549 { 550 void *PC; 551 UWORD SR; 552 ULONG Xn[15]; 553 }; 554 555 #define TSHE_VALID 0 /* Address is considered valid */ 556 #define TSHE_INVALID 1 /* Address doesn't look like valid */ 557 struct TaskStackHistoryEntry 558 { 559 ULONG tshe_Type; /* Currently either TSHE_VALID or TSHE_INVALID */ 560 IPTR tshe_Address; /* Function return address */ 561 }; 562 563 /* Used with TASKINFOTYPE_PPC_STACKHISTORY to skip frames 564 */ 565 #define TASKINFOTAG_STACKHISTORY_SKIPFRAMES (TASKINFOTAG_DUMMY + 0x3) 566 567 568 /* 569 * Don't depend on these 570 */ 571 #define DEFAULT_PPCSTACKSIZE 32768 572 #define DEFAULT_M68KSTACKSIZE 2048 573 #define DEFAULT_TASKPUDDLESIZE 4096 574 #define DEFAULT_TASKTHRESHSIZE 4096 575 576 #define PID_CURRENT 0 577 578 579 /* 580 * TLSAlloc (V51.46) 581 */ 582 #define TLS_INVALID_INDEX (0xffffffff) 583 584 #define TLSTAG_DUMMY (TAG_USER + 0x120000) 585 /* Destructor function to call on task termination if the TLS value 586 * is non-NULL. The function is called with as: 587 * VOID function(APTR value, APTR userdata); 588 */ 589 #define TLSTAG_DESTRUCTOR (TLSTAG_DUMMY + 0x0) 590 /* Userdata for the destructor function. Defaults to NULL. 591 */ 592 #define TLSTAG_USERDATA (TLSTAG_DUMMY + 0x1) 593 594 595 #pragma pack() 596 597 #endif