00001 00011 #ifndef MACHINE_SMP_H 00012 #define MACHINE_SMP_H 00013 00014 /* 00015 CmiIdleLock 00016 CmiState 00017 */ 00018 00019 /*********************************************************** 00020 * SMP Idle Locking 00021 * In an SMP system, idle processors need to sleep on a 00022 * lock so that if a message for them arrives, they can be 00023 * woken up. 00024 **********************************************************/ 00025 00026 #if CMK_SHARED_VARS_NT_THREADS 00027 00028 typedef struct { 00029 int hasMessages; /*Is there a message waiting?*/ 00030 volatile int isSleeping; /*Are we asleep in this cond?*/ 00031 HANDLE sem; 00032 } CmiIdleLock; 00033 00034 #elif CMK_SHARED_VARS_POSIX_THREADS_SMP 00035 00036 typedef struct { 00037 volatile int hasMessages; /*Is there a message waiting?*/ 00038 volatile int isSleeping; /*Are we asleep in this cond?*/ 00039 pthread_mutex_t mutex; 00040 pthread_cond_t cond; 00041 } CmiIdleLock; 00042 00043 #else /* non SMP */ 00044 00045 typedef struct { 00046 int hasMessages; 00047 } CmiIdleLock; 00048 00049 #endif 00050 00051 00052 /*#define CMK_SMP_MULTIQ 1*/ 00053 #if CMK_SMP_MULTIQ 00054 /* 00055 * The value is usually equal to the number of cores on 00056 * this node for the best possible performance. In such 00057 * cases, the CMK_PCQUEUE_PUSHLOCk should be disabled. 00058 * 00059 * For large fat smp node (say, over 16 cores per node), 00060 * then this value could be half or quarter of the #cores. 00061 * Then the CMK_PCQUEUE_PUSHLOCK should be enabled. 00062 * 00063 * */ 00064 #ifndef MULTIQ_GRPSIZE 00065 #define MULTIQ_GRPSIZE 8 00066 #endif 00067 #endif 00068 00069 /************************************************************ 00070 * 00071 * Processor state structure 00072 * 00073 ************************************************************/ 00074 00075 typedef struct CmiStateStruct 00076 { 00077 int pe, rank; 00078 #if !CMK_SMP_MULTIQ 00079 CMIQueue recv; 00080 #else 00081 CMIQueue recv[MULTIQ_GRPSIZE]; 00082 int myGrpIdx; 00083 int curPolledIdx; 00084 #endif 00085 00086 void *localqueue; 00087 CmiIdleLock idle; 00088 } 00089 *CmiState; 00090 00091 typedef struct CmiNodeStateStruct 00092 { 00093 CmiNodeLock immSendLock; /* lock for pushing into immediate queues */ 00094 CmiNodeLock immRecvLock; /* lock for processing immediate messages */ 00095 CMIQueue immQ; /* immediate messages to handle ASAP: 00096 Locks: push(SendLock), pop(RecvLock) */ 00097 CMIQueue delayedImmQ; /* delayed immediate messages: 00098 Locks: push(RecvLock), pop(RecvLock) */ 00099 #if CMK_NODE_QUEUE_AVAILABLE 00100 CmiNodeLock CmiNodeRecvLock; 00101 #if CMK_LOCKLESS_QUEUE 00102 MPMCQueue NodeRecv; 00103 #else 00104 CMIQueue NodeRecv; 00105 #endif 00106 #endif 00107 } 00108 CmiNodeState; 00109 00110 #endif 00111