<commit_before>/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team, 1998-2004
 *
 * Performing updates.
 *
 * ---------------------------------------------------------------------------*/

#ifndef UPDATES_H
#define UPDATES_H

/* -----------------------------------------------------------------------------
   Updates

   We have two layers of update macros.  The top layer, UPD_IND() and
   friends perform all the work of an update.  In detail:

      - if the closure being updated is a blocking queue, then all the
        threads waiting on the blocking queue are updated.

      - then the lower level updateWithIndirection() macro is invoked 
        to actually replace the closure with an indirection (see below).

   -------------------------------------------------------------------------- */

#ifdef TICKY_TICKY
# define UPD_IND(updclosure, heapptr) \
   UPD_PERM_IND(updclosure,heapptr)
# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
   UPD_PERM_IND(updclosure,heapptr); and_then
#else
#  define SEMI ;
# define UPD_IND(updclosure, heapptr) \
   UPD_REAL_IND(updclosure,INFO_PTR(stg_IND_info),heapptr,SEMI)
# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
   UPD_REAL_IND(updclosure,ind_info,heapptr,and_then)
#endif

/* These macros have to work in both C and C--, so here's the
 * impedence matching:
 */
#ifdef CMINUSMINUS
#define DECLARE_IPTR(info)  W_ info
#define FCALL               foreign "C"
#define INFO_PTR(info)      info
#define ARG_PTR             "ptr"
#else
#define DECLARE_IPTR(info)  const StgInfoTable *(info)
#define FCALL               /* nothing */
#define INFO_PTR(info)      &info
#define StgBlockingQueue_blocking_queue(closure) \
    (((StgBlockingQueue *)closure)->blocking_queue)
#define ARG_PTR             /* nothing */
#endif

/* UPD_IND actually does a PERM_IND if TICKY_TICKY is on;
   if you *really* need an IND use UPD_REAL_IND
 */
#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then)		\
	DECLARE_IPTR(info);						\
	info = GET_INFO(updclosure);					\
        AWAKEN_BQ(info,updclosure);					\
	updateWithIndirection(GET_INFO(updclosure), ind_info,		\
			      updclosure,				\
			      heapptr,					\
			      and_then);

#if defined(PROFILING) || defined(TICKY_TICKY)
#define UPD_PERM_IND(updclosure, heapptr)	\
	DECLARE_IPTR(info);			\
	info = GET_INFO(updclosure);		\
        AWAKEN_BQ(info,updclosure);		\
	updateWithPermIndirection(info,		\
				  updclosure,	\
				  heapptr);
#endif

#if defined(RTS_SUPPORTS_THREADS)

# ifdef TICKY_TICKY
#  define UPD_IND_NOLOCK(updclosure, heapptr)	\
	DECLARE_IPTR(info);			\
	info = GET_INFO(updclosure);		\
        AWAKEN_BQ_NOLOCK(info,updclosure);	\
	updateWithPermIndirection(info,		\
				  updclosure,	\
				  heapptr)
# else
#  define UPD_IND_NOLOCK(updclosure, heapptr)			\
	DECLARE_IPTR(info);					\
	info = GET_INFO(updclosure);				\
        AWAKEN_BQ_NOLOCK(info,updclosure);			\
	updateWithIndirection(info, INFO_PTR(stg_IND_info),	\
			      updclosure,			\
			      heapptr,); 
# endif

#else
#define UPD_IND_NOLOCK(updclosure,heapptr) UPD_IND(updclosure,heapptr)
#endif

/* -----------------------------------------------------------------------------
   Awaken any threads waiting on a blocking queue (BLACKHOLE_BQ).
   -------------------------------------------------------------------------- */

#if defined(PAR) 

/* 
   In a parallel setup several types of closures might have a blocking queue:<commit_msg>[project @ 2004-09-02 12:34:05 by simonmar] Make the UPD_IND macros compatible with older gccs that don't accept declarations in the middle of a block.<commit_after>/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team, 1998-2004
 *
 * Performing updates.
 *
 * ---------------------------------------------------------------------------*/

#ifndef UPDATES_H
#define UPDATES_H

