tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tm.h
Go to the documentation of this file.
1 /* =============================================================================
2  *
3  * tm.h
4  *
5  * Utility defines for transactional memory
6  *
7  * =============================================================================
8  *
9  * Copyright (C) Stanford University, 2006. All Rights Reserved.
10  * Authors: Chi Cao Minh and Martin Trautmann
11  *
12  * =============================================================================
13  *
14  * For the license of bayes/sort.h and bayes/sort.c, please see the header
15  * of the files.
16  *
17  * ------------------------------------------------------------------------
18  *
19  * For the license of kmeans, please see kmeans/LICENSE.kmeans
20  *
21  * ------------------------------------------------------------------------
22  *
23  * For the license of ssca2, please see ssca2/COPYRIGHT
24  *
25  * ------------------------------------------------------------------------
26  *
27  * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the
28  * header of the files.
29  *
30  * ------------------------------------------------------------------------
31  *
32  * For the license of lib/rbtree.h and lib/rbtree.c, please see
33  * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree
34  *
35  * ------------------------------------------------------------------------
36  *
37  * Unless otherwise noted, the following license applies to STAMP files:
38  *
39  * Copyright (c) 2007, Stanford University
40  * All rights reserved.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions are
44  * met:
45  *
46  * * Redistributions of source code must retain the above copyright
47  * notice, this list of conditions and the following disclaimer.
48  *
49  * * Redistributions in binary form must reproduce the above copyright
50  * notice, this list of conditions and the following disclaimer in
51  * the documentation and/or other materials provided with the
52  * distribution.
53  *
54  * * Neither the name of Stanford University nor the names of its
55  * contributors may be used to endorse or promote products derived
56  * from this software without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
59  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
68  * THE POSSIBILITY OF SUCH DAMAGE.
69  *
70  * =============================================================================
71  */
72 
73 
74 #ifndef TM_H
75 #define TM_H 1
76 
77 #ifdef HAVE_CONFIG_H
78 # include "STAMP_config.h"
79 #endif
80 
81 /* =============================================================================
82  * Simulator Specific Interface
83  *
84  * MAIN(argc, argv)
85  * Declare the main function with argc being the identifier for the argument
86  * count and argv being the name for the argument string list
87  *
88  * MAIN_RETURN(int_val)
89  * Returns from MAIN function
90  *
91  * GOTO_SIM()
92  * Switch simulator to simulation mode
93  *
94  * GOTO_REAL()
95  * Switch simulator to non-simulation (real) mode
96  * Note: use in sequential region only
97  *
98  * IS_IN_SIM()
99  * Returns true if simulator is in simulation mode
100  *
101  * SIM_GET_NUM_CPU(var)
102  * Assigns the number of simulated CPUs to "var"
103  *
104  * P_MEMORY_STARTUP
105  * Start up the memory allocator system that handles malloc/free
106  * in parallel regions (but not in transactions)
107  *
108  * P_MEMORY_SHUTDOWN
109  * Shutdown the memory allocator system that handles malloc/free
110  * in parallel regions (but not in transactions)
111  *
112  * =============================================================================
113  */
114 #ifdef SIMULATOR
115 
116 # include <simapi.h>
117 
118 # define MAIN(argc, argv) void mainX (int argc, \
119  const char** argv, \
120  const char** envp)
121 # define MAIN_RETURN(val) return /* value is ignored */
122 
123 # define GOTO_SIM() goto_sim()
124 # define GOTO_REAL() goto_real()
125 # define IS_IN_SIM() (inSimulation)
126 
127 # define SIM_GET_NUM_CPU(var) ({ \
128  if (!IS_IN_SIM()) { \
129  GOTO_SIM(); \
130  var = Sim_GetNumCpus(); \
131  GOTO_REAL(); \
132  } else { \
133  var = Sim_GetNumCpus(); \
134  } \
135  var; \
136  })
137 
138 # define TM_PRINTF Sim_Print
139 # define TM_PRINT0 Sim_Print0
140 # define TM_PRINT1 Sim_Print1
141 # define TM_PRINT2 Sim_Print2
142 # define TM_PRINT3 Sim_Print3
143 
144 # include "memory.h"
145 # define P_MEMORY_STARTUP(numThread) do { \
146  bool_t status; \
147  status = memory_init((numThread), \
148  ((1<<28) / numThread), \
149  2); \
150  assert(status); \
151  } while (0) /* enforce comma */
152 # define P_MEMORY_SHUTDOWN() memory_destroy()
153 
154 #else /* !SIMULATOR */
155 
156 # include <stdio.h>
157 
158 # define MAIN(argc, argv) int main (int argc, char** argv)
159 # define MAIN_RETURN(val) return val
160 
161 # define GOTO_SIM() /* nothing */
162 # define GOTO_REAL() /* nothing */
163 # define IS_IN_SIM() (0)
164 
165 # define SIM_GET_NUM_CPU(var) /* nothing */
166 
167 # define TM_PRINTF printf
168 # define TM_PRINT0 printf
169 # define TM_PRINT1 printf
170 # define TM_PRINT2 printf
171 # define TM_PRINT3 printf
172 
173 # define P_MEMORY_STARTUP(numThread) /* nothing */
174 # define P_MEMORY_SHUTDOWN() /* nothing */
175 
176 #endif /* !SIMULATOR */
177 
178 
179 /* =============================================================================
180  * Transactional Memory System Interface
181  *
182  * TM_ARG
183  * TM_ARG_ALONE
184  * TM_ARGDECL
185  * TM_ARGDECL_ALONE
186  * Used to pass TM thread meta data to functions (see Examples below)
187  *
188  * TM_STARTUP(numThread)
189  * Startup the TM system (call before any other TM calls)
190  *
191  * TM_SHUTDOWN()
192  * Shutdown the TM system
193  *
194  * TM_THREAD_ENTER()
195  * Call when thread first enters parallel region
196  *
197  * TM_THREAD_EXIT()
198  * Call when thread exits last parallel region
199  *
200  * P_MALLOC(size)
201  * Allocate memory inside parallel region
202  *
203  * P_FREE(ptr)
204  * Deallocate memory inside parallel region
205  *
206  * TM_MALLOC(size)
207  * Allocate memory inside atomic block / transaction
208  *
209  * TM_FREE(ptr)
210  * Deallocate memory inside atomic block / transaction
211  *
212  * TM_BEGIN()
213  * Begin atomic block / transaction
214  *
215  * TM_BEGIN_RO()
216  * Begin atomic block / transaction that only reads shared data
217  *
218  * TM_END()
219  * End atomic block / transaction
220  *
221  * TM_RESTART()
222  * Restart atomic block / transaction
223  *
224  * TM_EARLY_RELEASE()
225  * Remove speculatively read line from the read set
226  *
227  * =============================================================================
228  *
229  * Example Usage:
230  *
231  * MAIN(argc,argv)
232  * {
233  * TM_STARTUP(8);
234  * // create 8 threads and go parallel
235  * TM_SHUTDOWN();
236  * }
237  *
238  * void parallel_region ()
239  * {
240  * TM_THREAD_ENTER();
241  * subfunction1(TM_ARG_ALONE);
242  * subfunction2(TM_ARG 1, 2, 3);
243  * TM_THREAD_EXIT();
244  * }
245  *
246  * void subfunction1 (TM_ARGDECL_ALONE)
247  * {
248  * TM_BEGIN_RO()
249  * // ... do work that only reads shared data ...
250  * TM_END()
251  *
252  * long* array = (long*)P_MALLOC(10 * sizeof(long));
253  * // ... do work ...
254  * P_FREE(array);
255  * }
256  *
257  * void subfunction2 (TM_ARGDECL long a, long b, long c)
258  * {
259  * TM_BEGIN();
260  * long* array = (long*)TM_MALLOC(a * b * c * sizeof(long));
261  * // ... do work that may read or write shared data ...
262  * TM_FREE(array);
263  * TM_END();
264  * }
265  *
266  * =============================================================================
267  */
268 
269 
270 /* =============================================================================
271  * HTM - Hardware Transactional Memory
272  * =============================================================================
273  */
274 
275 #ifdef HTM
276 
277 # ifndef SIMULATOR
278 # error HTM requries SIMULATOR
279 # endif
280 
281 # include <assert.h>
282 # include <tmapi.h>
283 # include "memory.h"
284 # include "thread.h"
285 # include "types.h"
286 
287 # define TM_ARG /* nothing */
288 # define TM_ARG_ALONE /* nothing */
289 # define TM_ARGDECL /* nothing */
290 # define TM_ARGDECL_ALONE /* nothing */
291 # define TM_CALLABLE /* nothing */
292 
293 # define TM_STARTUP(numThread) /* nothing */
294 # define TM_SHUTDOWN() /* nothing */
295 
296 # define TM_THREAD_ENTER() /* nothing */
297 # define TM_THREAD_EXIT() /* nothing */
298 # define TM_BEGIN_WAIVER()
299 # define TM_END_WAIVER()
300 
301 # define P_MALLOC(size) memory_get(thread_getId(), size)
302 # define P_FREE(ptr) /* TODO: thread local free is non-trivial */
303 # define TM_MALLOC(size) memory_get(thread_getId(), size)
304 # define TM_FREE(ptr) /* TODO: thread local free is non-trivial */
305 
306 # ifdef OTM
307 
308 # define thread_getId() omp_get_thread_num()
309 # define thread_getNumThread() omp_get_num_threads()
310 # define thread_startup(numThread) omp_set_num_threads(numThread)
311 # define thread_shutdown() /* nothing */
312 # define thread_barrier_wait(); _Pragma ("omp barrier")
313 # define TM_BEGIN() _Pragma ("omp transaction") {
314 # define TM_BEGIN_RO() _Pragma ("omp transaction") {
315 # define TM_END() }
316 # define TM_RESTART() _TM_Abort()
317 
318 # define TM_EARLY_RELEASE(var) TM_Release(&(var))
319 
320 # else /* !OTM */
321 
322 # define TM_BEGIN() TM_BeginClosed()
323 # define TM_BEGIN_RO() TM_BeginClosed()
324 # define TM_END() TM_EndClosed()
325 # define TM_RESTART() _TM_Abort()
326 # define TM_EARLY_RELEASE(var) TM_Release(&(var))
327 
328 # endif /* !OTM */
329 
330 
331  /* =============================================================================
332  * STM - Software Transactional Memory
333  * =============================================================================
334  */
335 
336 #elif defined(STM)
337 
338 # include <string.h>
339 # include <api/api.hpp>
340 # include "thread.h"
341 
342 # if defined (OTM)
343 
344 # define TM_ARG /* nothing */
345 # define TM_ARG_ALONE /* nothing */
346 # define TM_ARGDECL /* nothing */
347 # define TM_ARGDECL_ALONE /* nothing */
348 # define TM_CALLABLE _Pragma ("omp tm_function")
349 
350 # define thread_getId() omp_get_thread_num()
351 # define thread_getNumThread() omp_get_num_threads()
352 # define thread_startup(numThread) omp_set_num_threads(numThread)
353 # define thread_shutdown() /* nothing */
354 
355 # else /* !OTM */
356 #undef TM_ARG
357 #undef TM_ARG_ALONE
358 # define TM_ARG STM_SELF,
359 # define TM_ARG_ALONE STM_SELF
360 # define TM_ARGDECL STM_THREAD_T* TM_ARG
361 # define TM_ARGDECL_ALONE STM_THREAD_T* TM_ARG_ALONE
362 # define TM_CALLABLE /* nothing */
363 
364 #endif /* !OTM */
365 
366 # ifdef SIMULATOR
367 
368 # ifdef OTM
369 
370 # define TM_STARTUP(numThread) STM_STARTUP(); \
371  STM_NEW_THREADS(numThread)
372 # define TM_SHUTDOWN() STM_SHUTDOWN()
373 
374 # define TM_THREAD_ENTER() omp_set_self()
375 # define TM_THREAD_EXIT() /* Nothing */
376 # define TM_BEGIN_WAIVER()
377 # define TM_END_WAIVER()
378 # define thread_barrier_wait(); _Pragma ("omp barrier")
379 
380 # define P_MALLOC(size) memory_get(thread_getId(), size)
381 # define P_FREE(ptr) /* TODO: thread local free is non-trivial */
382 # define TM_MALLOC(size) memory_get(thread_getId(), size)
383 # define TM_FREE(ptr) /* TODO: thread local free is non-trivial */
384 
385 # else /* !OTM */
386 
387 # define TM_STARTUP(numThread) STM_STARTUP(); \
388  STM_NEW_THREADS(numThread)
389 # define TM_SHUTDOWN() STM_SHUTDOWN()
390 
391 # define TM_THREAD_ENTER() TM_ARGDECL_ALONE = \
392  STM_GET_THREAD(thread_getId()); \
393  STM_SET_SELF(TM_ARG_ALONE)
394 
395 # define TM_THREAD_EXIT() STM_FREE_THREAD(TM_ARG_ALONE)
396 # define TM_BEGIN_WAIVER()
397 # define TM_END_WAIVER()
398 
399 # define P_MALLOC(size) memory_get(thread_getId(), size)
400 # define P_FREE(ptr) /* TODO: thread local free is non-trivial */
401 # define TM_MALLOC(size) memory_get(thread_getId(), size)
402 # define TM_FREE(ptr) /* TODO: thread local free is non-trivial */
403 
404 # endif /* !OTM */
405 
406 # else /* !SIMULATOR */
407 
408 # ifdef OTM
409 
410 # include <omp.h>
411 # include "tl2.h"
412 
413 # define TM_STARTUP(numThread) STM_STARTUP()
414 # define TM_SHUTDOWN() STM_SHUTDOWN()
415 
416 # define TM_THREAD_ENTER() /* nothing */
417 # define TM_THREAD_EXIT() /* nothing */
418 # define TM_BEGIN_WAIVER()
419 # define TM_END_WAIVER()
420 # define thread_barrier_wait(); _Pragma ("omp barrier")
421 
422 # define P_MALLOC(size) malloc(size)
423 # define P_FREE(ptr) free(ptr)
424 # define TM_MALLOC(size) malloc(size)
425 # define TM_FREE(ptr) /* TODO: fix memory free problem with OpenTM */
426 
427 # else /* !OTM */
428 
429 # define TM_STARTUP(numThread) STM_STARTUP(numThread)
430 # define TM_SHUTDOWN() STM_SHUTDOWN()
431 
432 # define TM_THREAD_ENTER() TM_ARGDECL_ALONE = STM_NEW_THREAD(); \
433  STM_INIT_THREAD(TM_ARG_ALONE, thread_getId())
434 # define TM_THREAD_EXIT() STM_FREE_THREAD(TM_ARG_ALONE)
435 # define TM_BEGIN_WAIVER()
436 # define TM_END_WAIVER()
437 
438 # define P_MALLOC(size) malloc(size)
439 # define P_FREE(ptr) free(ptr)
440 # define SEQ_MALLOC(size) malloc(size)
441 # define SEQ_FREE(ptr) free(ptr)
442 
443 # define TM_MALLOC(size) TM_ALLOC(size)
444 //# define TM_FREE(ptr) STM_FREE(ptr)
445 # endif /* !OTM */
446 
447 # endif /* !SIMULATOR */
448 
449 # ifdef OTM
450 
451 # define TM_BEGIN() _Pragma ("omp transaction") {
452 # define TM_BEGIN_RO() _Pragma ("omp transaction") {
453 # define TM_END() }
454 # define TM_RESTART() omp_abort()
455 
456 # define TM_EARLY_RELEASE(var) /* nothing */
457 
458 # else /* !OTM */
459 # undef TM_BEGIN
460 # undef TM_END
461 # define TM_BEGIN() STM_BEGIN_WR()
462 # define TM_BEGIN_RO() STM_BEGIN_RD()
463 # define TM_END() STM_END()
464 # define TM_RESTART() STM_RESTART()
465 
466 # define TM_EARLY_RELEASE(var) /* nothing */
467 
468 # endif /* !OTM */
469 
470 
471 /* =============================================================================
472  * C++ STM API (it's an STM, but it has a HTM-ish interface
473  * =============================================================================
474  */
475 #elif defined(CXXTM)
476 
477 # define TM_ARG /* nothing */
478 # define TM_ARG_ALONE /* nothing */
479 # define TM_ARGDECL /* nothing */
480 # define TM_ARGDECL_ALONE /* nothing */
481 # define TM_CALLABLE [[transaction_callable]]
482 
483 # ifdef ITM
484 # include <itm.h>
485 # define TM_STARTUP(numThread) _ITM_initializeProcess()
486 # define TM_SHUTDOWN() _ITM_finalizeProcess()
487 # define TM_THREAD_ENTER() _ITM_initializeThread()
488 # define TM_THREAD_EXIT() _ITM_finalizeThread()
489 
490 # ifdef STAMP_USE_WAIVER
491 # define TM_BEGIN_WAIVER() __transaction [[waiver]] {
492 # define TM_END_WAIVER() }
493 # else
494 # define TM_BEGIN_WAIVER()
495 # define TM_END_WAIVER()
496 # endif
497 
498 # else
499 # define TM_STARTUP(numThread) /* nothing */
500 # define TM_SHUTDOWN() /* nothing */
501 # define TM_THREAD_ENTER() /* nothing */
502 # define TM_THREAD_EXIT() /* nothing */
503 # define TM_BEGIN_WAIVER()
504 # define TM_END_WAIVER()
505 # endif
506 
507 # define P_MALLOC(size) malloc(size)
508 # define P_FREE(ptr) free(ptr)
509 # define TM_MALLOC(size) malloc(size)
510 # define TM_FREE(ptr) free(ptr)
511 # define SEQ_MALLOC(size) malloc(size)
512 # define SEQ_FREE(ptr) free(ptr)
513 
514 # define TM_BEGIN() __transaction [[relaxed]] {
515 # define TM_BEGIN_RO() __transaction [[relaxed]] {
516 # define TM_END() }
517 # define TM_RESTART() assert(0)
518 
519 # define TM_EARLY_RELEASE(var) /* nothing */
520 
521 /* =============================================================================
522  * Sequential execution
523  * =============================================================================
524  */
525 
526 #else /* SEQUENTIAL */
527 
528 # include <assert.h>
529 
530 # define TM_ARG /* nothing */
531 # define TM_ARG_ALONE /* nothing */
532 # define TM_ARGDECL /* nothing */
533 # define TM_ARGDECL_ALONE /* nothing */
534 # define TM_CALLABLE /* nothing */
535 
536 # define TM_STARTUP(numThread) /* nothing */
537 # define TM_SHUTDOWN() /* nothing */
538 
539 # define TM_THREAD_ENTER() /* nothing */
540 # define TM_THREAD_EXIT() /* nothing */
541 
542 # ifdef SIMULATOR
543 
544 # include "thread.h"
545 
546 # define P_MALLOC(size) memory_get(thread_getId(), size)
547 # define P_FREE(ptr) /* TODO: thread local free is non-trivial */
548 # define TM_MALLOC(size) memory_get(thread_getId(), size)
549 # define TM_FREE(ptr) /* TODO: thread local free is non-trivial */
550 
551 # else /* !SIMULATOR */
552 
553 # define P_MALLOC(size) malloc(size)
554 # define P_FREE(ptr) free(ptr)
555 # define TM_MALLOC(size) malloc(size)
556 # define TM_FREE(ptr) free(ptr)
557 
558 # endif /* !SIMULATOR */
559 
560 # define TM_BEGIN() /* nothing */
561 # define TM_BEGIN_RO() /* nothing */
562 # define TM_END() /* nothing */
563 # define TM_RESTART() assert(0)
564 
565 # define TM_EARLY_RELEASE(var) /* nothing */
566 
567 #endif /* SEQUENTIAL */
568 
569 
570 /* =============================================================================
571  * Transactional Memory System interface for shared memory accesses
572  *
573  * There are 3 flavors of each function:
574  *
575  * 1) no suffix: for accessing variables of size "long"
576  * 2) _P suffix: for accessing variables of type "pointer"
577  * 3) _F suffix: for accessing variables of type "float"
578  * =============================================================================
579  */
580 #if defined(STM)
581 
582 #if defined(OTM)
583 
584 # define TM_SHARED_READ_I(var) (var)
585 # define TM_SHARED_READ_L(var) (var)
586 # define TM_SHARED_READ_P(var) (var)
587 # define TM_SHARED_READ_F(var) (var)
588 
589 # define TM_SHARED_WRITE_I(var, val) ({var = val; var;})
590 # define TM_SHARED_WRITE_L(var, val) ({var = val; var;})
591 # define TM_SHARED_WRITE_P(var, val) ({var = val; var;})
592 # define TM_SHARED_WRITE_F(var, val) ({var = val; var;})
593 
594 # define TM_LOCAL_WRITE_I(var, val) ({var = val; var;})
595 # define TM_LOCAL_WRITE_L(var, val) ({var = val; var;})
596 # define TM_LOCAL_WRITE_P(var, val) ({var = val; var;})
597 # define TM_LOCAL_WRITE_F(var, val) ({var = val; var;})
598 
599 #else /* OTM */
600 
601 # define STMREAD stm::stm_read
602 # define STMWRITE stm::stm_write
603 
604 # define TM_SHARED_READ_I(var) STMREAD(&var, (stm::TxThread*)STM_SELF)
605 # define TM_SHARED_READ_L(var) STMREAD(&var, (stm::TxThread*)STM_SELF)
606 # define TM_SHARED_READ_P(var) STMREAD(&var, (stm::TxThread*)STM_SELF)
607 # define TM_SHARED_READ_F(var) STMREAD(&var, (stm::TxThread*)STM_SELF)
608 
609 # define TM_SHARED_WRITE_I(var, val) STMWRITE(&var, val, (stm::TxThread*)STM_SELF)
610 # define TM_SHARED_WRITE_L(var, val) STMWRITE(&var, val, (stm::TxThread*)STM_SELF)
611 # define TM_SHARED_WRITE_P(var, val) STMWRITE(&var, val, (stm::TxThread*)STM_SELF)
612 # define TM_SHARED_WRITE_F(var, val) STMWRITE(&var, val, (stm::TxThread*)STM_SELF)
613 
614 # define TM_LOCAL_WRITE_I(var, val) STM_LOCAL_WRITE_I(var, val)
615 # define TM_LOCAL_WRITE_L(var, val) STM_LOCAL_WRITE_L(var, val)
616 # define TM_LOCAL_WRITE_P(var, val) STM_LOCAL_WRITE_P(var, val)
617 # define TM_LOCAL_WRITE_F(var, val) STM_LOCAL_WRITE_F(var, val)
618 # define TM_LOCAL_WRITE_D(var, val) STM_LOCAL_WRITE_D(var, val)
619 
620 #endif /* !OTM */
621 
622 #else /* !STM */
623 
624 # define TM_SHARED_READ_I(var) (var)
625 # define TM_SHARED_READ_L(var) (var)
626 # define TM_SHARED_READ_P(var) (var)
627 # define TM_SHARED_READ_F(var) (var)
628 
629 # define TM_SHARED_WRITE_I(var, val) ({var = val; var;})
630 # define TM_SHARED_WRITE_L(var, val) ({var = val; var;})
631 # define TM_SHARED_WRITE_P(var, val) ({var = val; var;})
632 # define TM_SHARED_WRITE_F(var, val) ({var = val; var;})
633 
634 # define TM_LOCAL_WRITE_I(var, val) ({var = val; var;})
635 # define TM_LOCAL_WRITE_L(var, val) ({var = val; var;})
636 # define TM_LOCAL_WRITE_P(var, val) ({var = val; var;})
637 # define TM_LOCAL_WRITE_F(var, val) ({var = val; var;})
638 
639 #endif /* !STM */
640 
641 
642 #endif /* TM_H */
643 
644 /* =============================================================================
645  * Fix some missing things for ITM.
646  * =============================================================================
647  */
648 #if defined(ITM)
649 extern "C" {
650 [[transaction_safe]] void* malloc(size_t) __THROW;
651 [[transaction_safe]] void free(void*) __THROW;
652 }
653 #endif
654 
655 /* =============================================================================
656  *
657  * End of tm.h
658  *
659  * =============================================================================
660  */