/* multimac.h -- runtime macros related to multiprocessing */
/* if MPDX is defined, disable MULTI_MPD (etc.) for building mpdx. */
#ifdef MPDX
#undef MULTI_MPD
#undef SHARED_FILE_OBJS
#undef UNSHARED_FILE_OBJS
#endif
/* access to per-jobserver private variables */
#define PRIV(var) mpd_private[MY_JS_ID].var
#define CUR_PROC PRIV(cur_proc)
#define CUR_RES PRIV(cur_res)
#define CUR_STACK (PRIV(cur_proc)->stack)
/*
* Mutual exclusion primitives (MultiMPD only).
*
* LOCK_QUEUE and UNLOCK_QUEUE access the queue_mutex.
* LOCK and UNLOCK are used for most other mutexes.
* There are also special macros for file locking inside io.c.
*/
#ifdef MULTI_MPD /* locks are needed under MultiMPD */
/* INIT_LOCK allocates the lock and clears it */
#define INIT_LOCK(var, label) { \
multi_alloc_lock ((var).lock); \
(var).name = label; \
multi_reset_lock ((var).lock); \
}
/* RESET_LOCK clears a lock */
#define RESET_LOCK(var) { \
DEBUG (D_MUTEX, "%-14s reset %s (&%06lX)", "", (var).name, &(var.lock)); \
multi_reset_lock ((var).lock); \
}
#define FREE_LOCK(var,label) { \
DEBUG (D_MUTEX, "free %s (%06lX)", label, &(var.lock), 0); \
multi_free_lock ((var).lock); \
}
#define LOCK(var,who) { \
DEBUG (D_MUTEX, "%-14s need %s (&%06lX)", who, (var).name, &(var.lock)); \
multi_lock ((var).lock); \
DEBUG (D_MUTEX, "%-14s got %s (&%06lX)", who, (var).name, &(var.lock)); \
}
#define UNLOCK(var,who) { \
DEBUG (D_MUTEX, "%-14s give %s (&%06lX)", who, (var).name, &(var)); \
multi_unlock ((var).lock); \
}
/* LOCK_QUEUE only grabs the queue lock if we don't already have it */
#define LOCK_QUEUE(who) { \
if (PRIV (js_queue_depth) == 0) { \
DEBUG (D_QMUTEX, "%-14s need queue_mutex", who, 0, 0); \
multi_lock (mpd_queue_mutex.lock); \
DEBUG (D_QMUTEX, "%-14s got queue_mutex", who, 0, 0); \
} \
PRIV (js_queue_depth)++; \
}
/* UNLOCK_QUEUE only really unlocks it when the depth hits zero */
#define UNLOCK_QUEUE(who) { \
if (PRIV (js_queue_depth) == 1) { \
DEBUG (D_QMUTEX, "%-14s give queue_mutex", who, 0, 0); \
multi_unlock (mpd_queue_mutex.lock); \
} \
PRIV (js_queue_depth)--; \
}
#else /* locks are unneeded if not MULTI_MPD */
#define LOCK(var,who)
#define UNLOCK(var,who)
#define INIT_LOCK(var,label)
#define RESET_LOCK(var)
#define FREE_LOCK(var,label)
#define LOCK_QUEUE(who)
#define UNLOCK_QUEUE(who)
#endif /* MULTI_MPD */
/*
* SHARED_FILE_OBJS and UNSHARED_FILE_OBJS tell the
* type of configuration that is built. The RTS uses these in a few
* places. I_AM_IOSERVER is used in a boolean expression to tell a
* job server whether or not it is the job server. It should go to
* 0 if heavyweight threads are not used. I_CHECK_TERMINATION tells
* the idle procs which jobserver in MultiMPD checks for termination.
* MY_QUEUE_ADDR and lets a job server know what ready queue to
* pull jobs off of.
*
* BEGIN_IO(fp) reserves the lock for file fp, setting PRIV(io_handoff).
* END_IO(fp) releases it, if PRIV(io_handoff) is set.
* (The file locking becomes a no-op in uni-MPD.)
*
* ABORT_IO(fp,locn,msg) is END_IO followed by mpd_loc_abort(locn,msg).
* IO_RETURN(fp,v) is END_IO followed by return v [where v is int].
*/
#ifdef MULTI_MPD
/* always need file locks whether shared or unshared */
#define SHARED_FD(fd) ((fd>=FIRST_SHARED_FD) && (fd<=LAST_SHARED_FD))
#ifdef SHARED_FILE_OBJS
#define NUM_IO_SERVERS 0
#define I_AM_IOSERVER 0 /* nobody is */
#define I_AM_NON_IOSERVER 0 /* nobody is */
#define BEGIN_IO(fp) mpd_begin_io ((FILE *) fp)
#define END_IO(fp) mpd_end_io ((FILE *) fp)
#define I_CHECK_TERMINATION (PRIV(my_jobserver_id) == 0)
#define MY_QUEUE_ADDR (& mpd_ready_list)
#else /* not SHARED_FILE_OBJS */
#define NUM_IO_SERVERS 1
#define IO_SERVER_JOB 0 /* which JS is the IO server */
#define I_AM_IOSERVER (PRIV(my_jobserver_id) == IO_SERVER_JOB)
#define I_AM_NON_IOSERVER (PRIV(my_jobserver_id) != IO_SERVER_JOB)
#define BEGIN_IO(fp) \
((PRIV(io_handoff)=I_AM_NON_IOSERVER)?mpd_begin_io((FILE*)fp):0)
#define END_IO(fp) (PRIV(io_handoff)?mpd_end_io((FILE*)fp):0)
#define I_CHECK_TERMINATION I_AM_IOSERVER
#define MY_QUEUE_ADDR (mpd_scheduler_queue_addr[PRIV(my_jobserver_id)])
#endif /* not SHARED_FILE_OBJS */
#else /* not MULTI_MPD */
#define SHARED_FD(fd) 0 /* always false */
#define NUM_IO_SERVERS 0
#define I_AM_IOSERVER 0 /* nobody is */
#define I_AM_NON_IOSERVER 0 /* nobody is */
#define I_CHECK_TERMINATION 1 /* everyone does (the only idle proc) */
#define MPD_NUM_IDLE_PROCS 0
#define MY_QUEUE_ADDR (&mpd_ready_list)
#define BEGIN_IO(fp) 0
#define END_IO(fp) 0
#endif /* MULTI_MPD */
#define ABORT_IO(fp,locn,msg) (END_IO(fp),mpd_loc_abort(locn,msg))
#define IO_RETURN(fp,v) return(END_IO(fp),(v))
syntax highlighted by Code2HTML, v. 0.9.1