/* -----------------------------------------------------------------------------
   Updates

   We have two layers of update macros.  The top layer, UPD_IND() and
   friends perform all the work of an update.  In detail:

      - if the closure being updated is a blocking queue, then all the
        threads waiting on the blocking queue are updated.

      - then the lower level updateWithIndirection() macro is invoked 
        to actually replace the closure with an indirection (see below).

   -------------------------------------------------------------------------- */

#ifdef TICKY_TICKY
# define UPD_IND(updclosure, heapptr) \
   UPD_PERM_IND(updclosure,heapptr)
# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
   UPD_PERM_IND(updclosure,heapptr); and_then
#else
#  define SEMI ;
# define UPD_IND(updclosure, heapptr) \
   UPD_REAL_IND(updclosure,INFO_PTR(stg_IND_info),heapptr,SEMI)
# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
   UPD_REAL_IND(updclosure,ind_info,heapptr,and_then)
#endif

/* These macros have to work in both C and C--, so here's the
 * impedence matching:
 */
#ifdef CMINUSMINUS
#define BLOCK_BEGIN
#define BLOCK_END
#define DECLARE_IPTR(info)  W_ info
#define FCALL               foreign "C"
#define INFO_PTR(info)      info
#define ARG_PTR             "ptr"
#else
#define BLOCK_BEGIN         {
#define BLOCK_END           }
#define DECLARE_IPTR(info)  const StgInfoTable *(info)
#define FCALL               /* nothing */
#define INFO_PTR(info)      &info
#define StgBlockingQueue_blocking_queue(closure) \
    (((StgBlockingQueue *)closure)->blocking_queue)
#define ARG_PTR             /* nothing */
#endif

/* UPD_IND actually does a PERM_IND if TICKY_TICKY is on;
   if you *really* need an IND use UPD_REAL_IND
 */
#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then)	\
        BLOCK_BEGIN						\
	DECLARE_IPTR(info);					\
	info = GET_INFO(updclosure);				\
        AWAKEN_BQ(info,updclosure);				\
	updateWithIndirection(GET_INFO(updclosure), ind_info,	\
			      updclosure,			\
			      heapptr,				\
			      and_then);			\
	BLOCK_END

#if defined(PROFILING) || defined(TICKY_TICKY)
#define UPD_PERM_IND(updclosure, heapptr)	\
        BLOCK_BEGIN				\
	DECLARE_IPTR(info);			\
	info = GET_INFO(updclosure);		\
        AWAKEN_BQ(info,updclosure);		\
	updateWithPermIndirection(info,		\
				  updclosure,	\
				  heapptr);	\
	BLOCK_END
#endif

#if defined(RTS_SUPPORTS_THREADS)

# ifdef TICKY_TICKY
#  define UPD_IND_NOLOCK(updclosure, heapptr)	\
        BLOCK_BEGIN				\
	DECLARE_IPTR(info);			\
	info = GET_INFO(updclosure);		\
        AWAKEN_BQ_NOLOCK(info,updclosure);	\
	updateWithPermIndirection(info,		\
				  updclosure,	\
				  heapptr);	\
	BLOCK_END
# else
#  define UPD_IND_NOLOCK(updclosure, heapptr)			\
        BLOCK_BEGIN						\
	DECLARE_IPTR(info);					\
	info = GET_INFO(updclosure);				\
        AWAKEN_BQ_NOLOCK(info,updclosure);			\
	updateWithIndirection(info, INFO_PTR(stg_IND_info),	\
			      updclosure,			\
			      heapptr,); 			\
	BLOCK_END
# endif

#else
#define UPD_IND_NOLOCK(updclosure,heapptr) UPD_IND(updclosure,heapptr)
#endif

/* -----------------------------------------------------------------------------
   Awaken any threads waiting on a blocking queue (BLACKHOLE_BQ).
   -------------------------------------------------------------------------- */

#if defined(PAR) 

/* 
   In a parallel setup several types of closures might have a blocking queue:
{'fraction_non_alphanumeric': 0.20695230396119643, 'fraction_numerical': 0.004042037186742118, 'mean_word_length': 2.034750613246116, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5179509', 'n_tokens_mistral': 2658, 'n_tokens_neox': 2461, 'n_words': 541}