- Timestamp:
- Oct 10, 2004, 12:48:19 PM (21 years ago)
- Location:
- trunk/src/emx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/include/InnoTekLIBC/sharedpm.h
-
Property cvs2svn:cvs-rev
changed from
1.7
to1.8
r1570 r1571 29 29 #include <sys/cdefs.h> 30 30 #include <sys/types.h> 31 #include <sys/signal.h> 31 32 32 33 __BEGIN_DECLS … … 56 57 * The SPM version. 57 58 */ 58 #define SPM_VERSION 0x0001000 059 #define SPM_VERSION 0x00010001 59 60 60 61 /** … … 105 106 __LIBC_EXIT_REASON_MAKE_INT32 = 0x7fffffff 106 107 } __LIBC_EXIT_REASON; 108 109 110 /** 111 * Signal (queued). 112 */ 113 typedef struct __libc_SPMSignal 114 { 115 /** Structure size. */ 116 unsigned cb; 117 /** Pointer to the next signal. */ 118 struct __libc_SPMSignal *pNext; 119 /** Signal info. */ 120 siginfo_t Info; 121 } __LIBC_SPMSIGNAL; 122 /** Pointer to (queued) signal. */ 123 typedef __LIBC_SPMSIGNAL *__LIBC_PSPMSIGNAL; 124 107 125 108 126 /** Inheritance FH Bundle Type. … … 253 271 /** Creation timestamp. */ 254 272 unsigned uTimestamp; 273 /** Incoming signal queue. 274 * This is a LIFO for speed and size. The receiving process will 275 * process them in the correct order of course. 276 * For signals which aren't queable only one signal can be queued. 277 */ 278 __LIBC_PSPMSIGNAL pSigHead; 279 /** Number of queued signals. 280 * After it passes 48 signals, only SIGCHLD will be queued. 281 * This means siqueue() won't work 100% according to spec. */ 282 unsigned cSigsQueued; 255 283 256 284 /** Reserved pool pointer field with default value 0. */ 257 unsigned aReserved[40 - 1 4];285 unsigned aReserved[40 - 16]; 258 286 259 287 /** Number of possible pointers to shared memory starting at pvInherit. … … 379 407 __LIBC_SPMLOADAVG LoadAvg; 380 408 409 /** List of free signal structures. This will reduce 410 * the time spent allocating a signal structure in most cases. 411 * During SPM init 8 signal structures will be allocated and queued. */ 412 __LIBC_PSPMSIGNAL pSigFreeHead; 413 /** Number of free signal structures in the list. 414 * This is used to prevent the list from growing infinitly under stress. 415 * When cSigFree reaches 32 unused signal structures will be freed instead 416 * of put in the list. */ 417 unsigned cSigFree; 418 /** Number of active signals. 419 * This is used to keep a reasonable limit of the number of active signal 420 * structures so a process cannot exhaust the shared memory pool. 421 * The maximum is defined by cSigMaxActive. 422 */ 423 unsigned cSigActive; 424 /** The maximum number of active signals. 425 * This is initialized by the SPM creator but can be adjusted later. 426 */ 427 unsigned cSigMaxActive; 428 381 429 /* The rest of the block, up to cbProcess, is undefined in this version. 382 430 * Future versions of LIBC may use this area assuming it's initalized with zeros. … … 593 641 594 642 /** 643 * Queues a signal on another process. 644 * 645 * @returns 0 on success. 646 * @returns Negative error code (errno.h) on failure. 647 * @param pSignal Signal to queue. 648 * @param pid Pid to queue it on. 649 * @param fQueued Set if the signal type is queued. 650 */ 651 int __libc_spmSigQueue(siginfo_t *pSignal, pid_t pid, int fQueued); 652 653 /** 654 * De-queues one or more pending signals. 655 * @returns Number of de-queued signals on success. 656 * @returns Negative error code (errno.h) on failure. 657 * @param paSignals Where to store the signals. 658 * @param cSignals Size of the signal array. 659 * @param cbSignal Size of one signal entry. 660 */ 661 int __libc_spmSigDequeue(siginfo_t *paSignals, unsigned cSignals, size_t cbSignal); 662 663 664 /** 595 665 * Checks the SPM memory for trouble. 596 666 * -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/sharedpm.c
-
Property cvs2svn:cvs-rev
changed from
1.9
to1.10
r1570 r1571 62 62 #include <os2emx.h> 63 63 #include <stdlib.h> 64 #include <stddef.h> 64 65 #include <string.h> 65 66 #include <errno.h> … … 116 117 static void spmCleanup(void); 117 118 static void spmZombieOrFree(__LIBC_PSPMPROCESS pProcess); 119 static __LIBC_PSPMPROCESS spmQueryProcessInState(pid_t pid, __LIBC_SPMPROCSTAT enmState); 118 120 static unsigned spmTimestamp(void); 119 121 static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent); … … 192 194 PGINFOSEG pGIS = GETGINFOSEG(); 193 195 /* this will trigger after the default one, so no message. */ 194 if (pGIS->time >= 0x414a47ad && pGIS->time <= 0x41859c85)196 if (pGIS->time >= 0x414a47ad && pGIS->time <= (0x41859c85 + 2678400)) 195 197 return; 196 198 asm("lock; movl 0,%eax\n\t" … … 882 884 883 885 /** 886 * Queues a signal on another process. 887 * 888 * @returns 0 on success. 889 * @returns Negative error code (errno.h) on failure. 890 * @param pSignal Signal to queue. 891 * @param pid Pid to queue it on. 892 * @param fQueued Set if the signal type is queued. 893 */ 894 int __libc_spmSigQueue(siginfo_t *pSignal, pid_t pid, int fQueued) 895 { 896 LIBCLOG_ENTER("pSignal=%p:{.si_signo=%d,..} pid=%d fQueued=%d\n", (void *)pSignal, pSignal->si_signo, pid, fQueued); 897 898 /* 899 * Validate intput. 900 * This is mostly because we wanna crash before we take the sem. 901 */ 902 if (pSignal->si_signo <= 0 || pSignal->si_signo > SIGRTMAX) 903 { 904 LIBC_ASSERTM_FAILED("Invalid signal number %d\n", pSignal->si_signo); 905 LIBCLOG_RETURN_INT(-EINVAL); 906 } 907 if (pSignal->auReserved[(sizeof(pSignal->auReserved) / sizeof(pSignal->auReserved[0])) - 1]) 908 { 909 LIBC_ASSERTM_FAILED("Reserved field is not zero!\n"); 910 LIBCLOG_RETURN_INT(-EINVAL); 911 } 912 913 /* 914 * Request sem. 915 */ 916 __LIBC_SPMXCPTREGREC RegRec; 917 int rc = spmRequestMutex(&RegRec); 918 if (rc) 919 LIBCLOG_RETURN_INT(rc); 920 921 /* 922 * Find pid. 923 */ 924 __LIBC_PSPMPROCESS pProcess = spmQueryProcessInState(pid, __LIBC_PROCSTATE_ALIVE); 925 if (pProcess) 926 { 927 /* 928 * Check if already pending. 929 */ 930 __LIBC_PSPMSIGNAL pSig = pProcess->pSigHead; 931 if (!fQueued) 932 { 933 int iSignal = pSignal->si_signo; 934 for (pSig = pProcess->pSigHead; pSig; pSig = pSig->pNext) 935 if (pSig->Info.si_signo == iSignal) 936 break; 937 } 938 if (!pSig) 939 { 940 /* 941 * Check that we're not exceeding any per process or system limits. 942 */ 943 if (!gpSPMHdr->cSigMaxActive) 944 gpSPMHdr->cSigMaxActive = 1024; 945 if ( ( gpSPMHdr->cSigActive < gpSPMHdr->cSigMaxActive 946 && pProcess->cSigsQueued < 48) 947 || pSignal->si_signo == SIGCHLD) 948 { 949 /* 950 * Allocate a signal packet. 951 */ 952 if (gpSPMHdr->pSigFreeHead) 953 { 954 __LIBC_PSPMSIGNAL pPrev = NULL; 955 for (pSig = gpSPMHdr->pSigFreeHead; pSig; pPrev = pSig, pSig = pSig->pNext) 956 if (pSig->cb == sizeof(*pSig)) 957 { 958 if (pPrev) 959 pPrev->pNext = pSig->pNext; 960 else 961 gpSPMHdr->pSigFreeHead = pSig->pNext; 962 gpSPMHdr->cSigFree--; 963 break; 964 } 965 } 966 if (!pSig) 967 { 968 pSig = spmAlloc(sizeof(*pSig)); 969 if (pSig) 970 pSig->cb = sizeof(*pSig); 971 } 972 if (pSig) 973 { 974 /* 975 * Copy the data and insert it into the queue. 976 */ 977 pSig->pNext = pProcess->pSigHead; 978 pSig->Info = *pSignal; 979 pProcess->pSigHead = pSig; 980 pProcess->cSigsQueued++; 981 gpSPMHdr->cSigActive++; 982 rc = 0; 983 } 984 else 985 { 986 LIBCLOG_MSG("Out of memory! Cannot allocate %d bytes for a signal packet!\n", sizeof(*pSig)); 987 rc = -EAGAIN; 988 } 989 } 990 else 991 { 992 LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigsQueued=%d (max 48)\n", 993 gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigsQueued); 994 rc = -EAGAIN; 995 } 996 } 997 else 998 LIBCLOG_MSG("Signal %d is already pending on pid %d. (ts=%x,pid=%d)\n", 999 pSignal->si_signo, pid, pSig->Info.si_timestamp, pSig->Info.si_pid); 1000 } 1001 else 1002 rc = -ESRCH; 1003 1004 /* 1005 * Release sem and be gone. 1006 */ 1007 spmReleaseMutex(&RegRec); 1008 LIBCLOG_RETURN_INT(rc); 1009 } 1010 1011 /** 1012 * De-queues one or more pending signals. 1013 * @returns Number of de-queued signals on success. 1014 * @returns Negative error code (errno.h) on failure. 1015 * @param paSignals Where to store the signals. 1016 * @param cSignals Size of the signal array. 1017 * @param cbSignal Size of one signal entry. 1018 */ 1019 int __libc_spmSigDequeue(siginfo_t *paSignals, unsigned cSignals, size_t cbSignal) 1020 { 1021 LIBCLOG_ENTER("paSignals=%p cSignals=%d cbSignal=%d\n", (void *)paSignals, cSignals, cbSignal); 1022 1023 /* 1024 * Validate input. 1025 */ 1026 if (sizeof(siginfo_t) > cbSignal) 1027 { 1028 LIBC_ASSERTM_FAILED("Invalid siginfo_t size: cbSignal=%d sizeof(siginfo_t)=%d\n", cbSignal, sizeof(siginfo_t)); 1029 LIBCLOG_RETURN_INT(-EINVAL); 1030 } 1031 bzero(paSignals, cSignals * cbSignal); /* This'll trap if it's wrong :-) */ 1032 1033 /* 1034 * Request sem. 1035 */ 1036 __LIBC_SPMXCPTREGREC RegRec; 1037 int rc = spmRequestMutex(&RegRec); 1038 if (rc) 1039 LIBCLOG_RETURN_INT(rc); 1040 1041 /* 1042 * De-queue signals one-by-one. 1043 */ 1044 while (gpSPMSelf->pSigHead && cSignals-- > 0) 1045 { 1046 /* 1047 * Copy it. 1048 */ 1049 __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead; 1050 if (pSig->cb >= sizeof(siginfo_t)) 1051 *paSignals = pSig->Info; 1052 else 1053 memcpy(paSignals, &pSig->Info, pSig->cb); 1054 1055 /* 1056 * Unlink it and free it. 1057 */ 1058 gpSPMSelf->pSigHead = pSig->pNext; 1059 if (gpSPMSelf->cSigsQueued > 0) 1060 gpSPMSelf->cSigsQueued--; 1061 if (gpSPMHdr->cSigFree < 32) 1062 { 1063 pSig->pNext = gpSPMHdr->pSigFreeHead; 1064 gpSPMHdr->pSigFreeHead = pSig; 1065 gpSPMHdr->cSigFree++; 1066 } 1067 else 1068 spmFree(pSig); 1069 1070 /* next */ 1071 rc++; 1072 paSignals = (siginfo_t *)((char *)paSignals + cbSignal); 1073 } 1074 1075 spmReleaseMutex(&RegRec); 1076 LIBCLOG_RETURN_INT(rc); 1077 } 1078 1079 1080 1081 /** 884 1082 * Checks the SPM memory for trouble. 885 1083 * … … 1002 1200 } 1003 1201 1202 /** 1203 * This function checks that there is at least 2k of writable 1204 * stack available. If there isn't a crash is usually the 1205 * result. 1206 */ 1207 static int spmRequestMutexStackChecker(void) 1208 { 1209 char *pch = alloca(2048); 1210 if (!pch) 1211 return -1; 1212 /* With any luck the compiler doesn't optimize this away. */ 1213 pch[0] = pch[1024] = pch[2044] = 0x7f; 1214 return 0; 1215 } 1004 1216 1005 1217 /** … … 1026 1238 1027 1239 /* 1240 * Check stack. 1241 */ 1242 if (spmRequestMutexStackChecker()) 1243 { 1244 DosUnsetExceptionHandler(&pRegRec->Core); 1245 FS_RESTORE(); 1246 LIBC_ASSERTM_FAILED("Too little stack left!\n"); 1247 LIBCLOG_RETURN_INT(-EFAULT); 1248 } 1249 1250 /* 1028 1251 * Check if initatied. 1029 1252 */ … … 1101 1324 } 1102 1325 1103 __atomic_xchg((volatile unsigned *)(void *)&rc, 0); /* ..... */1104 1326 DosUnsetExceptionHandler(&pRegRec->Core); 1105 1327 DosExitMustComplete(&ul); … … 1124 1346 PTIB pTib; 1125 1347 FS_VAR(); 1348 1349 /* 1350 * Size and offset assertions. 1351 */ 1352 LIBC_ASSERT(sizeof(*gpSPMHdr) < SPM_PROCESS_SIZE); 1353 LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, pTcpip) == 72); 1354 LIBC_ASSERT(offsetof(__LIBC_SPMHEADER, cSigMaxActive) == 124); 1355 LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, cReferences) == 12); 1356 LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pvForkHandle) == 48); 1357 LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, cPoolPointers) == 160); 1358 LIBC_ASSERT(offsetof(__LIBC_SPMPROCESS, pInheritLocked) == 168); 1126 1359 1127 1360 /* … … 1210 1443 gpSPMHdr->cb = cb; 1211 1444 gpSPMHdr->cbProcess = SPM_PROCESS_SIZE; 1212 LIBC_ASSERT(sizeof(*gpSPMHdr) < SPM_PROCESS_SIZE);1213 1445 gpSPMHdr->pPoolTail = gpSPMHdr->pPoolHead = (__LIBC_PSPMPOOLCHUNK)((char *)gpSPMHdr + SPM_PROCESS_SIZE); 1214 1446 gpSPMHdr->pPoolFreeTail = gpSPMHdr->pPoolFreeHead = (__LIBC_PSPMPOOLCHUNKFREE)gpSPMHdr->pPoolTail; … … 1219 1451 gpSPMHdr->pTcpip->cb = sizeof(*gpSPMHdr->pTcpip); 1220 1452 gpSPMHdr->pTcpip->cSockets = sizeof(gpSPMHdr->pTcpip->acRefs) / sizeof(gpSPMHdr->pTcpip->acRefs[0]); 1453 gpSPMHdr->cSigMaxActive = 1024; 1454 /* Pre-allocate a few signals. */ 1455 gpSPMHdr->cSigFree = 8; 1456 unsigned i = gpSPMHdr->cSigFree; 1457 while (i--) 1458 { 1459 __LIBC_PSPMSIGNAL pSignal = spmAlloc(sizeof(*pSignal)); 1460 pSignal->cb = sizeof(*pSignal); 1461 pSignal->pNext = gpSPMHdr->pSigFreeHead; 1462 gpSPMHdr->pSigFreeHead = pSignal; 1463 } 1221 1464 } 1222 1465 } … … 1460 1703 LIBCLOG_RETURN_VOID(); 1461 1704 } 1705 1706 1707 /** 1708 * Searches for a process with a given pid and state. 1709 * 1710 * @returns Pointer to the desired process on success. 1711 * @returns NULL on failure. 1712 * @param pid Process id to search for. 1713 * @param enmState The state of the process. 1714 */ 1715 static __LIBC_PSPMPROCESS spmQueryProcessInState(pid_t pid, __LIBC_SPMPROCSTAT enmState) 1716 { 1717 LIBCLOG_ENTER("pid=%d enmState=%d\n", pid, enmState); 1718 __LIBC_PSPMPROCESS pProcess; 1719 1720 /* 1721 * Search process list. 1722 */ 1723 for (pProcess = gpSPMHdr->apHeads[enmState]; pProcess ; pProcess = pProcess->pNext) 1724 if (pProcess->pid == pid && pProcess->enmState == enmState) 1725 LIBCLOG_RETURN_P(pProcess); 1726 1727 LIBCLOG_RETURN_P(NULL); 1728 } 1729 1462 1730 1463 1731 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.