├── .github ├── pull_request_template.md └── workflows │ └── CI.yml ├── .gitignore ├── CHANGES ├── COPYRIGHT ├── Doxyfile.in ├── Makefile.am ├── README.envvar ├── README.md ├── autogen.sh ├── configure.ac ├── doc ├── coding-standards.txt └── img │ ├── es_states.png │ ├── tasklet_states.png │ └── ult_states.png ├── examples ├── .gitignore ├── Makefile.am ├── Makefile.mk ├── fibonacci │ ├── .gitignore │ ├── Makefile.am │ └── fibonacci.c ├── hello_world │ ├── .gitignore │ ├── Makefile.am │ ├── hello_world.c │ └── hello_world_ws.c ├── profiling │ ├── .gitignore │ ├── Makefile.am │ ├── abtx_prof.h │ ├── async_engine.c │ └── daxpy.c ├── scheduling │ ├── .gitignore │ ├── Makefile.am │ ├── sched_and_pool_user.c │ ├── sched_predef.c │ ├── sched_shared_pool.c │ ├── sched_stack.c │ └── sched_user.c └── stencil │ ├── .gitignore │ ├── Makefile.am │ ├── stencil_barrier.c │ ├── stencil_depend_future.c │ ├── stencil_depend_mutex_cond.c │ ├── stencil_depend_yield.c │ ├── stencil_forkjoin.c │ ├── stencil_forkjoin_divconq.c │ ├── stencil_forkjoin_divconq_hrws.c │ ├── stencil_forkjoin_divconq_rws.c │ ├── stencil_forkjoin_divconq_rws_cf.c │ ├── stencil_forkjoin_revive.c │ ├── stencil_forkjoin_task.c │ ├── stencil_forkjoin_task_revive.c │ ├── stencil_forkjoin_ws.c │ ├── stencil_helper.h │ ├── stencil_naive.c │ └── stencil_seq.c ├── m4 ├── aclocal.m4 ├── aclocal_cc.m4 ├── aclocal_check_visibility.m4 ├── aclocal_runlog.m4 ├── aclocal_util.m4 ├── ax_gcc_builtin.m4 ├── ax_gcc_func_attribute.m4 └── config.rpath ├── maint ├── Version.base.m4 ├── argobots.pc.in ├── code-cleanup.sh ├── hook │ └── pre-commit ├── release.pl ├── spellcheck.bash ├── template.c └── version.m4 ├── src ├── Makefile.am ├── arch │ ├── Makefile.mk │ ├── abtd_affinity.c │ ├── abtd_affinity_parser.c │ ├── abtd_env.c │ ├── abtd_futex.c │ ├── abtd_stream.c │ ├── abtd_time.c │ ├── abtd_ythread.c │ └── fcontext │ │ ├── LICENSE_1_0.txt │ │ ├── fcontext_arm64_aapcs_elf_gas.S │ │ ├── fcontext_arm64_aapcs_macho_gas.S │ │ ├── fcontext_i386_sysv_elf_gas.S │ │ ├── fcontext_ppc64_sysv_elf_gas.S │ │ ├── fcontext_x86_64_sysv_elf_gas.S │ │ └── fcontext_x86_64_sysv_macho_gas.S ├── barrier.c ├── cond.c ├── error.c ├── eventual.c ├── futures.c ├── global.c ├── include │ ├── Makefile.mk │ ├── abt.h.in │ ├── abtd.h │ ├── abtd_atomic.h │ ├── abtd_context.h │ ├── abtd_fcontext.h │ ├── abtd_futex.h │ ├── abtd_spinlock.h │ ├── abtd_stream.h │ ├── abtd_ucontext.h │ ├── abti.h │ ├── abti_barrier.h │ ├── abti_cond.h │ ├── abti_error.h │ ├── abti_event.h │ ├── abti_eventual.h │ ├── abti_future.h │ ├── abti_global.h │ ├── abti_key.h │ ├── abti_local.h │ ├── abti_log.h │ ├── abti_mem.h │ ├── abti_mem_pool.h │ ├── abti_mutex.h │ ├── abti_mutex_attr.h │ ├── abti_pool.h │ ├── abti_pool_config.h │ ├── abti_pool_user_def.h │ ├── abti_rwlock.h │ ├── abti_sched.h │ ├── abti_sched_config.h │ ├── abti_self.h │ ├── abti_stream.h │ ├── abti_stream_barrier.h │ ├── abti_sync_lifo.h │ ├── abti_thread.h │ ├── abti_thread_attr.h │ ├── abti_timer.h │ ├── abti_tool.h │ ├── abti_unit.h │ ├── abti_valgrind.h │ ├── abti_waitlist.h │ ├── abti_ythread.h │ ├── abtu.h │ └── asm │ │ ├── Makefile.mk │ │ └── abtd_asm_int128_cas.h ├── info.c ├── key.c ├── local.c ├── log.c ├── mem │ ├── Makefile.mk │ ├── malloc.c │ ├── mem_pool.c │ └── valgrind.c ├── mutex.c ├── mutex_attr.c ├── pool │ ├── Makefile.mk │ ├── fifo.c │ ├── fifo_wait.c │ ├── pool.c │ ├── pool_config.c │ ├── pool_user_def.c │ ├── randws.c │ └── thread_queue.h ├── rwlock.c ├── sched │ ├── Makefile.mk │ ├── basic.c │ ├── basic_wait.c │ ├── prio.c │ ├── randws.c │ ├── sched.c │ └── sched_config.c ├── self.c ├── stream.c ├── stream_barrier.c ├── task.c ├── thread.c ├── thread_attr.c ├── timer.c ├── tool.c ├── unit.c ├── util │ ├── Makefile.mk │ ├── atoi.c │ ├── hashtable.c │ ├── largepage.c │ └── mprotect.c └── ythread.c └── test ├── .gitignore ├── Makefile.am ├── Makefile.mk ├── basic ├── Makefile.am ├── barrier.c ├── cond_join.c ├── cond_signal_in_main.c ├── cond_static.c ├── cond_test.c ├── cond_timedwait.c ├── error.c ├── eventual_create.c ├── eventual_static.c ├── eventual_test.c ├── ext_thread.c ├── ext_thread2.c ├── ext_thread_barrier.c ├── ext_thread_cond.c ├── ext_thread_eventual.c ├── ext_thread_future.c ├── ext_thread_join.c ├── ext_thread_mutex.c ├── ext_thread_rwlock.c ├── future_create.c ├── info_print.c ├── info_print_stack.c ├── info_query.c ├── info_stackdump.c ├── info_stackdump2.c ├── init_finalize.c ├── main_sched.c ├── mutex.c ├── mutex_prio.c ├── mutex_recursive.c ├── mutex_spinlock.c ├── mutex_static.c ├── mutex_unlock_se.c ├── pool_config.c ├── pool_custom.c ├── pool_user_def.c ├── rwlock_reader_incl.c ├── rwlock_reader_writer_excl.c ├── rwlock_writer_excl.c ├── sched_basic.c ├── sched_basic_wait.c ├── sched_config.c ├── sched_on_thread.c ├── sched_prio.c ├── sched_randws.c ├── sched_set_main.c ├── sched_stack.c ├── sched_user_ws.c ├── self_exit_to.c ├── self_rank_id.c ├── self_resume_to.c ├── self_suspend_to.c ├── self_type.c ├── self_yield_to.c ├── stack_guard.c ├── sync_no_contention.c ├── task_create.c ├── task_create_on_xstream.c ├── task_data.c ├── task_data2.c ├── task_revive.c ├── thread_attr.c ├── thread_attr2.c ├── thread_create.c ├── thread_create2.c ├── thread_create3.c ├── thread_create4.c ├── thread_create_on_xstream.c ├── thread_data.c ├── thread_data2.c ├── thread_exit.c ├── thread_get_func_arg.c ├── thread_get_last_xstream.c ├── thread_id.c ├── thread_migrate.c ├── thread_revive.c ├── thread_self_suspend_resume.c ├── thread_task.c ├── thread_task_arg.c ├── thread_task_num.c ├── thread_yield.c ├── thread_yield2.c ├── thread_yield_to.c ├── timer.c ├── unit.c ├── xstream_affinity.c ├── xstream_barrier.c ├── xstream_create.c ├── xstream_rank.c ├── xstream_revive.c └── xstream_set_main_sched.c ├── benchmark ├── Makefile.am ├── bench_util.h ├── init_finalize.c ├── sync_ops.c ├── task_fork_join.c ├── task_ops.c ├── task_ops_all.c ├── thread_fork_join.c ├── thread_many_ops.c ├── thread_ops.c ├── thread_ops_all.c └── xstream_ops.c ├── leakcheck ├── .gitignore ├── Makefile.am ├── affinity.c ├── barrier.c ├── cond.c ├── eventual.c ├── future.c ├── init_finalize.c ├── key.c ├── mutex.c ├── pool.c ├── rtrace.c ├── rtrace.h ├── rwlock.c ├── sched.c ├── thread.c ├── timer.c ├── unit.c ├── util.h ├── xstream.c └── xstream_barrier.c ├── scripts └── create_junit.pl └── util ├── Makefile.am ├── abttest.c └── abttest.h /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Pull Request Description 2 | 3 | 6 | 7 | ## Checklist 8 | * [ ] Reference appropriate issues (with "Fixes" or "See" as appropriate) 9 | * [ ] Commits are self-contained and do not do two things at once 10 | * [ ] Commit message is of the form: `module: short description` and follows [good practice](https://chris.beams.io/posts/git-commit/) 11 | * [ ] Passes whitespace checkers 12 | 13 | 17 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | 2 | name: CI 3 | 4 | on: 5 | push: 6 | branches: [ main ] 7 | pull_request: 8 | branches: [ main ] 9 | 10 | jobs: 11 | whitespace: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 0 17 | - name: cleanup 18 | run: | 19 | maint/code-cleanup.sh --all --recursive 20 | git --no-pager diff 21 | if [ x"$(git --no-pager diff)" != x ]; then 22 | exit 1 23 | fi 24 | 25 | build-basic: 26 | runs-on: ubuntu-latest 27 | timeout-minutes: 20 28 | env: 29 | CFLAGS: "-std=gnu90 -Werror -Wextra" 30 | steps: 31 | - uses: actions/checkout@v2 32 | - name: autogen 33 | run: | 34 | ./autogen.sh 35 | - name: configure 36 | run: | 37 | ./configure 38 | - name: make 39 | run: | 40 | make -j 2 41 | cd test 42 | make -j 2 43 | cd ../examples 44 | make -j 2 45 | cd ../ 46 | - name: run_test 47 | run: | 48 | cd test 49 | make check -j 2 50 | cd ../ 51 | - name: run_examples 52 | run: | 53 | cd examples 54 | make check -j 2 55 | cd ../ 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # configure and make files 2 | Makefile.in 3 | Makefile 4 | aclocal.m4 5 | autom4te.cache/ 6 | configure 7 | config.log 8 | config.status 9 | libtool 10 | src/include/abt_config.h 11 | src/include/abt_config.h.in 12 | stamp-h1 13 | Doxyfile 14 | maint/argobots.pc 15 | 16 | # m4 additions 17 | m4/ar-lib 18 | m4/compile 19 | m4/config.guess 20 | m4/config.sub 21 | m4/depcomp 22 | m4/install-sh 23 | m4/libtool.m4 24 | m4/ltmain.sh 25 | m4/ltoptions.m4 26 | m4/ltsugar.m4 27 | m4/ltversion.m4 28 | m4/lt~obsolete.m4 29 | m4/missing 30 | m4/test-driver 31 | 32 | # temporary directories 33 | .libs/ 34 | .deps/ 35 | .dirstamp 36 | 37 | # code builds 38 | libabt.la 39 | abt.h 40 | *.lo 41 | *.o 42 | *~ 43 | 44 | # autogen.sh temporary files 45 | maint/Version 46 | README 47 | .tmp 48 | 49 | # editor temporary files 50 | .*.swp 51 | .*.swo 52 | 53 | # etc. 54 | .DS_Store 55 | doc/doxygen/ 56 | *.log 57 | *.trs 58 | *.out 59 | *.files 60 | *.dSYM/ 61 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | Changes in 1.1 3 | =============================================================================== 4 | 5 | - Added a tool interface to support a profiler (see ABTX_prof) 6 | - Supported the stack unwinding feature 7 | - Implemented static initializers for ABT_mutex and ABT_cond 8 | - Improved work-unit-local storage support 9 | - Added several utility functions 10 | - Improved support for affinity settings via an environmental variable 11 | - Enhanced memory management of ULT stacks and descriptors 12 | - Used futex when external threads call Argobots synchronization operations 13 | - Revised the API specification 14 | - Added support for XLC, PGI, Solaris, and ARM HPC compilers 15 | - Supported Autoconf 2.70 16 | - Fixed several bugs 17 | 18 | =============================================================================== 19 | Changes in 1.0.1 20 | =============================================================================== 21 | 22 | - Fixed the ABI string for the Argobots 1.0.x series. 23 | 24 | =============================================================================== 25 | Changes in 1.0 26 | =============================================================================== 27 | 28 | - Added support for restarting xstream 29 | - Updated the example code 30 | - Fixed the IBM POWER support 31 | - Fixed a bug in affinity management 32 | - Fixed a bug in future operation 33 | - Fixed a bug in hugepage allocation 34 | - Removed retain/release APIs of ULTs and tasklets 35 | - Removed the event interface 36 | - Updated the code formatting standard to use clang-format 37 | 38 | =============================================================================== 39 | Changes in 1.0rc2 40 | =============================================================================== 41 | 42 | - Added support for stack dump 43 | - Added support for ucontext to cover more architectures 44 | - Fixed code that assumes 64-bit OS to support 32bit environments 45 | - Enhanced performance with --enable-valgrind when Valgrind is not used 46 | - Fixed a bug in TLS handling 47 | - Fixed a bug in memory pool 48 | 49 | =============================================================================== 50 | Changes in 1.0rc1 51 | =============================================================================== 52 | 53 | - Added support for dynamically promoted threads, which offer 54 | better trade-offs than the existing ULT and tasklet methods 55 | - Reduced the overhead of context switching 56 | - Fixed the Valgrind support 57 | - Extended the API with new blocking pool operations 58 | - Leverage the more efficient GCC `__atomic` builtins when available 59 | - Fixed a bug in the condition variable implementation 60 | - Fixed bugs in memory pool 61 | - Fixed bugs in pool operation 62 | 63 | =============================================================================== 64 | Changes in 1.0b1 65 | =============================================================================== 66 | 67 | - Added new API routines for bulk ULT creation and destruction 68 | - Reduced the overhead of error checking 69 | - Fixed bugs in some thread synchronization routines 70 | - Fixed POWER8 support 71 | - CPU affinity improvements on Intel KNL 72 | - Improved the dynamic management of large numbers of execution streams 73 | - Removed the local-exec TLS option 74 | - Updated the documentation 75 | - Added performance benchmarks 76 | 77 | =============================================================================== 78 | Changes in 1.0a1 79 | =============================================================================== 80 | 81 | The first release of Argobots. 82 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright © 2016, UChicago Argonne, LLC 2 | 3 | All Rights Reserved 4 | 5 | Argobots: A Lightweight Low-level Threading/Tasking Framework, SF-16-039 6 | 7 | OPEN SOURCE LICENSE 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. Software changes, 14 | modifications, or derivative works, should be noted with comments and the 15 | author and organization's name. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | 21 | 3. Neither the names of UChicago Argonne, LLC or the Department of Energy nor 22 | the names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | 4. The software and the end-user documentation included with the 26 | redistribution, if any, must include the following acknowledgment: 27 | 28 | "This product includes software produced by UChicago Argonne, LLC under 29 | Contract No. DE-AC02-06CH11357 with the Department of Energy." 30 | 31 | 32 | ******************************************************************************** 33 | DISCLAIMER 34 | 35 | THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND. 36 | 37 | NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF 38 | ENERGY, NOR UCHICAGO ARGONNE, LLC, NOR ANY OF THEIR EMPLOYEES, MAKES ANY 39 | WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY 40 | FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, DATA, 41 | APPARATUS, PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT 42 | INFRINGE PRIVATELY OWNED RIGHTS. 43 | 44 | ******************************************************************************** 45 | 46 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | ACLOCAL_AMFLAGS = -I m4 7 | 8 | SUBDIRS = src 9 | DIST_SUBDIRS = $(SUBDIRS) test examples 10 | 11 | EXTRA_DIST = autogen.sh 12 | 13 | .PHONY: build-all clean-all doxygen 14 | 15 | pkgconfigdir = $(libdir)/pkgconfig 16 | pkgconfig_DATA = maint/argobots.pc 17 | 18 | build-all: 19 | $(MAKE) 20 | $(MAKE) -C test 21 | $(MAKE) -C examples 22 | 23 | clean-all: 24 | $(MAKE) clean 25 | $(MAKE) -C test clean 26 | $(MAKE) -C examples clean 27 | 28 | doxygen: 29 | mkdir -p doc 30 | doxygen Doxyfile 31 | -------------------------------------------------------------------------------- /doc/coding-standards.txt: -------------------------------------------------------------------------------- 1 | Argobots uses K&R style. The script maint/code-cleanup.sh can be used to 2 | cleanup whitespace, comments, and line-wrapping in existing source files. 3 | It is a good idea to run it on any newly created files in the git repo. 4 | 5 | For more information about coding standards, please refer to 6 | https://github.com/pmodels/argobots/wiki/Coding-Standards 7 | 8 | -------------------------------------------------------------------------------- /doc/img/es_states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmodels/argobots/bb6faacab09f41c23d30886bfdc9becd113970a8/doc/img/es_states.png -------------------------------------------------------------------------------- /doc/img/tasklet_states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmodels/argobots/bb6faacab09f41c23d30886bfdc9becd113970a8/doc/img/tasklet_states.png -------------------------------------------------------------------------------- /doc/img/ult_states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmodels/argobots/bb6faacab09f41c23d30886bfdc9becd113970a8/doc/img/ult_states.png -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | # examples 2 | fibonacci_future 3 | fibonacci_recursive 4 | hello_world 5 | hello_world_thread 6 | sched_predef 7 | sched_shared_pool 8 | sched_stack 9 | sched_user 10 | sched_and_pool_user 11 | stencil_task 12 | stencil_thread 13 | stencil_thread_cond 14 | -------------------------------------------------------------------------------- /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | SUBDIRS = fibonacci hello_world profiling scheduling stencil 7 | DIST_SUBDIRS = $(SUBDIRS) 8 | -------------------------------------------------------------------------------- /examples/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | AM_CPPFLAGS = $(DEPS_CPPFLAGS) 7 | AM_CPPFLAGS += -I$(top_builddir)/src/include 8 | AM_LDFLAGS = $(DEPS_LDFLAGS) 9 | 10 | libabt = $(top_builddir)/src/libabt.la 11 | 12 | $(libabt): 13 | $(MAKE) -C $(top_builddir)/src 14 | 15 | LDADD = $(libabt) 16 | -------------------------------------------------------------------------------- /examples/fibonacci/.gitignore: -------------------------------------------------------------------------------- 1 | fibonacci 2 | -------------------------------------------------------------------------------- /examples/fibonacci/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | fibonacci 8 | 9 | check_PROGRAMS = $(TESTS) 10 | noinst_PROGRAMS = $(TESTS) 11 | 12 | include $(top_srcdir)/examples/Makefile.mk 13 | 14 | fibonacci_SOURCES = fibonacci.c 15 | -------------------------------------------------------------------------------- /examples/hello_world/.gitignore: -------------------------------------------------------------------------------- 1 | hello_world 2 | hello_world_ws 3 | -------------------------------------------------------------------------------- /examples/hello_world/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | hello_world \ 8 | hello_world_ws 9 | 10 | check_PROGRAMS = $(TESTS) 11 | noinst_PROGRAMS = $(TESTS) 12 | 13 | include $(top_srcdir)/examples/Makefile.mk 14 | 15 | hello_world_SOURCES = hello_world.c 16 | hello_world_ws_SOURCES = hello_world_ws.c 17 | -------------------------------------------------------------------------------- /examples/hello_world/hello_world.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | /* 7 | * Creates multiple execution streams and runs ULTs on these execution streams. 8 | * Users can change the number of execution streams and the number of ULT via 9 | * arguments. Each ULT prints its ID. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define DEFAULT_NUM_XSTREAMS 2 19 | #define DEFAULT_NUM_THREADS 8 20 | 21 | typedef struct { 22 | int tid; 23 | } thread_arg_t; 24 | 25 | void hello_world(void *arg) 26 | { 27 | int tid = ((thread_arg_t *)arg)->tid; 28 | printf("Hello world! (thread = %d)\n", tid); 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | int i; 34 | /* Read arguments. */ 35 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 36 | int num_threads = DEFAULT_NUM_THREADS; 37 | while (1) { 38 | int opt = getopt(argc, argv, "he:n:"); 39 | if (opt == -1) 40 | break; 41 | switch (opt) { 42 | case 'e': 43 | num_xstreams = atoi(optarg); 44 | break; 45 | case 'n': 46 | num_threads = atoi(optarg); 47 | break; 48 | case 'h': 49 | default: 50 | printf("Usage: ./hello_world [-e NUM_XSTREAMS] " 51 | "[-n NUM_THREADS]\n"); 52 | return -1; 53 | } 54 | } 55 | if (num_xstreams <= 0) 56 | num_xstreams = 1; 57 | if (num_threads <= 0) 58 | num_threads = 1; 59 | 60 | /* Allocate memory. */ 61 | ABT_xstream *xstreams = 62 | (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 63 | ABT_pool *pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 64 | ABT_thread *threads = 65 | (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads); 66 | thread_arg_t *thread_args = 67 | (thread_arg_t *)malloc(sizeof(thread_arg_t) * num_threads); 68 | 69 | /* Initialize Argobots. */ 70 | ABT_init(argc, argv); 71 | 72 | /* Get a primary execution stream. */ 73 | ABT_xstream_self(&xstreams[0]); 74 | 75 | /* Create secondary execution streams. */ 76 | for (i = 1; i < num_xstreams; i++) { 77 | ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 78 | } 79 | 80 | /* Get default pools. */ 81 | for (i = 0; i < num_xstreams; i++) { 82 | ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); 83 | } 84 | 85 | /* Create ULTs. */ 86 | for (i = 0; i < num_threads; i++) { 87 | int pool_id = i % num_xstreams; 88 | thread_args[i].tid = i; 89 | ABT_thread_create(pools[pool_id], hello_world, &thread_args[i], 90 | ABT_THREAD_ATTR_NULL, &threads[i]); 91 | } 92 | 93 | /* Join and free ULTs. */ 94 | for (i = 0; i < num_threads; i++) { 95 | ABT_thread_free(&threads[i]); 96 | } 97 | 98 | /* Join and free secondary execution streams. */ 99 | for (i = 1; i < num_xstreams; i++) { 100 | ABT_xstream_join(xstreams[i]); 101 | ABT_xstream_free(&xstreams[i]); 102 | } 103 | 104 | /* Finalize Argobots. */ 105 | ABT_finalize(); 106 | 107 | /* Free allocated memory. */ 108 | free(xstreams); 109 | free(pools); 110 | free(threads); 111 | free(thread_args); 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /examples/hello_world/hello_world_ws.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | /* 7 | * Creates multiple execution streams and runs ULTs on these execution streams. 8 | * Users can change the number of execution streams and the number of ULTs via 9 | * arguments. Pools are shared among schedulers, so ULTs can be executed on any 10 | * execution streams by work stealing. Each ULT prints its ID and the rank of 11 | * the underlying execution stream. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #define DEFAULT_NUM_XSTREAMS 2 21 | #define DEFAULT_NUM_THREADS 8 22 | 23 | typedef struct { 24 | int tid; 25 | } thread_arg_t; 26 | 27 | void hello_world(void *arg) 28 | { 29 | int tid = ((thread_arg_t *)arg)->tid; 30 | int rank; 31 | ABT_xstream_self_rank(&rank); 32 | printf("Hello world! (thread = %d, ES = %d)\n", tid, rank); 33 | } 34 | 35 | int main(int argc, char **argv) 36 | { 37 | int i, j; 38 | /* Read arguments. */ 39 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 40 | int num_threads = DEFAULT_NUM_THREADS; 41 | while (1) { 42 | int opt = getopt(argc, argv, "he:n:"); 43 | if (opt == -1) 44 | break; 45 | switch (opt) { 46 | case 'e': 47 | num_xstreams = atoi(optarg); 48 | break; 49 | case 'n': 50 | num_threads = atoi(optarg); 51 | break; 52 | case 'h': 53 | default: 54 | printf("Usage: ./hello_world_ws [-e NUM_XSTREAMS] " 55 | "[-n NUM_THREADS]\n"); 56 | return -1; 57 | } 58 | } 59 | if (num_xstreams <= 0) 60 | num_xstreams = 1; 61 | if (num_threads <= 0) 62 | num_threads = 1; 63 | 64 | /* Allocate memory. */ 65 | ABT_xstream *xstreams = 66 | (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 67 | ABT_pool *pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 68 | ABT_sched *scheds = (ABT_sched *)malloc(sizeof(ABT_sched) * num_xstreams); 69 | ABT_thread *threads = 70 | (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads); 71 | thread_arg_t *thread_args = 72 | (thread_arg_t *)malloc(sizeof(thread_arg_t) * num_threads); 73 | 74 | /* Initialize Argobots. */ 75 | ABT_init(argc, argv); 76 | 77 | /* Create pools. */ 78 | for (i = 0; i < num_xstreams; i++) { 79 | ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, 80 | &pools[i]); 81 | } 82 | 83 | /* Create schedulers. */ 84 | for (i = 0; i < num_xstreams; i++) { 85 | ABT_pool *tmp = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 86 | for (j = 0; j < num_xstreams; j++) { 87 | tmp[j] = pools[(i + j) % num_xstreams]; 88 | } 89 | ABT_sched_create_basic(ABT_SCHED_DEFAULT, num_xstreams, tmp, 90 | ABT_SCHED_CONFIG_NULL, &scheds[i]); 91 | free(tmp); 92 | } 93 | 94 | /* Set up a primary execution stream. */ 95 | ABT_xstream_self(&xstreams[0]); 96 | ABT_xstream_set_main_sched(xstreams[0], scheds[0]); 97 | 98 | /* Create secondary execution streams. */ 99 | for (i = 1; i < num_xstreams; i++) { 100 | ABT_xstream_create(scheds[i], &xstreams[i]); 101 | } 102 | 103 | /* Create ULTs. */ 104 | for (i = 0; i < num_threads; i++) { 105 | int pool_id = i % num_xstreams; 106 | thread_args[i].tid = i; 107 | ABT_thread_create(pools[pool_id], hello_world, &thread_args[i], 108 | ABT_THREAD_ATTR_NULL, &threads[i]); 109 | } 110 | 111 | /* Join and free ULTs. */ 112 | for (i = 0; i < num_threads; i++) { 113 | ABT_thread_free(&threads[i]); 114 | } 115 | 116 | /* Join secondary execution streams. */ 117 | for (i = 1; i < num_xstreams; i++) { 118 | ABT_xstream_join(xstreams[i]); 119 | ABT_xstream_free(&xstreams[i]); 120 | } 121 | 122 | /* Finalize Argobots. */ 123 | ABT_finalize(); 124 | 125 | /* Free allocated memory. */ 126 | free(xstreams); 127 | free(pools); 128 | free(scheds); 129 | free(threads); 130 | free(thread_args); 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /examples/profiling/.gitignore: -------------------------------------------------------------------------------- 1 | daxpy 2 | async_engine 3 | -------------------------------------------------------------------------------- /examples/profiling/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | daxpy \ 8 | async_engine 9 | 10 | check_PROGRAMS = $(TESTS) 11 | noinst_PROGRAMS = $(TESTS) 12 | 13 | include $(top_srcdir)/examples/Makefile.mk 14 | 15 | daxpy_SOURCES = daxpy.c 16 | async_engine_SOURCES = async_engine.c 17 | -------------------------------------------------------------------------------- /examples/scheduling/.gitignore: -------------------------------------------------------------------------------- 1 | sched_and_pool_user 2 | sched_predef 3 | sched_shared_pool 4 | sched_stack 5 | sched_user 6 | 7 | -------------------------------------------------------------------------------- /examples/scheduling/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | sched_and_pool_user \ 8 | sched_predef \ 9 | sched_shared_pool \ 10 | sched_stack \ 11 | sched_user 12 | 13 | check_PROGRAMS = $(TESTS) 14 | noinst_PROGRAMS = $(TESTS) 15 | 16 | include $(top_srcdir)/examples/Makefile.mk 17 | 18 | sched_and_pool_user_SOURCES = sched_and_pool_user.c 19 | sched_predef_SOURCES = sched_predef.c 20 | sched_shared_pool_SOURCES = sched_shared_pool.c 21 | sched_stack_SOURCES = sched_stack.c 22 | sched_user_SOURCES = sched_user.c 23 | -------------------------------------------------------------------------------- /examples/scheduling/sched_predef.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | 10 | #define NUM_XSTREAMS 4 11 | 12 | void thread_hello(void *arg) 13 | { 14 | int rank, tid = (int)(size_t)arg; 15 | ABT_xstream_self_rank(&rank); 16 | printf("[U%d:E%d] Hello, world!\n", tid, rank); 17 | } 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | ABT_xstream xstreams[NUM_XSTREAMS]; 22 | ABT_sched scheds[NUM_XSTREAMS]; 23 | int num_pools[NUM_XSTREAMS]; 24 | ABT_pool *pools[NUM_XSTREAMS]; 25 | int i, k; 26 | 27 | ABT_init(argc, argv); 28 | 29 | /* Create schedulers */ 30 | for (i = 0; i < NUM_XSTREAMS; i++) { 31 | ABT_sched_predef predef; 32 | predef = (i % 2) ? ABT_SCHED_BASIC : ABT_SCHED_PRIO; 33 | ABT_sched_create_basic(predef, 0, NULL, ABT_SCHED_CONFIG_NULL, 34 | &scheds[i]); 35 | } 36 | 37 | /* Create ESs */ 38 | ABT_xstream_self(&xstreams[0]); 39 | ABT_xstream_set_main_sched(xstreams[0], scheds[0]); 40 | for (i = 1; i < NUM_XSTREAMS; i++) { 41 | ABT_xstream_create(scheds[i], &xstreams[i]); 42 | } 43 | 44 | /* Get the pools associated with each scheduler */ 45 | for (i = 0; i < NUM_XSTREAMS; i++) { 46 | ABT_sched_get_num_pools(scheds[i], &num_pools[i]); 47 | pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); 48 | ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]); 49 | } 50 | 51 | /* Create ULTs */ 52 | for (i = 0; i < NUM_XSTREAMS; i++) { 53 | for (k = num_pools[i] - 1; k >= 0; k--) { 54 | size_t tid = (i + 1) * 10 + k; 55 | ABT_thread_create(pools[i][k], thread_hello, (void *)tid, 56 | ABT_THREAD_ATTR_NULL, NULL); 57 | } 58 | } 59 | 60 | /* Join & Free */ 61 | for (i = 1; i < NUM_XSTREAMS; i++) { 62 | ABT_xstream_join(xstreams[i]); 63 | ABT_xstream_free(&xstreams[i]); 64 | } 65 | 66 | for (i = 0; i < NUM_XSTREAMS; i++) { 67 | free(pools[i]); 68 | } 69 | 70 | ABT_finalize(); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /examples/scheduling/sched_shared_pool.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | 10 | #define NUM_XSTREAMS 4 11 | #define NUM_THREADS (NUM_XSTREAMS * 2) 12 | 13 | void thread_hello(void *arg) 14 | { 15 | int rank, tid = (int)(size_t)arg; 16 | ABT_xstream_self_rank(&rank); 17 | printf("[U%d:E%d] Hello, world!\n", tid, rank); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | ABT_xstream xstreams[NUM_XSTREAMS]; 23 | ABT_sched scheds[NUM_XSTREAMS]; 24 | ABT_pool shared_pool; 25 | ABT_thread threads[NUM_THREADS]; 26 | int i; 27 | 28 | ABT_init(argc, argv); 29 | 30 | /* Create a shared pool */ 31 | ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, 32 | &shared_pool); 33 | 34 | /* Create schedulers */ 35 | for (i = 0; i < NUM_XSTREAMS; i++) { 36 | ABT_sched_create_basic(ABT_SCHED_DEFAULT, 1, &shared_pool, 37 | ABT_SCHED_CONFIG_NULL, &scheds[i]); 38 | } 39 | 40 | /* Create ESs */ 41 | ABT_xstream_self(&xstreams[0]); 42 | ABT_xstream_set_main_sched(xstreams[0], scheds[0]); 43 | for (i = 1; i < NUM_XSTREAMS; i++) { 44 | ABT_xstream_create(scheds[i], &xstreams[i]); 45 | } 46 | 47 | /* Create ULTs */ 48 | for (i = 0; i < NUM_THREADS; i++) { 49 | size_t tid = (size_t)i; 50 | ABT_thread_create(shared_pool, thread_hello, (void *)tid, 51 | ABT_THREAD_ATTR_NULL, &threads[i]); 52 | } 53 | 54 | /* Join & Free */ 55 | for (i = 0; i < NUM_THREADS; i++) { 56 | ABT_thread_join(threads[i]); 57 | ABT_thread_free(&threads[i]); 58 | } 59 | for (i = 1; i < NUM_XSTREAMS; i++) { 60 | ABT_xstream_join(xstreams[i]); 61 | ABT_xstream_free(&xstreams[i]); 62 | } 63 | 64 | ABT_finalize(); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /examples/scheduling/sched_stack.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | 10 | #define NUM_XSTREAMS 2 11 | #define NUM_TASKS 10 12 | 13 | void task_hello(void *arg) 14 | { 15 | int rank, tid = (int)(size_t)arg; 16 | ABT_xstream_self_rank(&rank); 17 | printf(" [T%d:E%d] Hello, world!\n", tid, rank); 18 | } 19 | 20 | void add_sched(void *arg) 21 | { 22 | int rank, tid = (int)(size_t)arg; 23 | ABT_xstream_self_rank(&rank); 24 | ABT_sched sched; 25 | ABT_pool cur_pool, tar_pool; 26 | ABT_thread cur_thread; 27 | int i; 28 | 29 | /* Create a new scheduler */ 30 | printf("[U%d:E%d] Create a scheduler and tasks\n", tid, rank); 31 | ABT_sched_create_basic(ABT_SCHED_BASIC, 0, NULL, ABT_SCHED_CONFIG_NULL, 32 | &sched); 33 | 34 | /* Create tasks */ 35 | ABT_sched_get_pools(sched, 1, 0, &tar_pool); 36 | for (i = 0; i < NUM_TASKS; i++) { 37 | ABT_task_create(tar_pool, task_hello, (void *)(size_t)i, NULL); 38 | } 39 | 40 | /* Push the scheduler to the current pool */ 41 | printf("[U%d:E%d] Push the scheduler\n", tid, rank); 42 | ABT_thread_self(&cur_thread); 43 | ABT_thread_get_last_pool(cur_thread, &cur_pool); 44 | ABT_pool_add_sched(cur_pool, sched); 45 | } 46 | 47 | int main(int argc, char *argv[]) 48 | { 49 | ABT_xstream xstreams[NUM_XSTREAMS]; 50 | ABT_pool pools[NUM_XSTREAMS]; 51 | ABT_thread threads[NUM_XSTREAMS]; 52 | int i; 53 | 54 | ABT_init(argc, argv); 55 | 56 | /* Create ESs */ 57 | ABT_xstream_self(&xstreams[0]); 58 | for (i = 1; i < NUM_XSTREAMS; i++) { 59 | ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 60 | } 61 | 62 | /* Get the first pool associated with each ES */ 63 | for (i = 0; i < NUM_XSTREAMS; i++) { 64 | ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); 65 | } 66 | 67 | /* Create ULTs */ 68 | for (i = 0; i < NUM_XSTREAMS; i++) { 69 | ABT_thread_create(pools[i], add_sched, (void *)(size_t)i, 70 | ABT_THREAD_ATTR_NULL, &threads[i]); 71 | } 72 | 73 | /* Join & Free */ 74 | for (i = 0; i < NUM_XSTREAMS; i++) { 75 | ABT_thread_join(threads[i]); 76 | ABT_thread_free(&threads[i]); 77 | } 78 | for (i = 1; i < NUM_XSTREAMS; i++) { 79 | ABT_xstream_join(xstreams[i]); 80 | ABT_xstream_free(&xstreams[i]); 81 | } 82 | 83 | ABT_finalize(); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /examples/stencil/.gitignore: -------------------------------------------------------------------------------- 1 | stencil_barrier 2 | stencil_depend_future 3 | stencil_depend_mutex_cond 4 | stencil_depend_yield 5 | stencil_forkjoin 6 | stencil_forkjoin_divconq 7 | stencil_forkjoin_divconq_hrws 8 | stencil_forkjoin_divconq_rws 9 | stencil_forkjoin_divconq_rws_cf 10 | stencil_forkjoin_revive 11 | stencil_forkjoin_task 12 | stencil_forkjoin_task_revive 13 | stencil_forkjoin_ws 14 | stencil_naive 15 | stencil_seq 16 | 17 | -------------------------------------------------------------------------------- /examples/stencil/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | stencil_barrier \ 8 | stencil_depend_future \ 9 | stencil_depend_mutex_cond \ 10 | stencil_depend_yield \ 11 | stencil_forkjoin \ 12 | stencil_forkjoin_divconq \ 13 | stencil_forkjoin_divconq_hrws \ 14 | stencil_forkjoin_divconq_rws \ 15 | stencil_forkjoin_divconq_rws_cf \ 16 | stencil_forkjoin_revive \ 17 | stencil_forkjoin_task \ 18 | stencil_forkjoin_task_revive \ 19 | stencil_forkjoin_ws \ 20 | stencil_naive \ 21 | stencil_seq 22 | 23 | check_PROGRAMS = $(TESTS) 24 | noinst_PROGRAMS = $(TESTS) 25 | 26 | include $(top_srcdir)/examples/Makefile.mk 27 | 28 | stencil_barrier_SOURCES = stencil_barrier.c 29 | stencil_depend_future_SOURCES = stencil_depend_future.c 30 | stencil_depend_mutex_cond_SOURCES = stencil_depend_mutex_cond.c 31 | stencil_depend_yield_SOURCES = stencil_depend_yield.c 32 | stencil_forkjoin_SOURCES = stencil_forkjoin.c 33 | stencil_forkjoin_divconq_SOURCES = stencil_forkjoin_divconq.c 34 | stencil_forkjoin_divconq_hrws_SOURCES = stencil_forkjoin_divconq_hrws.c 35 | stencil_forkjoin_divconq_rws_SOURCES = stencil_forkjoin_divconq_rws.c 36 | stencil_forkjoin_divconq_rws_cf_SOURCES = stencil_forkjoin_divconq_rws_cf.c 37 | stencil_forkjoin_revive_SOURCES = stencil_forkjoin_revive.c 38 | stencil_forkjoin_task_SOURCES = stencil_forkjoin_task.c 39 | stencil_forkjoin_task_revive_SOURCES = stencil_forkjoin_task_revive.c 40 | stencil_forkjoin_ws_SOURCES = stencil_forkjoin_ws.c 41 | stencil_naive_SOURCES = stencil_naive.c 42 | stencil_seq_SOURCES = stencil_seq.c 43 | -------------------------------------------------------------------------------- /examples/stencil/stencil_naive.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | /* 7 | * Very basic sequential five-point 2D stencil code. The grid contains 8 | * num_blocksX * num_blocksY blocks, each of which has blocksize x blocksize 9 | * points, so in total, the grid contains (num_blocksX * blocksize) x 10 | * (num_blocksY * blocksize) points. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "stencil_helper.h" 17 | 18 | /* Global variables. */ 19 | int num_blocksX, num_blocksY; 20 | int blocksize; 21 | int num_iters; 22 | int num_xstreams; 23 | int validate; 24 | 25 | int main(int argc, char **argv) 26 | { 27 | int t; 28 | /* Read arguments. */ 29 | int read_arg_ret = 30 | read_args(argc, argv, &num_blocksX, &num_blocksY, &blocksize, 31 | &num_iters, &num_xstreams, &validate); 32 | if (read_arg_ret != 0) { 33 | return -1; 34 | } 35 | 36 | /* Allocate memory. */ 37 | double *values_old = (double *)malloc(sizeof(double) * WIDTH * HEIGHT); 38 | double *values_new = (double *)malloc(sizeof(double) * WIDTH * HEIGHT); 39 | 40 | /* Initialize grid values. */ 41 | init_values(values_old, values_new, num_blocksX, num_blocksY, blocksize); 42 | 43 | /* Main iteration loop. */ 44 | for (t = 0; t < num_iters; t++) { 45 | int x, y; 46 | for (y = 0; y < num_blocksY * blocksize; y++) { 47 | for (x = 0; x < num_blocksX * blocksize; x++) { 48 | values_new[INDEX(x, y)] = 49 | values_old[INDEX(x, y)] * (1.0 / 2.0) + 50 | (values_old[INDEX(x + 1, y)] + values_old[INDEX(x - 1, y)] + 51 | values_old[INDEX(x, y + 1)] + 52 | values_old[INDEX(x, y - 1)]) * 53 | (1.0 / 8.0); 54 | } 55 | } 56 | /* Swap values_old and values_new. */ 57 | double *values_tmp = values_new; 58 | values_new = values_old; 59 | values_old = values_tmp; 60 | } 61 | 62 | /* Validate results. values_old has the latest values. */ 63 | int validate_ret = 0; 64 | if (validate) { 65 | validate_ret = validate_values(values_old, num_blocksX, num_blocksY, 66 | blocksize, num_iters); 67 | } 68 | 69 | /* Free allocated memory. */ 70 | free(values_old); 71 | free(values_new); 72 | 73 | if (validate_ret != 0) { 74 | printf("Validation failed.\n"); 75 | return -1; 76 | } else if (validate) { 77 | printf("Validation succeeded.\n"); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /examples/stencil/stencil_seq.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | /* 7 | * Base implementation: stencil_naive.c 8 | * 9 | * Single-threaded 2D stencil code. The does the same computation as does 10 | * stencil_naive. However, the programmer can easily parallelize this version 11 | * (compared with stencil_naive.c) since the kernel is computed per block. 12 | * Particularly, one needs to parallelize the execution of kernel(). 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include "stencil_helper.h" 19 | 20 | /* Global variables. */ 21 | int num_blocksX, num_blocksY; 22 | int blocksize; 23 | int num_iters; 24 | int num_xstreams; 25 | int validate; 26 | 27 | typedef struct { 28 | double *values_old; 29 | double *values_new; 30 | int blockX; 31 | int blockY; 32 | } kernel_arg_t; 33 | 34 | void kernel(void *arg) 35 | { 36 | int x, y; 37 | double *values_old = ((kernel_arg_t *)arg)->values_old; 38 | double *values_new = ((kernel_arg_t *)arg)->values_new; 39 | int blockX = ((kernel_arg_t *)arg)->blockX; 40 | int blockY = ((kernel_arg_t *)arg)->blockY; 41 | for (y = blockY * blocksize; y < (blockY + 1) * blocksize; y++) { 42 | for (x = blockX * blocksize; x < (blockX + 1) * blocksize; x++) { 43 | values_new[INDEX(x, y)] = 44 | values_old[INDEX(x, y)] * (1.0 / 2.0) + 45 | (values_old[INDEX(x + 1, y)] + values_old[INDEX(x - 1, y)] + 46 | values_old[INDEX(x, y + 1)] + values_old[INDEX(x, y - 1)]) * 47 | (1.0 / 8.0); 48 | } 49 | } 50 | } 51 | 52 | int main(int argc, char **argv) 53 | { 54 | int t; 55 | /* Read arguments. */ 56 | int read_arg_ret = 57 | read_args(argc, argv, &num_blocksX, &num_blocksY, &blocksize, 58 | &num_iters, &num_xstreams, &validate); 59 | if (read_arg_ret != 0) { 60 | return -1; 61 | } 62 | 63 | /* Allocate memory. */ 64 | double *values_old = (double *)malloc(sizeof(double) * WIDTH * HEIGHT); 65 | double *values_new = (double *)malloc(sizeof(double) * WIDTH * HEIGHT); 66 | kernel_arg_t *kernel_args = (kernel_arg_t *)malloc( 67 | sizeof(kernel_arg_t) * num_blocksX * num_blocksY); 68 | 69 | /* Initialize grid values. */ 70 | init_values(values_old, values_new, num_blocksX, num_blocksY, blocksize); 71 | 72 | /* Main iteration loop. */ 73 | for (t = 0; t < num_iters; t++) { 74 | int blockX, blockY; 75 | for (blockX = 0; blockX < num_blocksX; blockX++) { 76 | for (blockY = 0; blockY < num_blocksY; blockY++) { 77 | kernel_arg_t *p_kernel_arg = 78 | &kernel_args[blockX + blockY * num_blocksX]; 79 | p_kernel_arg->values_old = values_old; 80 | p_kernel_arg->values_new = values_new; 81 | p_kernel_arg->blockX = blockX; 82 | p_kernel_arg->blockY = blockY; 83 | kernel(p_kernel_arg); 84 | } 85 | } 86 | /* Swap values_old and values_new. */ 87 | double *values_tmp = values_new; 88 | values_new = values_old; 89 | values_old = values_tmp; 90 | } 91 | 92 | /* Validate results. values_old has the latest values. */ 93 | int validate_ret = 0; 94 | if (validate) { 95 | validate_ret = validate_values(values_old, num_blocksX, num_blocksY, 96 | blocksize, num_iters); 97 | } 98 | 99 | /* Free allocated memory. */ 100 | free(values_old); 101 | free(values_new); 102 | free(kernel_args); 103 | 104 | if (validate_ret != 0) { 105 | printf("Validation failed.\n"); 106 | return -1; 107 | } else if (validate) { 108 | printf("Validation succeeded.\n"); 109 | } 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /m4/aclocal.m4: -------------------------------------------------------------------------------- 1 | dnl This version of aclocal.m4 simply includes all of the individual 2 | dnl components 3 | builtin(include,aclocal_cc.m4) 4 | builtin(include,aclocal_runlog.m4) 5 | builtin(include,aclocal_check_visibility.m4) 6 | builtin(include,aclocal_util.m4) 7 | builtin(include,ax_gcc_func_attribute.m4) 8 | builtin(include,ax_gcc_builtin.m4) 9 | -------------------------------------------------------------------------------- /m4/aclocal_util.m4: -------------------------------------------------------------------------------- 1 | dnl Nesting safe macros for saving variables 2 | dnl Usage: PAC_PUSH_FLAG(CFLAGS) 3 | AC_DEFUN([PAC_PUSH_FLAG],[ 4 | if test -z "${pac_save_$1_nesting}" ; then 5 | pac_save_$1_nesting=0 6 | fi 7 | eval pac_save_$1_${pac_save_$1_nesting}='"$$1"' 8 | pac_save_$1_nesting=`expr ${pac_save_$1_nesting} + 1` 9 | ]) 10 | 11 | dnl Usage: PAC_POP_FLAG(CFLAGS) 12 | AC_DEFUN([PAC_POP_FLAG],[ 13 | pac_save_$1_nesting=`expr ${pac_save_$1_nesting} - 1` 14 | eval $1="\$pac_save_$1_${pac_save_$1_nesting}" 15 | eval pac_save_$1_${pac_save_$1_nesting}="" 16 | ]) 17 | 18 | dnl Usage: PAC_APPEND_FLAG([-02], [CFLAGS]) 19 | dnl appends the given argument to the specified shell variable unless the 20 | dnl argument is already present in the variable 21 | AC_DEFUN([PAC_APPEND_FLAG],[ 22 | AC_REQUIRE([AC_PROG_FGREP]) 23 | AS_IF( 24 | [echo "$$2" | $FGREP -e '$1' >/dev/null 2>&1], 25 | [echo "$2(='$$2') contains '$1', not appending" >&AS_MESSAGE_LOG_FD], 26 | [echo "$2(='$$2') does not contain '$1', appending" >&AS_MESSAGE_LOG_FD 27 | $2="$$2 $1"] 28 | ) 29 | ]) 30 | 31 | dnl Usage: PAC_PREPEND_FLAG([-lpthread], [LIBS]) 32 | dnl Prepends the given argument to the specified shell variable unless the 33 | dnl argument is already present in the variable. 34 | dnl 35 | dnl This is typically used for LIBS and similar variables because libraries 36 | dnl should be added in reverse order. 37 | AC_DEFUN([PAC_PREPEND_FLAG],[ 38 | AC_REQUIRE([AC_PROG_FGREP]) 39 | AS_IF( 40 | [echo "$$2" | $FGREP -e '$1' >/dev/null 2>&1], 41 | [echo "$2(='$$2') contains '$1', not prepending" >&AS_MESSAGE_LOG_FD], 42 | [echo "$2(='$$2') does not contain '$1', prepending" >&AS_MESSAGE_LOG_FD 43 | $2="$1 $$2"] 44 | ) 45 | ]) 46 | -------------------------------------------------------------------------------- /maint/Version.base.m4: -------------------------------------------------------------------------------- 1 | dnl 2 | dnl this m4 file expects to be processed with "autom4te -l M4sugar" 3 | dnl 4 | m4_init 5 | 6 | dnl get the real version values 7 | m4_include([maint/version.m4])dnl 8 | 9 | dnl The m4sugar language switches the default diversion to "KILL", and causes 10 | dnl all normal output to be thrown away. We switch to the default (0) diversion 11 | dnl to restore output. 12 | m4_divert_push([])dnl 13 | dnl 14 | dnl now dump out a shell script header for those looking to change the version string 15 | # This shell script is no longer the canonical version number script, but rather 16 | # a byproduct of running ./maint/updatefiles using maint/Version.base.m4 as 17 | # input. The real version info is contained in maint/version.m4 instead. It is 18 | # intentionally not managed by the makefile system and may not be up to date at 19 | # all times w.r.t. the version.m4 file. 20 | 21 | dnl now provide shell versions so that simple scripts can still use 22 | dnl $ABT_VERSION as before 23 | ABT_VERSION=ABT_VERSION_m4 24 | export ABT_VERSION 25 | 26 | dnl balance our pushed diversion 27 | m4_divert_pop([])dnl 28 | -------------------------------------------------------------------------------- /maint/argobots.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Argobots 7 | Description: A Lightweight Low-level Threading/Tasking Framework 8 | Version: @ABT_VERSION@ 9 | URL: http://www.argobots.org/ 10 | Requires: 11 | Libs: -L${libdir} -labt 12 | Libs.private: @LIBS@ 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /maint/code-cleanup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # clang-format-6.0 and above versions are recommended. 4 | # * clang-format < 3.9 cannot be used since SortIncludes is not supported. 5 | # SortIncludes must be disabled since abti.h depends on the order of #include. 6 | 7 | indent_list="clang-format-10 clang-format-9.0 clang-format-8.0 clang-format-7.0 \ 8 | clang-format-6.0 clang-format clang-format-5.0 clang-format-4.0 \ 9 | clang-format-3.9" 10 | 11 | is_find_indent=0 12 | for indent in $indent_list; do 13 | if test ! -z "`which $indent`" ; then 14 | is_find_indent=1 15 | break 16 | fi 17 | done 18 | if [ "is_find_indent" = "x0" ]; then 19 | echo "clang-format is not found." 20 | exit 1 21 | fi 22 | 23 | indent_code() 24 | { 25 | file=$1 26 | if [[ "$file" == *"abt.h.in" ]]; then 27 | return 28 | fi 29 | $indent --style="{BasedOnStyle: llvm, \ 30 | BreakBeforeBraces: WebKit, \ 31 | IndentWidth: 4, \ 32 | Cpp11BracedListStyle: false, \ 33 | IndentCaseLabels: true, \ 34 | AlignAfterOpenBracket: Align, \ 35 | SortIncludes: false, \ 36 | AllowShortFunctionsOnASingleLine : None, \ 37 | PenaltyBreakBeforeFirstCallParameter: 100000, 38 | SpacesInContainerLiterals: false}" \ 39 | -i ${file} 40 | } 41 | 42 | usage() 43 | { 44 | echo "Usage: $1 [filename | --all] {--recursive} {--debug}" 45 | echo "Example 1: format a single file (e.g., src/thread.c)" 46 | echo " $1 src/thread.c" 47 | echo "Example 2: recursively find all files and format them" 48 | echo " $1 --all --recursive" 49 | } 50 | 51 | # Check usage 52 | if [ -z "$1" ]; then 53 | usage $0 54 | exit 55 | fi 56 | 57 | # Make sure the parameters make sense 58 | all=0 59 | recursive=0 60 | got_file=0 61 | debug= 62 | ignore=0 63 | ignore_list="__I_WILL_NEVER_FIND_YOU__" 64 | for arg in $@; do 65 | if [ "$ignore" = "1" ] ; then 66 | ignore_list="$ignore_list|$arg" 67 | ignore=0 68 | continue; 69 | fi 70 | 71 | if [ "$arg" = "--all" ]; then 72 | all=1 73 | elif [ "$arg" = "--recursive" ]; then 74 | recursive=1 75 | elif [ "$arg" = "--debug" ]; then 76 | debug="echo" 77 | elif [ "$arg" = "--ignore" ] ; then 78 | ignore=1 79 | else 80 | got_file=1 81 | fi 82 | done 83 | 84 | if [ "$recursive" = "1" -a "$all" = "0" ]; then 85 | echo "--recursive cannot be used without --all" 86 | usage $0 87 | exit 88 | fi 89 | 90 | if [ "$got_file" = "1" -a "$all" = "1" ]; then 91 | echo "--all cannot be used in conjunction with a specific file" 92 | usage $0 93 | exit 94 | fi 95 | 96 | if [ "x$debug" != "x" ]; then 97 | echo "Use $indent (`$indent --version`)" 98 | fi 99 | 100 | if [ "$recursive" = "1" ]; then 101 | for i in `find . \! -type d | egrep '(\.c$|\.h$|\.c\.in$|\.h\.in$|\.cpp$|\.cpp.in$)' | \ 102 | egrep -v "($ignore_list)"` ; do 103 | ${debug} indent_code $i 104 | done 105 | elif [ "$all" = "1" ]; then 106 | for i in `find . -maxdepth 1 \! -type d | egrep '(\.c$|\.h$|\.c\.in$|\.h\.in$|\.cpp$|\.cpp.in$)' | \ 107 | egrep -v "($ignore_list)"` ; do 108 | ${debug} indent_code $i 109 | done 110 | else 111 | ${debug} indent_code $@ 112 | fi 113 | -------------------------------------------------------------------------------- /maint/hook/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=$(git merge-base --fork-point main) 13 | else 14 | # Initial commit: diff against an git hash-object -t tree /dev/nullempty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ASCII filenames set this variable to true. 19 | allownonascii=$(git config --bool hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ASCII filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if test $(git diff --cached --name-only --diff-filter=A -z $against | 28 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 29 | then 30 | cat <<\EOF 31 | Error: Attempt to add a non-ASCII file name. 32 | EOF 33 | exit 1 34 | fi 35 | 36 | MIRROR=/tmp/${USER}/argobots-tmp-mirror 37 | TMP_FILENAME=/tmp/${USER}/argobots-tmp-file 38 | 39 | # Checkout a copy of the current index into MIRROR 40 | git checkout-index --prefix=$MIRROR/ -af 41 | 42 | # Remove files from MIRROR which are no longer present in the index 43 | git diff-index --cached --name-only --diff-filter=D -z $against | \ 44 | (cd $MIRROR && xargs -0 rm -f --) 45 | 46 | # This will check the previous commit again when not amending a commit, but that 47 | # should be ok if the patches are correct. 48 | filestring=`git diff --cached --name-only --diff-filter=ACM $against` 49 | 50 | # Everything else happens in the temporary build tree 51 | pushd $MIRROR > /dev/null 52 | 53 | ret=0 54 | 55 | # This won't work if we ever have a file with a space in the name 56 | for file in $filestring 57 | do 58 | if [[ ($file == *.c || $file == *.h || $file == *.c.in || $file == *.h.in) 59 | && !($file == *abt.h.in) ]]; then 60 | cp ${file} ${TMP_FILENAME} 61 | maint/code-cleanup.sh ${file} 62 | git --no-pager diff ${TMP_FILENAME} ${file} 63 | if [ $? != 0 ] ; then 64 | ret=1 65 | fi 66 | fi 67 | done 68 | 69 | rm -rf ${MIRROR} ${TMP_FILENAME} 70 | 71 | if [ $ret != 0 ] ; then 72 | RED='\033[0;31m' 73 | NC='\033[0m' # No Color 74 | echo -e "${RED}== CODE CLEANUP SCRIPT FAILED ==${NC}" 75 | exit $ret 76 | fi 77 | -------------------------------------------------------------------------------- /maint/spellcheck.bash: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | ## 3 | ## Copyright (C) by Argonne National Laboratory 4 | ## See COPYRIGHT in top-level directory 5 | ## 6 | 7 | IGNORE_WORDS="inout,cas,ans,numer" 8 | SKIP_FILES=".git,*.tex,*.bib,*.sty,*.f,confdb/config.*,*.png,*.rpath,*.m4" 9 | codespell --ignore-words-list="${IGNORE_WORDS}" --skip="${SKIP_FILES}" 10 | -------------------------------------------------------------------------------- /maint/template.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | 8 | int ABTI_template(ABTI_ythread *p_thread, void *p_arg) 9 | { 10 | int abt_errno = ABT_SUCCESS; 11 | 12 | if (p_thread == NULL) { 13 | HANDLE_ERROR("NULL THREAD"); 14 | abt_errno = ABT_ERR_INV_THREAD; 15 | goto fn_fail; 16 | } 17 | 18 | /* Implementation */ 19 | /* ... */ 20 | 21 | fn_exit: 22 | return abt_errno; 23 | 24 | fn_fail: 25 | goto fn_exit; 26 | } 27 | -------------------------------------------------------------------------------- /maint/version.m4: -------------------------------------------------------------------------------- 1 | [#] start of __file__ 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | m4_define([ABT_VERSION_m4],[1.2rc1])dnl 7 | m4_define([ABT_RELEASE_DATE_m4],[unreleased development copy])dnl 8 | 9 | # For libtool ABI versioning rules see: 10 | # http://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info 11 | # 12 | # 1. If the library source code has changed at all since the last 13 | # update, then increment revision (`c:r:a' becomes `c:r+1:a'). 14 | # 15 | # 2. If any interfaces have been added, removed, or changed since 16 | # the last update, increment current, and set revision to 0. 17 | # 18 | # 3. If any interfaces have been added since the last public 19 | # release, then increment age. 20 | # 21 | # 4. If any interfaces have been removed since the last public 22 | # release, then set age to 0. 23 | 24 | m4_define([libabt_so_version_m4],[2:0:1])dnl 25 | 26 | [#] end of __file__ 27 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources = \ 7 | barrier.c \ 8 | cond.c \ 9 | error.c \ 10 | eventual.c \ 11 | futures.c \ 12 | global.c \ 13 | info.c \ 14 | key.c \ 15 | local.c \ 16 | log.c \ 17 | mutex.c \ 18 | mutex_attr.c \ 19 | rwlock.c \ 20 | self.c \ 21 | stream.c \ 22 | stream_barrier.c \ 23 | task.c \ 24 | thread.c \ 25 | thread_attr.c \ 26 | timer.c \ 27 | tool.c \ 28 | unit.c \ 29 | ythread.c 30 | 31 | include $(top_srcdir)/src/arch/Makefile.mk 32 | include $(top_srcdir)/src/mem/Makefile.mk 33 | include $(top_srcdir)/src/pool/Makefile.mk 34 | include $(top_srcdir)/src/sched/Makefile.mk 35 | include $(top_srcdir)/src/util/Makefile.mk 36 | 37 | include $(top_srcdir)/src/include/Makefile.mk 38 | 39 | lib_LTLIBRARIES = libabt.la 40 | libabt_la_SOURCES = $(abt_sources) 41 | libabt_la_CPPFLAGS = -I$(top_srcdir)/src/include @ABT_VISIBILITY_CFLAGS@ 42 | libabt_la_CCASFLAGS = -I$(top_srcdir)/src/include @ABT_VISIBILITY_CFLAGS@ 43 | libabt_la_LDFLAGS = -version-info @libabt_so_version@ 44 | 45 | -------------------------------------------------------------------------------- /src/arch/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources += \ 7 | arch/abtd_affinity.c \ 8 | arch/abtd_affinity_parser.c \ 9 | arch/abtd_env.c \ 10 | arch/abtd_futex.c \ 11 | arch/abtd_stream.c \ 12 | arch/abtd_time.c \ 13 | arch/abtd_ythread.c 14 | 15 | if ABT_USE_FCONTEXT 16 | abt_sources += \ 17 | arch/fcontext/fcontext_@fctx_arch_bin@.S 18 | endif 19 | -------------------------------------------------------------------------------- /src/arch/abtd_time.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | 8 | #if defined(ABT_CONFIG_USE_MACH_ABSOLUTE_TIME) 9 | static double g_time_mult = 0.0; 10 | #endif 11 | void ABTD_time_init(void) 12 | { 13 | #if defined(ABT_CONFIG_USE_MACH_ABSOLUTE_TIME) 14 | mach_timebase_info_data_t info; 15 | mach_timebase_info(&info); 16 | g_time_mult = 1.0e-9 * ((double)info.numer / (double)info.denom); 17 | #endif 18 | } 19 | 20 | /* Obtain the time value */ 21 | void ABTD_time_get(ABTD_time *p_time) 22 | { 23 | #if defined(ABT_CONFIG_USE_CLOCK_GETTIME) 24 | int ret = clock_gettime(CLOCK_REALTIME, p_time); 25 | ABTI_ASSERT(ret == 0); 26 | #elif defined(ABT_CONFIG_USE_MACH_ABSOLUTE_TIME) 27 | *p_time = mach_absolute_time(); 28 | #elif defined(ABT_CONFIG_USE_GETTIMEOFDAY) 29 | int ret = gettimeofday(p_time, NULL); 30 | ABTI_ASSERT(ret == 0); 31 | #endif 32 | } 33 | 34 | /* Read the time value as seconds (double precision) */ 35 | double ABTD_time_read_sec(ABTD_time *p_time) 36 | { 37 | double secs; 38 | 39 | #if defined(ABT_CONFIG_USE_CLOCK_GETTIME) 40 | secs = ((double)p_time->tv_sec) + 1.0e-9 * ((double)p_time->tv_nsec); 41 | #elif defined(ABT_CONFIG_USE_MACH_ABSOLUTE_TIME) 42 | if (g_time_mult == 0.0) 43 | ABTD_time_init(); 44 | secs = *p_time * g_time_mult; 45 | #elif defined(ABT_CONFIG_USE_GETTIMEOFDAY) 46 | secs = ((double)p_time->tv_sec) + 1.0e-6 * ((double)p_time->tv_usec); 47 | #endif 48 | 49 | return secs; 50 | } 51 | -------------------------------------------------------------------------------- /src/arch/abtd_ythread.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | 8 | void ABTD_ythread_func_wrapper(ABTD_ythread_context *p_arg) 9 | { 10 | ABTD_ythread_context *p_ctx = p_arg; 11 | ABTI_ythread *p_ythread = ABTI_ythread_context_get_ythread(p_ctx); 12 | p_ythread->thread.f_thread(p_ythread->thread.p_arg); 13 | 14 | ABTI_xstream *p_local_xstream = p_ythread->thread.p_last_xstream; 15 | ABTI_ythread_exit(p_local_xstream, p_ythread); 16 | } 17 | 18 | void ABTD_ythread_print_context(ABTI_ythread *p_ythread, FILE *p_os, int indent) 19 | { 20 | ABTD_ythread_context *p_ctx = &p_ythread->ctx; 21 | fprintf(p_os, "%*sp_ctx : %p\n", indent, "", (void *)p_ctx); 22 | fprintf(p_os, "%*sp_link : %p\n", indent, "", 23 | (void *)ABTD_atomic_acquire_load_ythread_context_ptr( 24 | &p_ctx->p_link)); 25 | fflush(p_os); 26 | } 27 | -------------------------------------------------------------------------------- /src/arch/fcontext/LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/include/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | include_HEADERS = include/abt.h 7 | 8 | noinst_HEADERS = \ 9 | include/abt_config.h \ 10 | include/abtd.h \ 11 | include/abtd_atomic.h \ 12 | include/abtd_context.h \ 13 | include/abtd_fcontext.h \ 14 | include/abtd_futex.h \ 15 | include/abtd_spinlock.h \ 16 | include/abtd_ucontext.h \ 17 | include/abti.h \ 18 | include/abti_barrier.h \ 19 | include/abti_cond.h \ 20 | include/abti_error.h \ 21 | include/abti_event.h \ 22 | include/abti_eventual.h \ 23 | include/abti_future.h \ 24 | include/abti_global.h \ 25 | include/abti_key.h \ 26 | include/abti_local.h \ 27 | include/abti_log.h \ 28 | include/abti_mem.h \ 29 | include/abti_mem_pool.h \ 30 | include/abti_mutex.h \ 31 | include/abti_mutex_attr.h \ 32 | include/abti_rwlock.h \ 33 | include/abti_pool.h \ 34 | include/abti_pool_config.h \ 35 | include/abti_pool_user_def.h \ 36 | include/abti_sched.h \ 37 | include/abti_sched_config.h \ 38 | include/abti_self.h \ 39 | include/abti_stream.h \ 40 | include/abti_stream_barrier.h \ 41 | include/abti_sync_lifo.h \ 42 | include/abti_timer.h \ 43 | include/abti_unit.h \ 44 | include/abti_thread.h \ 45 | include/abti_thread_attr.h \ 46 | include/abti_waitlist.h \ 47 | include/abti_tool.h \ 48 | include/abti_valgrind.h \ 49 | include/abti_ythread.h \ 50 | include/abtu.h 51 | -------------------------------------------------------------------------------- /src/include/abtd_context.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTD_CONTEXT_H_INCLUDED 7 | #define ABTD_CONTEXT_H_INCLUDED 8 | 9 | #include "abt_config.h" 10 | 11 | #ifndef ABT_CONFIG_USE_FCONTEXT 12 | #ifndef _XOPEN_SOURCE 13 | #define _XOPEN_SOURCE 14 | #endif 15 | #include 16 | #endif 17 | 18 | typedef struct ABTD_ythread_context ABTD_ythread_context; 19 | 20 | typedef struct ABTD_ythread_context_atomic_ptr { 21 | ABTD_atomic_ptr val; 22 | } ABTD_ythread_context_atomic_ptr; 23 | 24 | static inline ABTD_ythread_context * 25 | ABTD_atomic_relaxed_load_ythread_context_ptr( 26 | const ABTD_ythread_context_atomic_ptr *ptr) 27 | { 28 | return (ABTD_ythread_context *)ABTD_atomic_relaxed_load_ptr(&ptr->val); 29 | } 30 | 31 | static inline ABTD_ythread_context * 32 | ABTD_atomic_acquire_load_ythread_context_ptr( 33 | const ABTD_ythread_context_atomic_ptr *ptr) 34 | { 35 | return (ABTD_ythread_context *)ABTD_atomic_acquire_load_ptr(&ptr->val); 36 | } 37 | 38 | static inline void ABTD_atomic_relaxed_store_ythread_context_ptr( 39 | ABTD_ythread_context_atomic_ptr *ptr, ABTD_ythread_context *p_ctx) 40 | { 41 | ABTD_atomic_relaxed_store_ptr(&ptr->val, (void *)p_ctx); 42 | } 43 | 44 | static inline void ABTD_atomic_release_store_ythread_context_ptr( 45 | ABTD_ythread_context_atomic_ptr *ptr, ABTD_ythread_context *p_ctx) 46 | { 47 | ABTD_atomic_release_store_ptr(&ptr->val, (void *)p_ctx); 48 | } 49 | 50 | void ABTD_ythread_func_wrapper(ABTD_ythread_context *p_arg); 51 | void ABTD_ythread_print_context(ABTI_ythread *p_ythread, FILE *p_os, 52 | int indent); 53 | 54 | #ifdef ABT_CONFIG_USE_FCONTEXT 55 | #include "abtd_fcontext.h" 56 | #else 57 | #include "abtd_ucontext.h" 58 | #endif 59 | 60 | #endif /* ABTD_CONTEXT_H_INCLUDED */ 61 | -------------------------------------------------------------------------------- /src/include/abtd_futex.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTD_FUTEX_H_INCLUDED 7 | #define ABTD_FUTEX_H_INCLUDED 8 | 9 | #ifndef ABT_CONFIG_ACTIVE_WAIT_POLICY 10 | 11 | /* ABTD_futex_multiple supports a wait-broadcast pattern. ABTD_futex_multiple 12 | * allows multiple waiters. */ 13 | typedef struct ABTD_futex_multiple ABTD_futex_multiple; 14 | 15 | /* Initialize ABTD_futex_multiple. */ 16 | static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex); 17 | 18 | /* This routine unlocks p_lock and makes the underlying Pthread block on 19 | * p_futex. Broadcast can wake up this waiter. Spurious wakeup does not 20 | * happen. */ 21 | void ABTD_futex_wait_and_unlock(ABTD_futex_multiple *p_futex, 22 | ABTD_spinlock *p_lock); 23 | 24 | /* This routine unlocks p_lock and makes the underlying Pthread block on 25 | * p_futex. Broadcast can wake up this waiter. By nature, spurious wakeup 26 | * might happen, so the caller needs to check the current time if necessary. */ 27 | void ABTD_futex_timedwait_and_unlock(ABTD_futex_multiple *p_futex, 28 | ABTD_spinlock *p_lock, 29 | double wait_time_sec); 30 | 31 | /* This routine wakes up waiters that are waiting on p_futex. This function 32 | * must be called when a lock (p_lock above) is taken. */ 33 | void ABTD_futex_broadcast(ABTD_futex_multiple *p_futex); 34 | 35 | /* ABTD_futex_single supports a suspend-resume pattern. ABTD_futex_single 36 | * allows only a single waiter. */ 37 | typedef struct ABTD_futex_single ABTD_futex_single; 38 | 39 | /* Initialize ABTD_futex_single. */ 40 | static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex); 41 | 42 | /* This routine suspends the underlying Pthread. Only one thread can suspend 43 | * on a single p_futex. This suspended thread must be woken up by 44 | * ABTD_futex_resume(). Spurious wakeup does not happen. 45 | * 46 | * p_futex must be new; it may not have been used after initialization. */ 47 | void ABTD_futex_suspend(ABTD_futex_single *p_futex); 48 | 49 | /* This routine wakes up a Pthread suspended by ABTD_futex_suspend(). This 50 | * routine blocks if no Pthread is waiting on p_futex. */ 51 | void ABTD_futex_resume(ABTD_futex_single *p_futex); 52 | 53 | #ifdef ABT_CONFIG_USE_LINUX_FUTEX 54 | 55 | struct ABTD_futex_multiple { 56 | ABTD_atomic_int val; 57 | }; 58 | 59 | static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex) 60 | { 61 | ABTD_atomic_relaxed_store_int(&p_futex->val, 0); 62 | } 63 | 64 | struct ABTD_futex_single { 65 | ABTD_atomic_int val; 66 | }; 67 | 68 | static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex) 69 | { 70 | ABTD_atomic_relaxed_store_int(&p_futex->val, 0); 71 | } 72 | 73 | #else /* ABT_CONFIG_USE_LINUX_FUTEX */ 74 | 75 | struct ABTD_futex_multiple { 76 | void *p_next; /* pthread_sync */ 77 | }; 78 | 79 | static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex) 80 | { 81 | p_futex->p_next = NULL; 82 | } 83 | 84 | struct ABTD_futex_single { 85 | ABTD_atomic_ptr p_sync_obj; 86 | }; 87 | 88 | static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex) 89 | { 90 | ABTD_atomic_relaxed_store_ptr(&p_futex->p_sync_obj, NULL); 91 | } 92 | 93 | #endif /* !ABT_CONFIG_USE_LINUX_FUTEX */ 94 | 95 | #endif /* !ABT_CONFIG_ACTIVE_WAIT_POLICY */ 96 | 97 | #endif /* ABTD_FUTEX_H_INCLUDED */ 98 | -------------------------------------------------------------------------------- /src/include/abtd_spinlock.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTD_SPINLOCK_H_INCLUDED 7 | #define ABTD_SPINLOCK_H_INCLUDED 8 | 9 | typedef struct ABTD_spinlock { 10 | ABTD_atomic_bool val; 11 | } ABTD_spinlock; 12 | 13 | #define ABTD_SPINLOCK_STATIC_INITIALIZER() \ 14 | { \ 15 | ABTD_ATOMIC_BOOL_STATIC_INITIALIZER(0) \ 16 | } 17 | 18 | static inline ABT_bool ABTD_spinlock_is_locked(const ABTD_spinlock *p_lock) 19 | { 20 | return ABTD_atomic_acquire_load_bool(&p_lock->val); 21 | } 22 | 23 | static inline void ABTD_spinlock_clear(ABTD_spinlock *p_lock) 24 | { 25 | ABTD_atomic_relaxed_clear_bool(&p_lock->val); 26 | } 27 | 28 | static inline void ABTD_spinlock_acquire(ABTD_spinlock *p_lock) 29 | { 30 | while (ABTD_atomic_test_and_set_bool(&p_lock->val)) { 31 | while (ABTD_spinlock_is_locked(p_lock) != ABT_FALSE) 32 | ; 33 | } 34 | } 35 | 36 | /* Return ABT_FALSE if the lock is acquired. */ 37 | static inline ABT_bool ABTD_spinlock_try_acquire(ABTD_spinlock *p_lock) 38 | { 39 | return ABTD_atomic_test_and_set_bool(&p_lock->val) ? ABT_TRUE : ABT_FALSE; 40 | } 41 | 42 | static inline void ABTD_spinlock_release(ABTD_spinlock *p_lock) 43 | { 44 | ABTD_atomic_release_clear_bool(&p_lock->val); 45 | } 46 | 47 | #endif /* ABTD_SPINLOCK_H_INCLUDED */ 48 | -------------------------------------------------------------------------------- /src/include/abtd_stream.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTD_STREAM_H_INCLUDED 7 | #define ABTD_STREAM_H_INCLUDED 8 | 9 | #ifdef HAVE_PTHREAD_BARRIER_INIT 10 | ABTU_ret_err static inline int 11 | ABTD_xstream_barrier_init(uint32_t num_waiters, ABTD_xstream_barrier *p_barrier) 12 | { 13 | int ret = pthread_barrier_init(p_barrier, NULL, num_waiters); 14 | return (ret == 0) ? ABT_SUCCESS : ABT_ERR_XSTREAM_BARRIER; 15 | } 16 | 17 | static inline void ABTD_xstream_barrier_destroy(ABTD_xstream_barrier *p_barrier) 18 | { 19 | int ret = pthread_barrier_destroy(p_barrier); 20 | ABTI_ASSERT(ret == 0); 21 | } 22 | 23 | static inline void ABTD_xstream_barrier_wait(ABTD_xstream_barrier *p_barrier) 24 | { 25 | int ret = pthread_barrier_wait(p_barrier); 26 | ABTI_ASSERT(ret == PTHREAD_BARRIER_SERIAL_THREAD || ret == 0); 27 | } 28 | #endif 29 | 30 | #endif /* ABTD_STREAM_H_INCLUDED */ 31 | -------------------------------------------------------------------------------- /src/include/abti_barrier.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_BARRIER_H_INCLUDED 7 | #define ABTI_BARRIER_H_INCLUDED 8 | 9 | /* Inlined functions for Barrier */ 10 | 11 | /* Barrier */ 12 | static inline ABTI_barrier *ABTI_barrier_get_ptr(ABT_barrier barrier) 13 | { 14 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 15 | ABTI_barrier *p_barrier; 16 | if (barrier == ABT_BARRIER_NULL) { 17 | p_barrier = NULL; 18 | } else { 19 | p_barrier = (ABTI_barrier *)barrier; 20 | } 21 | return p_barrier; 22 | #else 23 | return (ABTI_barrier *)barrier; 24 | #endif 25 | } 26 | 27 | static inline ABT_barrier ABTI_barrier_get_handle(ABTI_barrier *p_barrier) 28 | { 29 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 30 | ABT_barrier h_barrier; 31 | if (p_barrier == NULL) { 32 | h_barrier = ABT_BARRIER_NULL; 33 | } else { 34 | h_barrier = (ABT_barrier)p_barrier; 35 | } 36 | return h_barrier; 37 | #else 38 | return (ABT_barrier)p_barrier; 39 | #endif 40 | } 41 | 42 | #endif /* ABTI_BARRIER_H_INCLUDED */ 43 | -------------------------------------------------------------------------------- /src/include/abti_cond.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_COND_H_INCLUDED 7 | #define ABTI_COND_H_INCLUDED 8 | 9 | #include "abti_mutex.h" 10 | 11 | /* Inlined functions for Condition Variable */ 12 | 13 | static inline void ABTI_cond_init(ABTI_cond *p_cond) 14 | { 15 | ABTD_spinlock_clear(&p_cond->lock); 16 | p_cond->p_waiter_mutex = NULL; 17 | ABTI_waitlist_init(&p_cond->waitlist); 18 | } 19 | 20 | static inline void ABTI_cond_fini(ABTI_cond *p_cond) 21 | { 22 | /* The lock needs to be acquired to safely free the condition structure. 23 | * However, we do not have to unlock it because the entire structure is 24 | * freed here. */ 25 | ABTD_spinlock_acquire(&p_cond->lock); 26 | ABTI_UB_ASSERT(ABTI_waitlist_is_empty(&p_cond->waitlist)); 27 | } 28 | 29 | static inline ABTI_cond *ABTI_cond_get_ptr(ABT_cond cond) 30 | { 31 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 32 | ABTI_cond *p_cond; 33 | if (cond == ABT_COND_NULL) { 34 | p_cond = NULL; 35 | } else { 36 | p_cond = (ABTI_cond *)cond; 37 | } 38 | return p_cond; 39 | #else 40 | return (ABTI_cond *)cond; 41 | #endif 42 | } 43 | 44 | static inline ABT_cond ABTI_cond_get_handle(ABTI_cond *p_cond) 45 | { 46 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 47 | ABT_cond h_cond; 48 | if (p_cond == NULL) { 49 | h_cond = ABT_COND_NULL; 50 | } else { 51 | h_cond = (ABT_cond)p_cond; 52 | } 53 | return h_cond; 54 | #else 55 | return (ABT_cond)p_cond; 56 | #endif 57 | } 58 | 59 | ABTU_ret_err static inline int 60 | ABTI_cond_wait(ABTI_local **pp_local, ABTI_cond *p_cond, ABTI_mutex *p_mutex) 61 | { 62 | ABTD_spinlock_acquire(&p_cond->lock); 63 | 64 | if (p_cond->p_waiter_mutex == NULL) { 65 | p_cond->p_waiter_mutex = p_mutex; 66 | } else { 67 | if (p_cond->p_waiter_mutex != p_mutex) { 68 | ABTD_spinlock_release(&p_cond->lock); 69 | return ABT_ERR_INV_MUTEX; 70 | } 71 | } 72 | 73 | ABTI_mutex_unlock(*pp_local, p_mutex); 74 | ABTI_waitlist_wait_and_unlock(pp_local, &p_cond->waitlist, &p_cond->lock, 75 | ABT_SYNC_EVENT_TYPE_COND, (void *)p_cond); 76 | /* Lock the mutex again */ 77 | ABTI_mutex_lock(pp_local, p_mutex); 78 | return ABT_SUCCESS; 79 | } 80 | 81 | static inline void ABTI_cond_broadcast(ABTI_local *p_local, ABTI_cond *p_cond) 82 | { 83 | ABTD_spinlock_acquire(&p_cond->lock); 84 | /* Wake up all waiting ULTs */ 85 | ABTI_waitlist_broadcast(p_local, &p_cond->waitlist); 86 | ABTD_spinlock_release(&p_cond->lock); 87 | } 88 | 89 | #endif /* ABTI_COND_H_INCLUDED */ 90 | -------------------------------------------------------------------------------- /src/include/abti_eventual.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_EVENTUAL_H_INCLUDED 7 | #define ABTI_EVENTUAL_H_INCLUDED 8 | 9 | /* Inlined functions for Eventual */ 10 | 11 | static inline ABTI_eventual *ABTI_eventual_get_ptr(ABT_eventual eventual) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_eventual *p_eventual; 15 | if (eventual == ABT_EVENTUAL_NULL) { 16 | p_eventual = NULL; 17 | } else { 18 | p_eventual = (ABTI_eventual *)eventual; 19 | } 20 | return p_eventual; 21 | #else 22 | return (ABTI_eventual *)eventual; 23 | #endif 24 | } 25 | 26 | static inline ABT_eventual ABTI_eventual_get_handle(ABTI_eventual *p_eventual) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_eventual h_eventual; 30 | if (p_eventual == NULL) { 31 | h_eventual = ABT_EVENTUAL_NULL; 32 | } else { 33 | h_eventual = (ABT_eventual)p_eventual; 34 | } 35 | return h_eventual; 36 | #else 37 | return (ABT_eventual)p_eventual; 38 | #endif 39 | } 40 | 41 | #endif /* ABTI_EVENTUAL_H_INCLUDED */ 42 | -------------------------------------------------------------------------------- /src/include/abti_future.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_FUTURE_H_INCLUDED 7 | #define ABTI_FUTURE_H_INCLUDED 8 | 9 | /* Inlined functions for Future */ 10 | 11 | static inline ABTI_future *ABTI_future_get_ptr(ABT_future future) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_future *p_future; 15 | if (future == ABT_FUTURE_NULL) { 16 | p_future = NULL; 17 | } else { 18 | p_future = (ABTI_future *)future; 19 | } 20 | return p_future; 21 | #else 22 | return (ABTI_future *)future; 23 | #endif 24 | } 25 | 26 | static inline ABT_future ABTI_future_get_handle(ABTI_future *p_future) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_future h_future; 30 | if (p_future == NULL) { 31 | h_future = ABT_FUTURE_NULL; 32 | } else { 33 | h_future = (ABT_future)p_future; 34 | } 35 | return h_future; 36 | #else 37 | return (ABT_future)p_future; 38 | #endif 39 | } 40 | 41 | #endif /* ABTI_FUTURE_H_INCLUDED */ 42 | -------------------------------------------------------------------------------- /src/include/abti_global.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_GLOBAL_H_INCLUDED 7 | #define ABTI_GLOBAL_H_INCLUDED 8 | 9 | static inline ABTI_global *ABTI_global_get_global(void) 10 | { 11 | ABTI_ASSERT(gp_ABTI_global); 12 | return gp_ABTI_global; 13 | } 14 | 15 | static inline ABTI_global *ABTI_global_get_global_or_null(void) 16 | { 17 | return gp_ABTI_global; 18 | } 19 | 20 | static inline void ABTI_global_set_global(ABTI_global *p_global) 21 | { 22 | gp_ABTI_global = p_global; 23 | } 24 | 25 | #endif /* ABTI_GLOBAL_H_INCLUDED */ 26 | -------------------------------------------------------------------------------- /src/include/abti_local.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_LOCAL_H_INCLUDED 7 | #define ABTI_LOCAL_H_INCLUDED 8 | 9 | /* 10 | * An inlined getter function for ES Local Data. This function is more 11 | * efficient than ABTI_local_get_xstream_uninlined, but it can be used once only 12 | * at the beginning of the function to avoid TLS caching across context switch. 13 | * 14 | * Consider the following case: 15 | * 16 | * int ABT_any_func() 17 | * { 18 | * ABTI_xstream *p_xstream = ABTI_local_get_xstream()->p_xstream; 19 | * [context switch (e.g., ABTI_ythread_yield())]; 20 | * ABTI_xstream *p_xstream2 = ABTI_local_get_xstream()->p_xstream; 21 | * } 22 | * 23 | * p_xstream and p_xstream2 can be always the same although context switch 24 | * changes the running execution stream because a compiler assumes that the 25 | * running Pthreads is the same across the function call 26 | * (i.e., ABTI_ythread_yield()) and caches a thread local value as a compiler 27 | * optimization. To avoid this, we need to assure that the second 28 | * ABTI_local_get_xstream() really reads the thread local value again. 29 | * 30 | * See https://github.com/pmodels/argobots/issues/55 for details. 31 | * 32 | * ABTI_local_get_xstream_uninlined() guarantees that it truly reads the thread 33 | * local value of the current Pthreads, but it is slow. 34 | * ABTI_local_get_xstream_uninlined() should be used only after context switch 35 | * happens, and in other cases, ABTI_local_get_xstream() should be called for 36 | * performance. 37 | * 38 | * If you don't understand this problem well and it is not in the critical path, 39 | * use the uninlined version for correctness. 40 | */ 41 | static inline ABTI_local *ABTI_local_get_local(void) 42 | { 43 | return lp_ABTI_local; 44 | } 45 | 46 | /* 47 | * A safe getter function for ES Local Data, which guarantees that it reads 48 | * the thread local value without referring to the cached TLS. This is slower 49 | * than ABTI_local_get_xstream(), so use ABTI_local_get_xstream() if possible. 50 | */ 51 | static inline ABTI_local *ABTI_local_get_local_uninlined(void) 52 | { 53 | return gp_ABTI_local_func.get_local_f(); 54 | } 55 | 56 | /* 57 | * A setter function for ES Local Data. This function is rarely called, so it 58 | * uses a slow version for correctness. 59 | */ 60 | static inline void ABTI_local_set_xstream(ABTI_xstream *p_local_xstream) 61 | { 62 | gp_ABTI_local_func.set_local_xstream_f(p_local_xstream); 63 | } 64 | 65 | /* 66 | * A safe getter function for a pointer to an ES Local Data, which is useful to 67 | * identify a native thread (i.e., execution streams and external threads). 68 | */ 69 | static inline void *ABTI_local_get_local_ptr(void) 70 | { 71 | return gp_ABTI_local_func.get_local_ptr_f(); 72 | } 73 | 74 | /* 75 | * A developer must be aware that p_local can be NULL. 76 | */ 77 | static inline ABTI_xstream *ABTI_local_get_xstream_or_null(ABTI_local *p_local) 78 | { 79 | return (ABTI_xstream *)p_local; 80 | } 81 | 82 | /* 83 | * This function assumes that the given p_local is not NULL (=running on an 84 | * execution stream). 85 | */ 86 | static inline ABTI_xstream *ABTI_local_get_xstream(ABTI_local *p_local) 87 | { 88 | return (ABTI_xstream *)p_local; 89 | } 90 | 91 | #endif /* ABTI_LOCAL_H_INCLUDED */ 92 | -------------------------------------------------------------------------------- /src/include/abti_log.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_LOG_H_INCLUDED 7 | #define ABTI_LOG_H_INCLUDED 8 | 9 | #include "abt_config.h" 10 | 11 | #ifdef ABT_CONFIG_USE_DEBUG_LOG 12 | 13 | void ABTI_log_debug(const char *format, ...); 14 | void ABTI_log_debug_thread(const char *msg, ABTI_thread *p_thread); 15 | void ABTI_log_pool_push(ABTI_pool *p_pool, ABT_unit unit); 16 | void ABTI_log_pool_remove(ABTI_pool *p_pool, ABT_unit unit); 17 | void ABTI_log_pool_pop(ABTI_pool *p_pool, ABT_thread thread); 18 | void ABTI_log_pool_pop_many(ABTI_pool *p_pool, const ABT_thread *threads, 19 | size_t num); 20 | void ABTI_log_pool_push_many(ABTI_pool *p_pool, const ABT_unit *units, 21 | size_t num); 22 | 23 | #define LOG_DEBUG_POOL_PUSH(p_pool, unit) ABTI_log_pool_push(p_pool, unit) 24 | #define LOG_DEBUG_POOL_REMOVE(p_pool, unit) ABTI_log_pool_remove(p_pool, unit) 25 | #define LOG_DEBUG_POOL_POP(p_pool, thread) ABTI_log_pool_pop(p_pool, thread) 26 | #define LOG_DEBUG_POOL_POP_MANY(p_pool, threads, num) \ 27 | ABTI_log_pool_pop_many(p_pool, threads, num) 28 | #define LOG_DEBUG_POOL_PUSH_MANY(p_pool, units, num) \ 29 | ABTI_log_pool_push_many(p_pool, units, num) 30 | 31 | #else 32 | 33 | #define LOG_DEBUG_POOL_PUSH(p_pool, unit) \ 34 | do { \ 35 | } while (0) 36 | #define LOG_DEBUG_POOL_REMOVE(p_pool, unit) \ 37 | do { \ 38 | } while (0) 39 | #define LOG_DEBUG_POOL_POP(p_pool, thread) \ 40 | do { \ 41 | } while (0) 42 | #define LOG_DEBUG_POOL_POP_MANY(p_pool, threads, num) \ 43 | do { \ 44 | } while (0) 45 | #define LOG_DEBUG_POOL_PUSH_MANY(p_pool, units, num) \ 46 | do { \ 47 | } while (0) 48 | 49 | #endif /* ABT_CONFIG_USE_DEBUG_LOG */ 50 | 51 | #endif /* ABTI_LOG_H_INCLUDED */ 52 | -------------------------------------------------------------------------------- /src/include/abti_mutex_attr.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_MUTEX_ATTR_H_INCLUDED 7 | #define ABTI_MUTEX_ATTR_H_INCLUDED 8 | 9 | /* Inlined functions for mutex attributes */ 10 | 11 | static inline ABTI_mutex_attr *ABTI_mutex_attr_get_ptr(ABT_mutex_attr attr) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_mutex_attr *p_attr; 15 | if (attr == ABT_MUTEX_ATTR_NULL) { 16 | p_attr = NULL; 17 | } else { 18 | p_attr = (ABTI_mutex_attr *)attr; 19 | } 20 | return p_attr; 21 | #else 22 | return (ABTI_mutex_attr *)attr; 23 | #endif 24 | } 25 | 26 | static inline ABT_mutex_attr ABTI_mutex_attr_get_handle(ABTI_mutex_attr *p_attr) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_mutex_attr h_attr; 30 | if (p_attr == NULL) { 31 | h_attr = ABT_MUTEX_ATTR_NULL; 32 | } else { 33 | h_attr = (ABT_mutex_attr)p_attr; 34 | } 35 | return h_attr; 36 | #else 37 | return (ABT_mutex_attr)p_attr; 38 | #endif 39 | } 40 | 41 | #endif /* ABTI_MUTEX_ATTR_H_INCLUDED */ 42 | -------------------------------------------------------------------------------- /src/include/abti_pool_config.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_POOL_CONFIG_H_INCLUDED 7 | #define ABTI_POOL_CONFIG_H_INCLUDED 8 | 9 | /* Inlined functions for pool config */ 10 | 11 | static inline ABTI_pool_config *ABTI_pool_config_get_ptr(ABT_pool_config config) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_pool_config *p_config; 15 | if (config == ABT_POOL_CONFIG_NULL) { 16 | p_config = NULL; 17 | } else { 18 | p_config = (ABTI_pool_config *)config; 19 | } 20 | return p_config; 21 | #else 22 | return (ABTI_pool_config *)config; 23 | #endif 24 | } 25 | 26 | static inline ABT_pool_config 27 | ABTI_pool_config_get_handle(ABTI_pool_config *p_config) 28 | { 29 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 30 | ABT_pool_config h_config; 31 | if (p_config == NULL) { 32 | h_config = ABT_POOL_CONFIG_NULL; 33 | } else { 34 | h_config = (ABT_pool_config)p_config; 35 | } 36 | return h_config; 37 | #else 38 | return (ABT_pool_config)p_config; 39 | #endif 40 | } 41 | 42 | #endif /* ABTI_POOL_CONFIG_H_INCLUDED */ 43 | -------------------------------------------------------------------------------- /src/include/abti_pool_user_def.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_POOL_USER_DEF_H_INCLUDED 7 | #define ABTI_POOL_USER_DEF_H_INCLUDED 8 | 9 | /* Inlined functions for pool user definitions */ 10 | 11 | static inline ABTI_pool_user_def * 12 | ABTI_pool_user_def_get_ptr(ABT_pool_user_def def) 13 | { 14 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 15 | ABTI_pool_user_def *p_def; 16 | if (def == ABT_POOL_USER_DEF_NULL) { 17 | p_def = NULL; 18 | } else { 19 | p_def = (ABTI_pool_user_def *)def; 20 | } 21 | return p_def; 22 | #else 23 | return (ABTI_pool_user_def *)def; 24 | #endif 25 | } 26 | 27 | static inline ABT_pool_user_def 28 | ABTI_pool_user_def_get_handle(ABTI_pool_user_def *p_def) 29 | { 30 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 31 | ABT_pool_user_def h_def; 32 | if (p_def == NULL) { 33 | h_def = ABT_POOL_USER_DEF_NULL; 34 | } else { 35 | h_def = (ABT_pool_user_def)p_def; 36 | } 37 | return h_def; 38 | #else 39 | return (ABT_pool_user_def)p_def; 40 | #endif 41 | } 42 | 43 | #endif /* ABTI_POOL_USER_DEF_H_INCLUDED */ 44 | -------------------------------------------------------------------------------- /src/include/abti_rwlock.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_RWLOCK_H_INCLUDED 7 | #define ABTI_RWLOCK_H_INCLUDED 8 | 9 | #include "abti_mutex.h" 10 | #include "abti_cond.h" 11 | 12 | /* Inlined functions for RWLock */ 13 | 14 | static inline ABTI_rwlock *ABTI_rwlock_get_ptr(ABT_rwlock rwlock) 15 | { 16 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 17 | ABTI_rwlock *p_rwlock; 18 | if (rwlock == ABT_RWLOCK_NULL) { 19 | p_rwlock = NULL; 20 | } else { 21 | p_rwlock = (ABTI_rwlock *)rwlock; 22 | } 23 | return p_rwlock; 24 | #else 25 | return (ABTI_rwlock *)rwlock; 26 | #endif 27 | } 28 | 29 | static inline ABT_rwlock ABTI_rwlock_get_handle(ABTI_rwlock *p_rwlock) 30 | { 31 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 32 | ABT_rwlock h_rwlock; 33 | if (p_rwlock == NULL) { 34 | h_rwlock = ABT_RWLOCK_NULL; 35 | } else { 36 | h_rwlock = (ABT_rwlock)p_rwlock; 37 | } 38 | return h_rwlock; 39 | #else 40 | return (ABT_rwlock)p_rwlock; 41 | #endif 42 | } 43 | 44 | #endif /* ABTI_RWLOCK_H_INCLUDED */ 45 | -------------------------------------------------------------------------------- /src/include/abti_sched.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_SCHED_H_INCLUDED 7 | #define ABTI_SCHED_H_INCLUDED 8 | 9 | /* Inlined functions for Scheduler */ 10 | 11 | static inline ABTI_sched *ABTI_sched_get_ptr(ABT_sched sched) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_sched *p_sched; 15 | if (sched == ABT_SCHED_NULL) { 16 | p_sched = NULL; 17 | } else { 18 | p_sched = (ABTI_sched *)sched; 19 | } 20 | return p_sched; 21 | #else 22 | return (ABTI_sched *)sched; 23 | #endif 24 | } 25 | 26 | static inline ABT_sched ABTI_sched_get_handle(ABTI_sched *p_sched) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_sched h_sched; 30 | if (p_sched == NULL) { 31 | h_sched = ABT_SCHED_NULL; 32 | } else { 33 | h_sched = (ABT_sched)p_sched; 34 | } 35 | return h_sched; 36 | #else 37 | return (ABT_sched)p_sched; 38 | #endif 39 | } 40 | 41 | /* Set `used` of p_sched to NOT_USED and free p_sched if its `automatic` is 42 | * ABT_TRUE, which means it is safe to free p_sched inside the runtime. */ 43 | static inline void ABTI_sched_discard_and_free(ABTI_global *p_global, 44 | ABTI_local *p_local, 45 | ABTI_sched *p_sched, 46 | ABT_bool force_free) 47 | { 48 | p_sched->used = ABTI_SCHED_NOT_USED; 49 | if (p_sched->automatic == ABT_TRUE || force_free) { 50 | ABTI_sched_free(p_global, p_local, p_sched, force_free); 51 | } else { 52 | /* Threads should be discarded here. */ 53 | if (p_sched->p_ythread) { 54 | ABTI_thread_free(p_global, p_local, &p_sched->p_ythread->thread); 55 | p_sched->p_ythread = NULL; 56 | } 57 | } 58 | } 59 | 60 | static inline void ABTI_sched_set_request(ABTI_sched *p_sched, uint32_t req) 61 | { 62 | ABTD_atomic_fetch_or_uint32(&p_sched->request, req); 63 | } 64 | 65 | static inline void ABTI_sched_unset_request(ABTI_sched *p_sched, uint32_t req) 66 | { 67 | ABTD_atomic_fetch_and_uint32(&p_sched->request, ~req); 68 | } 69 | 70 | #ifdef ABT_CONFIG_USE_SCHED_SLEEP 71 | #define CNT_DECL(c) int c 72 | #define CNT_INIT(c, v) c = v 73 | #define CNT_INC(c) c++ 74 | #define SCHED_SLEEP(c, t) \ 75 | if (c == 0) \ 76 | nanosleep(&(t), NULL) 77 | #else 78 | #define CNT_DECL(c) 79 | #define CNT_INIT(c, v) 80 | #define CNT_INC(c) 81 | #define SCHED_SLEEP(c, t) 82 | #endif 83 | 84 | #endif /* ABTI_SCHED_H_INCLUDED */ 85 | -------------------------------------------------------------------------------- /src/include/abti_sched_config.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_SCHED_CONFIG_H_INCLUDED 7 | #define ABTI_SCHED_CONFIG_H_INCLUDED 8 | 9 | /* Inlined functions for scheduler config */ 10 | 11 | static inline ABTI_sched_config * 12 | ABTI_sched_config_get_ptr(ABT_sched_config config) 13 | { 14 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 15 | ABTI_sched_config *p_config; 16 | if (config == ABT_SCHED_CONFIG_NULL) { 17 | p_config = NULL; 18 | } else { 19 | p_config = (ABTI_sched_config *)config; 20 | } 21 | return p_config; 22 | #else 23 | return (ABTI_sched_config *)config; 24 | #endif 25 | } 26 | 27 | static inline ABT_sched_config 28 | ABTI_sched_config_get_handle(ABTI_sched_config *p_config) 29 | { 30 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 31 | ABT_sched_config h_config; 32 | if (p_config == NULL) { 33 | h_config = ABT_SCHED_CONFIG_NULL; 34 | } else { 35 | h_config = (ABT_sched_config)p_config; 36 | } 37 | return h_config; 38 | #else 39 | return (ABT_sched_config)p_config; 40 | #endif 41 | } 42 | 43 | #endif /* ABTI_SCHED_CONFIG_H_INCLUDED */ 44 | -------------------------------------------------------------------------------- /src/include/abti_self.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_SELF_H_INCLUDED 7 | #define ABTI_SELF_H_INCLUDED 8 | 9 | static inline ABTI_native_thread_id 10 | ABTI_self_get_native_thread_id(ABTI_local *p_local) 11 | { 12 | ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(p_local); 13 | /* This is when an external thread called this routine. */ 14 | if (ABTI_IS_EXT_THREAD_ENABLED && p_local_xstream == NULL) { 15 | /* A pointer to a thread local variable can distinguish all external 16 | * threads and execution streams. */ 17 | return (ABTI_native_thread_id)ABTI_local_get_local_ptr(); 18 | } 19 | return (ABTI_native_thread_id)p_local_xstream; 20 | } 21 | 22 | static inline ABTI_thread_id ABTI_self_get_thread_id(ABTI_local *p_local) 23 | { 24 | ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(p_local); 25 | /* This is when an external thread called this routine. */ 26 | if (ABTI_IS_EXT_THREAD_ENABLED && p_local_xstream == NULL) { 27 | /* A pointer to a thread local variable is unique to an external thread 28 | * and its value is different from pointers to ULTs and tasks. */ 29 | return (ABTI_thread_id)ABTI_local_get_local_ptr(); 30 | } 31 | return (ABTI_thread_id)p_local_xstream->p_thread; 32 | } 33 | 34 | #endif /* ABTI_SELF_H_INCLUDED */ 35 | -------------------------------------------------------------------------------- /src/include/abti_stream.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_XSTREAM_H_INCLUDED 7 | #define ABTI_XSTREAM_H_INCLUDED 8 | 9 | /* Inlined functions for Execution Stream (ES) */ 10 | 11 | static inline ABTI_xstream *ABTI_xstream_get_ptr(ABT_xstream xstream) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_xstream *p_xstream; 15 | if (xstream == ABT_XSTREAM_NULL) { 16 | p_xstream = NULL; 17 | } else { 18 | p_xstream = (ABTI_xstream *)xstream; 19 | } 20 | return p_xstream; 21 | #else 22 | return (ABTI_xstream *)xstream; 23 | #endif 24 | } 25 | 26 | static inline ABT_xstream ABTI_xstream_get_handle(ABTI_xstream *p_xstream) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_xstream h_xstream; 30 | if (p_xstream == NULL) { 31 | h_xstream = ABT_XSTREAM_NULL; 32 | } else { 33 | h_xstream = (ABT_xstream)p_xstream; 34 | } 35 | return h_xstream; 36 | #else 37 | return (ABT_xstream)p_xstream; 38 | #endif 39 | } 40 | 41 | /* Get the first pool of the main scheduler. */ 42 | static inline ABTI_pool *ABTI_xstream_get_main_pool(ABTI_xstream *p_xstream) 43 | { 44 | ABT_pool pool = p_xstream->p_main_sched->pools[0]; 45 | return ABTI_pool_get_ptr(pool); 46 | } 47 | 48 | static inline ABTI_local *ABTI_xstream_get_local(ABTI_xstream *p_xstream) 49 | { 50 | return (ABTI_local *)p_xstream; 51 | } 52 | 53 | #endif /* ABTI_XSTREAM_H_INCLUDED */ 54 | -------------------------------------------------------------------------------- /src/include/abti_stream_barrier.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_XSTREAM_BARRIER_H_INCLUDED 7 | #define ABTI_XSTREAM_BARRIER_H_INCLUDED 8 | 9 | static inline ABTI_xstream_barrier * 10 | ABTI_xstream_barrier_get_ptr(ABT_xstream_barrier barrier) 11 | { 12 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 13 | ABTI_xstream_barrier *p_barrier; 14 | if (barrier == ABT_XSTREAM_BARRIER_NULL) { 15 | p_barrier = NULL; 16 | } else { 17 | p_barrier = (ABTI_xstream_barrier *)barrier; 18 | } 19 | return p_barrier; 20 | #else 21 | return (ABTI_xstream_barrier *)barrier; 22 | #endif 23 | } 24 | 25 | static inline ABT_xstream_barrier 26 | ABTI_xstream_barrier_get_handle(ABTI_xstream_barrier *p_barrier) 27 | { 28 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 29 | ABT_xstream_barrier h_barrier; 30 | if (p_barrier == NULL) { 31 | h_barrier = ABT_XSTREAM_BARRIER_NULL; 32 | } else { 33 | h_barrier = (ABT_xstream_barrier)p_barrier; 34 | } 35 | return h_barrier; 36 | #else 37 | return (ABT_xstream_barrier)p_barrier; 38 | #endif 39 | } 40 | 41 | #endif /* ABTI_XSTREAM_BARRIER_H_INCLUDED */ 42 | -------------------------------------------------------------------------------- /src/include/abti_thread_attr.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_THREAD_ATTR_H_INCLUDED 7 | #define ABTI_THREAD_ATTR_H_INCLUDED 8 | 9 | /* Inlined functions for ULT Attributes */ 10 | 11 | static inline ABTI_thread_attr *ABTI_thread_attr_get_ptr(ABT_thread_attr attr) 12 | { 13 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 14 | ABTI_thread_attr *p_attr; 15 | if (attr == ABT_THREAD_ATTR_NULL) { 16 | p_attr = NULL; 17 | } else { 18 | p_attr = (ABTI_thread_attr *)attr; 19 | } 20 | return p_attr; 21 | #else 22 | return (ABTI_thread_attr *)attr; 23 | #endif 24 | } 25 | 26 | static inline ABT_thread_attr 27 | ABTI_thread_attr_get_handle(ABTI_thread_attr *p_attr) 28 | { 29 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 30 | ABT_thread_attr h_attr; 31 | if (p_attr == NULL) { 32 | h_attr = ABT_THREAD_ATTR_NULL; 33 | } else { 34 | h_attr = (ABT_thread_attr)p_attr; 35 | } 36 | return h_attr; 37 | #else 38 | return (ABT_thread_attr)p_attr; 39 | #endif 40 | } 41 | 42 | static inline void ABTI_thread_attr_init(ABTI_thread_attr *p_attr, 43 | void *p_stack, size_t stacksize, 44 | ABT_bool migratable) 45 | { 46 | p_attr->p_stack = p_stack; 47 | p_attr->stacksize = stacksize; 48 | #ifndef ABT_CONFIG_DISABLE_MIGRATION 49 | p_attr->migratable = migratable; 50 | p_attr->f_cb = NULL; 51 | p_attr->p_cb_arg = NULL; 52 | #endif 53 | } 54 | 55 | #endif /* ABTI_THREAD_ATTR_H_INCLUDED */ 56 | -------------------------------------------------------------------------------- /src/include/abti_timer.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_TIMER_H_INCLUDED 7 | #define ABTI_TIMER_H_INCLUDED 8 | 9 | /* Inlined functions for Timer */ 10 | 11 | static inline double ABTI_get_wtime(void) 12 | { 13 | ABTD_time t; 14 | ABTD_time_get(&t); 15 | return ABTD_time_read_sec(&t); 16 | } 17 | 18 | static inline ABTI_timer *ABTI_timer_get_ptr(ABT_timer timer) 19 | { 20 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 21 | ABTI_timer *p_timer; 22 | if (timer == ABT_TIMER_NULL) { 23 | p_timer = NULL; 24 | } else { 25 | p_timer = (ABTI_timer *)timer; 26 | } 27 | return p_timer; 28 | #else 29 | return (ABTI_timer *)timer; 30 | #endif 31 | } 32 | 33 | static inline ABT_timer ABTI_timer_get_handle(ABTI_timer *p_timer) 34 | { 35 | #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 36 | ABT_timer h_timer; 37 | if (p_timer == NULL) { 38 | h_timer = ABT_TIMER_NULL; 39 | } else { 40 | h_timer = (ABT_timer)p_timer; 41 | } 42 | return h_timer; 43 | #else 44 | return (ABT_timer)p_timer; 45 | #endif 46 | } 47 | 48 | #endif /* ABTI_TIMER_H_INCLUDED */ 49 | -------------------------------------------------------------------------------- /src/include/abti_valgrind.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef ABTI_VALGRIND_H_INCLUDED 7 | #define ABTI_VALGRIND_H_INCLUDED 8 | 9 | /* Valgrind support */ 10 | #ifdef HAVE_VALGRIND_SUPPORT 11 | 12 | #include 13 | 14 | void ABTI_valgrind_register_stack(const void *p_stack, size_t size); 15 | void ABTI_valgrind_unregister_stack(const void *p_stack); 16 | #define ABTI_VALGRIND_REGISTER_STACK(p_stack, size) \ 17 | do { \ 18 | if (!RUNNING_ON_VALGRIND) \ 19 | break; \ 20 | ABTI_valgrind_register_stack(p_stack, size); \ 21 | } while (0) 22 | 23 | #define ABTI_VALGRIND_UNREGISTER_STACK(p_stack) \ 24 | do { \ 25 | if (!RUNNING_ON_VALGRIND) \ 26 | break; \ 27 | ABTI_valgrind_unregister_stack(p_stack); \ 28 | } while (0) 29 | 30 | #else 31 | 32 | #define ABTI_VALGRIND_REGISTER_STACK(p_stack, size) \ 33 | do { \ 34 | } while (0) 35 | #define ABTI_VALGRIND_UNREGISTER_STACK(p_stack) \ 36 | do { \ 37 | } while (0) 38 | 39 | #endif /* HAVE_VALGRIND_SUPPORT */ 40 | 41 | #endif /* ABTI_VALGRIND_H_INCLUDED */ 42 | -------------------------------------------------------------------------------- /src/include/asm/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | if ABT_USE_INT128_ATOMIC 7 | noinst_HEADERS = \ 8 | include/asm/abtd_asm_int128_cas.h 9 | endif 10 | -------------------------------------------------------------------------------- /src/local.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | 8 | static ABTI_local *local_get_local_internal(void) 9 | { 10 | return lp_ABTI_local; 11 | } 12 | 13 | static void local_set_xstream_internal(ABTI_xstream *p_local_xstream) 14 | { 15 | lp_ABTI_local = (ABTI_local *)p_local_xstream; 16 | } 17 | 18 | static void *local_get_local_ptr_internal(void) 19 | { 20 | return (void *)&lp_ABTI_local; 21 | } 22 | 23 | ABTI_local_func gp_ABTI_local_func = { { 0 }, 24 | local_get_local_internal, 25 | local_set_xstream_internal, 26 | local_get_local_ptr_internal, 27 | { 0 } }; 28 | /* ES Local Data */ 29 | ABTD_XSTREAM_LOCAL ABTI_local *lp_ABTI_local = NULL; 30 | -------------------------------------------------------------------------------- /src/mem/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources += \ 7 | mem/malloc.c \ 8 | mem/mem_pool.c \ 9 | mem/valgrind.c 10 | 11 | -------------------------------------------------------------------------------- /src/mem/valgrind.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | 8 | #ifdef HAVE_VALGRIND_SUPPORT 9 | 10 | /* 11 | * These routines register and unregister stacks of threads so that Valgrind can 12 | * handle them. This implementation uses a very naive linear list to keep track 13 | * of stacks and valgrind_id. Its performance is bad compared to, for example, 14 | * hash tables, but performance is less important when Valgrind is used. 15 | */ 16 | 17 | typedef size_t ABTI_valgrind_id; 18 | 19 | typedef struct ABTI_valgrind_id_list_t { 20 | const void *p_stack; 21 | ABTI_valgrind_id valgrind_id; 22 | struct ABTI_valgrind_id_list_t *p_next; 23 | } ABTI_valgrind_id_list; 24 | 25 | /* The list is protected by a global lock. */ 26 | static ABTD_spinlock g_valgrind_id_list_lock = 27 | ABTD_SPINLOCK_STATIC_INITIALIZER(); 28 | static int g_num_malloc_failures = 0; 29 | static ABTI_valgrind_id_list *gp_valgrind_id_list_head = NULL; 30 | static ABTI_valgrind_id_list *gp_valgrind_id_list_tail = NULL; 31 | 32 | #include 33 | 34 | void ABTI_valgrind_register_stack(const void *p_stack, size_t size) 35 | { 36 | if (p_stack == 0) 37 | return; 38 | 39 | const void *p_start = (char *)(p_stack); 40 | const void *p_end = (char *)(p_stack) + size; 41 | 42 | ABTD_spinlock_acquire(&g_valgrind_id_list_lock); 43 | ABTI_valgrind_id_list *p_valgrind_id_list = 44 | (ABTI_valgrind_id_list *)malloc(sizeof(ABTI_valgrind_id_list)); 45 | if (p_valgrind_id_list) { 46 | ABTI_valgrind_id valgrind_id = VALGRIND_STACK_REGISTER(p_start, p_end); 47 | p_valgrind_id_list->p_stack = p_stack; 48 | p_valgrind_id_list->valgrind_id = valgrind_id; 49 | p_valgrind_id_list->p_next = 0; 50 | if (!gp_valgrind_id_list_head) { 51 | gp_valgrind_id_list_head = p_valgrind_id_list; 52 | gp_valgrind_id_list_tail = p_valgrind_id_list; 53 | } else { 54 | gp_valgrind_id_list_tail->p_next = p_valgrind_id_list; 55 | gp_valgrind_id_list_tail = p_valgrind_id_list; 56 | } 57 | } else { 58 | /* When malloc() fails, VALGRIND_STACK_REGISTER is not performed, so we 59 | * cannot deregister this stack region. */ 60 | g_num_malloc_failures++; 61 | } 62 | ABTD_spinlock_release(&g_valgrind_id_list_lock); 63 | } 64 | 65 | void ABTI_valgrind_unregister_stack(const void *p_stack) 66 | { 67 | if (p_stack == 0) 68 | return; 69 | 70 | ABTD_spinlock_acquire(&g_valgrind_id_list_lock); 71 | if (gp_valgrind_id_list_head->p_stack == p_stack) { 72 | VALGRIND_STACK_DEREGISTER(gp_valgrind_id_list_head->valgrind_id); 73 | ABTI_valgrind_id_list *p_next = gp_valgrind_id_list_head->p_next; 74 | free(gp_valgrind_id_list_head); 75 | gp_valgrind_id_list_head = p_next; 76 | if (!p_next) 77 | gp_valgrind_id_list_tail = NULL; 78 | } else { 79 | /* Do linear search to find the corresponding valgrind_id. */ 80 | ABTI_valgrind_id_list *p_prev = gp_valgrind_id_list_head; 81 | ABTI_valgrind_id_list *p_current = gp_valgrind_id_list_head->p_next; 82 | ABT_bool deregister_flag = ABT_FALSE; 83 | while (p_current) { 84 | if (p_current->p_stack == p_stack) { 85 | VALGRIND_STACK_DEREGISTER(p_current->valgrind_id); 86 | p_prev->p_next = p_current->p_next; 87 | if (!p_prev->p_next) 88 | gp_valgrind_id_list_tail = p_prev; 89 | free(p_current); 90 | deregister_flag = ABT_TRUE; 91 | break; 92 | } 93 | p_prev = p_current; 94 | p_current = p_current->p_next; 95 | } 96 | if (!deregister_flag) { 97 | /* Although it is less likely, maybe we missed stack registration 98 | * because of the failure of malloc. */ 99 | ABTI_ASSERT(g_num_malloc_failures > 0); 100 | g_num_malloc_failures--; 101 | } 102 | } 103 | ABTD_spinlock_release(&g_valgrind_id_list_lock); 104 | } 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/pool/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources += \ 7 | pool/fifo.c \ 8 | pool/fifo_wait.c \ 9 | pool/pool.c \ 10 | pool/pool_config.c \ 11 | pool/pool_user_def.c \ 12 | pool/randws.c \ 13 | pool/thread_queue.h 14 | -------------------------------------------------------------------------------- /src/sched/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources += \ 7 | sched/basic.c \ 8 | sched/basic_wait.c \ 9 | sched/prio.c \ 10 | sched/randws.c \ 11 | sched/sched.c \ 12 | sched/sched_config.c 13 | 14 | -------------------------------------------------------------------------------- /src/util/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | abt_sources += \ 7 | util/atoi.c \ 8 | util/hashtable.c \ 9 | util/largepage.c \ 10 | util/mprotect.c 11 | -------------------------------------------------------------------------------- /src/util/mprotect.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include "abti.h" 7 | #include 8 | 9 | ABTU_ret_err int ABTU_mprotect(void *addr, size_t size, ABT_bool protect) 10 | { 11 | #ifdef HAVE_MPROTECT 12 | int ret; 13 | if (protect) { 14 | ret = mprotect(addr, size, PROT_READ); 15 | } else { 16 | ret = mprotect(addr, size, PROT_READ | PROT_WRITE); 17 | } 18 | return ret == 0 ? ABT_SUCCESS : ABT_ERR_SYS; 19 | #else 20 | return ABT_ERR_SYS; 21 | #endif 22 | } 23 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | # basic 2 | basic/init_finalize 3 | basic/xstream_create 4 | basic/xstream_revive 5 | basic/xstream_affinity 6 | basic/xstream_barrier 7 | basic/xstream_rank 8 | basic/xstream_set_main_sched 9 | basic/thread_create 10 | basic/thread_create2 11 | basic/thread_create3 12 | basic/thread_create4 13 | basic/thread_create_on_xstream 14 | basic/thread_revive 15 | basic/thread_attr 16 | basic/thread_attr2 17 | basic/thread_yield 18 | basic/thread_yield2 19 | basic/thread_yield_to 20 | basic/thread_exit 21 | basic/thread_self_suspend_resume 22 | basic/thread_get_last_xstream 23 | basic/thread_get_func_arg 24 | basic/thread_migrate 25 | basic/thread_data 26 | basic/thread_data2 27 | basic/thread_id 28 | basic/task_create 29 | basic/task_create_on_xstream 30 | basic/task_revive 31 | basic/task_data 32 | basic/task_data2 33 | basic/thread_task 34 | basic/thread_task_arg 35 | basic/thread_task_num 36 | basic/sched_basic 37 | basic/sched_basic_wait 38 | basic/sched_on_thread 39 | basic/sched_prio 40 | basic/sched_randws 41 | basic/sched_set_main 42 | basic/sched_stack 43 | basic/sched_config 44 | basic/sched_user_ws 45 | basic/pool_config 46 | basic/pool_custom 47 | basic/pool_user_def 48 | basic/sync_no_contention 49 | basic/main_sched 50 | basic/mutex 51 | basic/mutex_prio 52 | basic/mutex_recursive 53 | basic/mutex_spinlock 54 | basic/mutex_static 55 | basic/mutex_unlock_se 56 | basic/cond_test 57 | basic/cond_join 58 | basic/cond_signal_in_main 59 | basic/cond_static 60 | basic/cond_timedwait 61 | basic/future_create 62 | basic/rwlock_reader_incl 63 | basic/rwlock_reader_writer_excl 64 | basic/rwlock_writer_excl 65 | basic/eventual_create 66 | basic/eventual_static 67 | basic/eventual_test 68 | basic/barrier 69 | basic/self_exit_to 70 | basic/self_rank_id 71 | basic/self_resume_to 72 | basic/self_suspend_to 73 | basic/self_type 74 | basic/self_yield_to 75 | basic/ext_thread 76 | basic/ext_thread2 77 | basic/ext_thread_barrier 78 | basic/ext_thread_cond 79 | basic/ext_thread_eventual 80 | basic/ext_thread_future 81 | basic/ext_thread_join 82 | basic/ext_thread_mutex 83 | basic/ext_thread_rwlock 84 | basic/stack_guard 85 | basic/timer 86 | basic/info_print 87 | basic/info_print_stack 88 | basic/info_query 89 | basic/info_stackdump 90 | basic/info_stackdump2 91 | basic/unit 92 | basic/error 93 | 94 | # benchmark 95 | benchmark/init_finalize 96 | benchmark/xstream_ops 97 | benchmark/thread_ops 98 | benchmark/thread_many_ops 99 | benchmark/thread_ops_all 100 | benchmark/task_ops 101 | benchmark/task_ops_all 102 | benchmark/sync_ops 103 | benchmark/thread_fork_join 104 | benchmark/thread_fork_join_papi 105 | benchmark/thread_fork_join_papi_l1m_l2m 106 | benchmark/thread_fork_join_many 107 | benchmark/thread_fork_join_many_papi 108 | benchmark/thread_fork_join_many_papi_l1m_l2m 109 | benchmark/thread_fork_join_many_priv_pool 110 | benchmark/thread_fork_join_many_priv_pool_papi 111 | benchmark/thread_fork_join_many_priv_pool_papi_l1m_l2m 112 | benchmark/task_fork_join 113 | benchmark/task_fork_join_papi 114 | benchmark/task_fork_join_papi_l1m_l2m 115 | benchmark/task_fork_join_priv_pool 116 | benchmark/task_fork_join_priv_pool_papi 117 | benchmark/task_fork_join_priv_pool_papi_l1m_l2m 118 | 119 | # code builds 120 | util/libutil.la 121 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | SUBDIRS = util basic leakcheck benchmark 7 | DIST_SUBDIRS = $(SUBDIRS) 8 | 9 | -------------------------------------------------------------------------------- /test/Makefile.mk: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | AM_CPPFLAGS = $(DEPS_CPPFLAGS) 7 | AM_CPPFLAGS += -I$(top_builddir)/src/include -I$(top_srcdir)/test/util 8 | AM_LDFLAGS = $(DEPS_LDFLAGS) -lm 9 | 10 | libabt = $(top_builddir)/src/libabt.la 11 | libutil = $(top_builddir)/test/util/libutil.la 12 | 13 | $(libabt): 14 | $(MAKE) -C $(top_builddir)/src 15 | 16 | $(libutil): 17 | $(MAKE) -C $(top_builddir)/test/util 18 | 19 | LDADD = $(libutil) $(libabt) 20 | 21 | -------------------------------------------------------------------------------- /test/basic/cond_signal_in_main.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | ABT_mutex mutex = ABT_MUTEX_NULL; 13 | ABT_cond cond = ABT_COND_NULL; 14 | 15 | void wait_on_condition(void *arg) 16 | { 17 | ATS_UNUSED(arg); 18 | ABT_mutex_lock(mutex); 19 | ABT_cond_wait(cond, mutex); 20 | ABT_mutex_unlock(mutex); 21 | } 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | int ret; 26 | 27 | ABT_xstream xstream; 28 | 29 | /* Initialize */ 30 | ATS_read_args(argc, argv); 31 | 32 | ATS_init(argc, argv, 1); 33 | 34 | /* Create Execution Streams */ 35 | ret = ABT_xstream_self(&xstream); 36 | ATS_ERROR(ret, "ABT_xstream_self"); 37 | 38 | /* Get the pools attached to the execution stream */ 39 | ABT_pool pool; 40 | ret = ABT_xstream_get_main_pools(xstream, 1, &pool); 41 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 42 | 43 | /* Create a mutex */ 44 | ret = ABT_mutex_create(&mutex); 45 | ATS_ERROR(ret, "ABT_mutex_create"); 46 | 47 | /* Create condition variables */ 48 | ret = ABT_cond_create(&cond); 49 | ATS_ERROR(ret, "ABT_cond_create"); 50 | 51 | /* Create the ULT */ 52 | ABT_thread thread; 53 | ret = ABT_thread_create(pool, wait_on_condition, NULL, ABT_THREAD_ATTR_NULL, 54 | &thread); 55 | ATS_ERROR(ret, "ABT_thread_create"); 56 | 57 | /* Switch to the other user level thread */ 58 | ABT_thread_yield(); 59 | 60 | ABT_mutex_lock(mutex); 61 | ret = ABT_cond_signal(cond); 62 | ABT_mutex_unlock(mutex); 63 | ATS_ERROR(ret, "ABT_cond_signal"); 64 | 65 | /* Wait for the ULT and free it */ 66 | ABT_thread_free(&thread); 67 | 68 | /* Free the mutex */ 69 | ret = ABT_mutex_free(&mutex); 70 | ATS_ERROR(ret, "ABT_mutex_free"); 71 | 72 | /* Free the condition variables */ 73 | ret = ABT_cond_free(&cond); 74 | ATS_ERROR(ret, "ABT_cond_free"); 75 | 76 | /* Finalize */ 77 | ret = ATS_finalize(0); 78 | 79 | return ret; 80 | } 81 | -------------------------------------------------------------------------------- /test/basic/error.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | typedef struct { 13 | const char *str; 14 | int code; 15 | } error_pair_t; 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | int ret, i; 20 | 21 | /* init and thread creation */ 22 | ATS_read_args(argc, argv); 23 | 24 | error_pair_t error_pairs[] = { 25 | { "ABT_SUCCESS", ABT_SUCCESS }, 26 | { "ABT_ERR_UNINITIALIZED", ABT_ERR_UNINITIALIZED }, 27 | { "ABT_ERR_MEM", ABT_ERR_MEM }, 28 | { "ABT_ERR_OTHER", ABT_ERR_OTHER }, 29 | { "ABT_ERR_INV_XSTREAM", ABT_ERR_INV_XSTREAM }, 30 | { "ABT_ERR_INV_XSTREAM_RANK", ABT_ERR_INV_XSTREAM_RANK }, 31 | { "ABT_ERR_INV_XSTREAM_BARRIER", ABT_ERR_INV_XSTREAM_BARRIER }, 32 | { "ABT_ERR_INV_SCHED", ABT_ERR_INV_SCHED }, 33 | { "ABT_ERR_INV_SCHED_KIND", ABT_ERR_INV_SCHED_KIND }, 34 | { "ABT_ERR_INV_SCHED_PREDEF", ABT_ERR_INV_SCHED_PREDEF }, 35 | { "ABT_ERR_INV_SCHED_TYPE", ABT_ERR_INV_SCHED_TYPE }, 36 | { "ABT_ERR_INV_SCHED_CONFIG", ABT_ERR_INV_SCHED_CONFIG }, 37 | { "ABT_ERR_INV_POOL", ABT_ERR_INV_POOL }, 38 | { "ABT_ERR_INV_POOL_KIND", ABT_ERR_INV_POOL_KIND }, 39 | { "ABT_ERR_INV_POOL_ACCESS", ABT_ERR_INV_POOL_ACCESS }, 40 | { "ABT_ERR_INV_POOL_CONFIG", ABT_ERR_INV_POOL_CONFIG }, 41 | { "ABT_ERR_INV_POOL_USER_DEF", ABT_ERR_INV_POOL_USER_DEF }, 42 | { "ABT_ERR_INV_UNIT", ABT_ERR_INV_UNIT }, 43 | { "ABT_ERR_INV_THREAD", ABT_ERR_INV_THREAD }, 44 | { "ABT_ERR_INV_THREAD_ATTR", ABT_ERR_INV_THREAD_ATTR }, 45 | { "ABT_ERR_INV_TASK", ABT_ERR_INV_TASK }, 46 | { "ABT_ERR_INV_KEY", ABT_ERR_INV_KEY }, 47 | { "ABT_ERR_INV_MUTEX", ABT_ERR_INV_MUTEX }, 48 | { "ABT_ERR_INV_MUTEX_ATTR", ABT_ERR_INV_MUTEX_ATTR }, 49 | { "ABT_ERR_INV_COND", ABT_ERR_INV_COND }, 50 | { "ABT_ERR_INV_RWLOCK", ABT_ERR_INV_RWLOCK }, 51 | { "ABT_ERR_INV_EVENTUAL", ABT_ERR_INV_EVENTUAL }, 52 | { "ABT_ERR_INV_FUTURE", ABT_ERR_INV_FUTURE }, 53 | { "ABT_ERR_INV_BARRIER", ABT_ERR_INV_BARRIER }, 54 | { "ABT_ERR_INV_TIMER", ABT_ERR_INV_TIMER }, 55 | { "ABT_ERR_INV_QUERY_KIND", ABT_ERR_INV_QUERY_KIND }, 56 | { "ABT_ERR_XSTREAM", ABT_ERR_XSTREAM }, 57 | { "ABT_ERR_XSTREAM_STATE", ABT_ERR_XSTREAM_STATE }, 58 | { "ABT_ERR_XSTREAM_BARRIER", ABT_ERR_XSTREAM_BARRIER }, 59 | { "ABT_ERR_SCHED", ABT_ERR_SCHED }, 60 | { "ABT_ERR_SCHED_CONFIG", ABT_ERR_SCHED_CONFIG }, 61 | { "ABT_ERR_POOL", ABT_ERR_POOL }, 62 | { "ABT_ERR_UNIT", ABT_ERR_UNIT }, 63 | { "ABT_ERR_THREAD", ABT_ERR_THREAD }, 64 | { "ABT_ERR_TASK", ABT_ERR_TASK }, 65 | { "ABT_ERR_KEY", ABT_ERR_KEY }, 66 | { "ABT_ERR_MUTEX", ABT_ERR_MUTEX }, 67 | { "ABT_ERR_MUTEX_LOCKED", ABT_ERR_MUTEX_LOCKED }, 68 | { "ABT_ERR_COND", ABT_ERR_COND }, 69 | { "ABT_ERR_COND_TIMEDOUT", ABT_ERR_COND_TIMEDOUT }, 70 | { "ABT_ERR_RWLOCK", ABT_ERR_RWLOCK }, 71 | { "ABT_ERR_EVENTUAL", ABT_ERR_EVENTUAL }, 72 | { "ABT_ERR_FUTURE", ABT_ERR_FUTURE }, 73 | { "ABT_ERR_BARRIER", ABT_ERR_BARRIER }, 74 | { "ABT_ERR_TIMER", ABT_ERR_TIMER }, 75 | { "ABT_ERR_MIGRATION_TARGET", ABT_ERR_MIGRATION_TARGET }, 76 | { "ABT_ERR_MIGRATION_NA", ABT_ERR_MIGRATION_NA }, 77 | { "ABT_ERR_MISSING_JOIN", ABT_ERR_MISSING_JOIN }, 78 | { "ABT_ERR_FEATURE_NA", ABT_ERR_FEATURE_NA }, 79 | { "ABT_ERR_INV_TOOL_CONTEXT", ABT_ERR_INV_TOOL_CONTEXT }, 80 | { "ABT_ERR_INV_ARG", ABT_ERR_INV_ARG }, 81 | { "ABT_ERR_SYS", ABT_ERR_SYS }, 82 | { "ABT_ERR_CPUID", ABT_ERR_CPUID }, 83 | }; 84 | 85 | for (i = 0; i < (int)(sizeof(error_pairs) / sizeof(error_pairs[0])); i++) { 86 | char str[256]; 87 | ret = ABT_error_get_str(error_pairs[i].code, str, NULL); 88 | ATS_ERROR(ret, "ABT_error_get_str"); 89 | assert(strcmp(error_pairs[i].str, str) == 0); 90 | } 91 | return ret; 92 | } 93 | -------------------------------------------------------------------------------- /test/basic/eventual_create.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define EVENTUAL_SIZE 10 12 | 13 | ABT_thread th1, th2, th3; 14 | ABT_eventual myeventual; 15 | 16 | #define LOOP_CNT 10 17 | void fn1(void *args) 18 | { 19 | ATS_UNUSED(args); 20 | int i = 0; 21 | void *data; 22 | ATS_printf(1, "Thread 1 iteration %d waiting for eventual\n", i); 23 | ABT_eventual_wait(myeventual, &data); 24 | ATS_printf(1, 25 | "Thread 1 continue iteration %d returning from " 26 | "eventual\n", 27 | i); 28 | } 29 | 30 | void fn2(void *args) 31 | { 32 | ATS_UNUSED(args); 33 | int i = 0; 34 | ABT_bool is_ready = 0; 35 | void *data; 36 | ATS_printf(1, "Thread 2 iteration %d waiting from eventual\n", i); 37 | ABT_eventual_test(myeventual, &data, &is_ready); 38 | while (!is_ready) { 39 | ABT_thread_yield(); 40 | ABT_eventual_test(myeventual, &data, &is_ready); 41 | } 42 | ABT_eventual_wait(myeventual, &data); 43 | ATS_printf(1, 44 | "Thread 2 continue iteration %d returning from " 45 | "eventual\n", 46 | i); 47 | } 48 | 49 | void fn3(void *args) 50 | { 51 | ATS_UNUSED(args); 52 | int i = 0; 53 | ATS_printf(1, "Thread 3 iteration %d signal eventual \n", i); 54 | char *data = (char *)malloc(EVENTUAL_SIZE); 55 | ABT_eventual_set(myeventual, data, EVENTUAL_SIZE); 56 | free(data); 57 | ATS_printf(1, "Thread 3 continue iteration %d \n", i); 58 | } 59 | 60 | int main(int argc, char *argv[]) 61 | { 62 | int ret; 63 | ABT_xstream xstream; 64 | 65 | /* init and thread creation */ 66 | ATS_read_args(argc, argv); 67 | ATS_init(argc, argv, 1); 68 | 69 | ret = ABT_xstream_self(&xstream); 70 | ATS_ERROR(ret, "ABT_xstream_self"); 71 | 72 | /* Get the pools attached to an execution stream */ 73 | ABT_pool pool; 74 | ret = ABT_xstream_get_main_pools(xstream, 1, &pool); 75 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 76 | 77 | ret = ABT_thread_create(pool, fn1, NULL, ABT_THREAD_ATTR_NULL, &th1); 78 | ATS_ERROR(ret, "ABT_thread_create"); 79 | ret = ABT_thread_create(pool, fn2, NULL, ABT_THREAD_ATTR_NULL, &th2); 80 | ATS_ERROR(ret, "ABT_thread_create"); 81 | ret = ABT_thread_create(pool, fn3, NULL, ABT_THREAD_ATTR_NULL, &th3); 82 | ATS_ERROR(ret, "ABT_thread_create"); 83 | 84 | ret = ABT_eventual_create(EVENTUAL_SIZE, &myeventual); 85 | ATS_ERROR(ret, "ABT_eventual_create"); 86 | 87 | ATS_printf(1, "START\n"); 88 | 89 | void *data; 90 | ATS_printf(1, "Thread main iteration %d waiting for eventual\n", 0); 91 | ABT_eventual_wait(myeventual, &data); 92 | ATS_printf(1, 93 | "Thread main continue iteration %d returning from " 94 | "eventual\n", 95 | 0); 96 | 97 | /* Join and free other threads */ 98 | ret = ABT_thread_free(&th1); 99 | ATS_ERROR(ret, "ABT_thread_free"); 100 | ret = ABT_thread_free(&th2); 101 | ATS_ERROR(ret, "ABT_thread_free"); 102 | ret = ABT_thread_free(&th3); 103 | ATS_ERROR(ret, "ABT_thread_free"); 104 | 105 | ATS_printf(1, "END\n"); 106 | 107 | ret = ABT_eventual_free(&myeventual); 108 | ATS_ERROR(ret, "ABT_eventual_free"); 109 | 110 | ret = ATS_finalize(0); 111 | 112 | return ret; 113 | } 114 | -------------------------------------------------------------------------------- /test/basic/ext_thread2.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | /* This code tests that a pthread can free threads created locally, 13 | * and vice versa. */ 14 | #define NUM_THREADS 100 15 | #define NUM_XSTREAMS 2 16 | ABT_xstream xstreams[NUM_XSTREAMS]; 17 | ABT_pool pools[NUM_XSTREAMS]; 18 | ABT_thread threads[NUM_THREADS]; 19 | 20 | void thread_func(void *arg) 21 | { 22 | int i, ret, tid = (int)((intptr_t)arg); 23 | if (tid % 4 == 0) { 24 | /* ABT_self_yield */ 25 | for (i = 0; i < tid / 4; i++) { 26 | ret = ABT_self_yield(); 27 | ATS_ERROR(ret, "ABT_self_yield"); 28 | } 29 | } else if (tid % 4 == 1) { 30 | /* ABT_self_exit */ 31 | ret = ABT_self_exit(); 32 | ATS_ERROR(ret, "ABT_self_exit"); 33 | } else if (tid % 4 == 2) { 34 | /* ABT_thread_exit */ 35 | ret = ABT_thread_exit(); 36 | ATS_ERROR(ret, "ABT_thread_exit"); 37 | } else if (tid % 4 == 3) { 38 | /* ABT_thread_exit_to */ 39 | ABT_pool target_pool = pools[(tid / 4) % 2]; 40 | ABT_unit unit; 41 | ret = ABT_pool_pop(target_pool, &unit); 42 | ATS_ERROR(ret, "ABT_pool_pop"); 43 | if (unit != ABT_UNIT_NULL) { 44 | ABT_thread target; 45 | ret = ABT_unit_get_thread(unit, &target); 46 | ATS_ERROR(ret, "ABT_unit_get_thread"); 47 | ret = ABT_self_exit_to(target); 48 | ATS_ERROR(ret, "ABT_self_exit_to"); 49 | } 50 | } 51 | } 52 | 53 | void join_threads() 54 | { 55 | size_t i; 56 | int ret; 57 | /* Join */ 58 | for (i = 0; i < NUM_THREADS; i++) { 59 | ret = ABT_thread_join(threads[i]); 60 | ATS_ERROR(ret, "ABT_thread_join"); 61 | } 62 | /* Free */ 63 | for (i = 0; i < NUM_THREADS; i++) { 64 | ret = ABT_thread_free(&threads[i]); 65 | ATS_ERROR(ret, "ABT_thread_free"); 66 | } 67 | } 68 | 69 | void create_threads() 70 | { 71 | size_t i; 72 | int ret; 73 | /* Create */ 74 | for (i = 0; i < NUM_THREADS; i++) { 75 | ret = ABT_thread_create(pools[i % NUM_XSTREAMS], thread_func, (void *)i, 76 | ABT_THREAD_ATTR_NULL, &threads[i]); 77 | ATS_ERROR(ret, "ABT_thread_create"); 78 | } 79 | } 80 | 81 | void *pthread_join_threads(void *arg) 82 | { 83 | join_threads(); 84 | return NULL; 85 | } 86 | 87 | void *pthread_create_threads(void *arg) 88 | { 89 | create_threads(); 90 | return NULL; 91 | } 92 | 93 | int main(int argc, char *argv[]) 94 | { 95 | pthread_t pthread; 96 | int ret; 97 | size_t i; 98 | 99 | /* Initialize */ 100 | ATS_init(argc, argv, NUM_XSTREAMS); 101 | 102 | /* Set up execution streams and pools. */ 103 | for (i = 0; i < NUM_XSTREAMS; i++) { 104 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 105 | ATS_ERROR(ret, "ABT_xstream_create"); 106 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); 107 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 108 | } 109 | 110 | /* Create threads locally, and join threads by pthread */ 111 | create_threads(); 112 | ret = pthread_create(&pthread, NULL, pthread_join_threads, NULL); 113 | assert(ret == 0); 114 | ret = pthread_join(pthread, NULL); 115 | assert(ret == 0); 116 | 117 | /* Create threads by pthread, and join threads locally */ 118 | ret = pthread_create(&pthread, NULL, pthread_create_threads, NULL); 119 | assert(ret == 0); 120 | ret = pthread_join(pthread, NULL); 121 | assert(ret == 0); 122 | join_threads(); 123 | 124 | /* Join and free Execution Streams */ 125 | for (i = 0; i < NUM_XSTREAMS; i++) { 126 | ret = ABT_xstream_join(xstreams[i]); 127 | ATS_ERROR(ret, "ABT_xstream_join"); 128 | ret = ABT_xstream_free(&xstreams[i]); 129 | ATS_ERROR(ret, "ABT_xstream_free"); 130 | } 131 | 132 | /* Finalize */ 133 | return ATS_finalize(0); 134 | } 135 | -------------------------------------------------------------------------------- /test/basic/init_finalize.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | #define DEFAULT_NUM_THREADS 10 13 | #define DEFAULT_NUM_ITER 10 14 | 15 | static int num_iter = DEFAULT_NUM_ITER; 16 | 17 | static void *init_test(void *arg) 18 | { 19 | int i, ret; 20 | ret = ABT_initialized(); 21 | ATS_ERROR(ret, "ABT_initialized"); 22 | 23 | for (i = 0; i < num_iter; i++) { 24 | ret = ABT_init(0, NULL); 25 | ATS_ERROR(ret, "ABT_init"); 26 | ret = ABT_finalize(); 27 | ATS_ERROR(ret, "ABT_finalize"); 28 | } 29 | 30 | ret = ABT_initialized(); 31 | ATS_ERROR(ret, "ABT_initialized"); 32 | 33 | return NULL; 34 | } 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | int num_threads = DEFAULT_NUM_THREADS; 39 | pthread_t *threads; 40 | int i, ret; 41 | 42 | int initialized = ABT_initialized(); 43 | assert(initialized == ABT_ERR_UNINITIALIZED); 44 | 45 | /* Initialize */ 46 | ATS_read_args(argc, argv); 47 | if (argc > 2) { 48 | num_threads = ATS_get_arg_val(ATS_ARG_N_ES); 49 | num_iter = ATS_get_arg_val(ATS_ARG_N_ITER); 50 | } 51 | ATS_init(argc, argv, num_threads); 52 | 53 | threads = (pthread_t *)malloc(num_threads * sizeof(pthread_t)); 54 | assert(threads); 55 | 56 | /* Create threads. Each thread will call ABT_init and ABT_finalize. */ 57 | for (i = 0; i < num_threads; i++) { 58 | ret = pthread_create(&threads[i], NULL, init_test, NULL); 59 | assert(ret == 0); 60 | } 61 | 62 | /* Join threads */ 63 | for (i = 0; i < num_threads; i++) { 64 | ret = pthread_join(threads[i], NULL); 65 | assert(ret == 0); 66 | } 67 | free(threads); 68 | 69 | /* Finalize */ 70 | ret = ATS_finalize(0); 71 | 72 | initialized = ABT_initialized(); 73 | assert(initialized == ABT_ERR_UNINITIALIZED); 74 | 75 | return ret; 76 | } 77 | -------------------------------------------------------------------------------- /test/basic/sched_basic.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | int i, j; 23 | int ret; 24 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 25 | int num_threads = DEFAULT_NUM_THREADS; 26 | if (argc > 1) 27 | num_xstreams = atoi(argv[1]); 28 | assert(num_xstreams >= 0); 29 | if (argc > 2) 30 | num_threads = atoi(argv[2]); 31 | assert(num_threads >= 0); 32 | 33 | ABT_xstream *xstreams; 34 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 35 | 36 | ABT_sched *scheds; 37 | scheds = (ABT_sched *)malloc(sizeof(ABT_sched) * num_xstreams); 38 | 39 | ABT_pool *pools; 40 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 41 | 42 | /* Initialize */ 43 | ATS_read_args(argc, argv); 44 | ATS_init(argc, argv, num_xstreams); 45 | 46 | /* Create schedulers */ 47 | ABT_sched_config config; 48 | ret = ABT_sched_config_create(&config, ABT_sched_basic_freq, 10, 49 | ABT_sched_config_var_end); 50 | ATS_ERROR(ret, "ABT_sched_config_create"); 51 | for (i = 0; i < num_xstreams; i++) { 52 | ret = ABT_sched_create_basic(ABT_SCHED_DEFAULT, 0, NULL, config, 53 | &scheds[i]); 54 | ATS_ERROR(ret, "ABT_sched_create_basic"); 55 | } 56 | ret = ABT_sched_config_free(&config); 57 | ATS_ERROR(ret, "ABT_sched_config_free"); 58 | 59 | /* Create Execution Streams */ 60 | ret = ABT_xstream_self(&xstreams[0]); 61 | ATS_ERROR(ret, "ABT_xstream_self"); 62 | ret = ABT_xstream_set_main_sched(xstreams[0], scheds[0]); 63 | ATS_ERROR(ret, "ABT_xstream_set_main_sched"); 64 | for (i = 1; i < num_xstreams; i++) { 65 | ret = ABT_xstream_create(scheds[i], &xstreams[i]); 66 | ATS_ERROR(ret, "ABT_xstream_create"); 67 | } 68 | 69 | /* Get the pools attached to an execution stream */ 70 | for (i = 0; i < num_xstreams; i++) { 71 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 72 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 73 | } 74 | 75 | /* Create ULTs */ 76 | for (i = 0; i < num_xstreams; i++) { 77 | for (j = 0; j < num_threads; j++) { 78 | size_t tid = i * num_threads + j + 1; 79 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 80 | ABT_THREAD_ATTR_NULL, NULL); 81 | ATS_ERROR(ret, "ABT_thread_create"); 82 | } 83 | } 84 | 85 | /* Join Execution Streams */ 86 | for (i = 1; i < num_xstreams; i++) { 87 | ret = ABT_xstream_join(xstreams[i]); 88 | ATS_ERROR(ret, "ABT_xstream_join"); 89 | } 90 | 91 | /* Free Execution Streams */ 92 | for (i = 1; i < num_xstreams; i++) { 93 | ret = ABT_xstream_free(&xstreams[i]); 94 | ATS_ERROR(ret, "ABT_xstream_free"); 95 | } 96 | 97 | /* Finalize */ 98 | ret = ATS_finalize(0); 99 | 100 | free(pools); 101 | free(scheds); 102 | free(xstreams); 103 | 104 | return ret; 105 | } 106 | -------------------------------------------------------------------------------- /test/basic/sched_basic_wait.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | int i, j; 23 | int ret; 24 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 25 | int num_threads = DEFAULT_NUM_THREADS; 26 | if (argc > 1) 27 | num_xstreams = atoi(argv[1]); 28 | assert(num_xstreams >= 0); 29 | if (argc > 2) 30 | num_threads = atoi(argv[2]); 31 | assert(num_threads >= 0); 32 | 33 | ABT_xstream *xstreams; 34 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 35 | 36 | ABT_sched *scheds; 37 | scheds = (ABT_sched *)malloc(sizeof(ABT_sched) * num_xstreams); 38 | 39 | ABT_pool *pools; 40 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 41 | 42 | /* Initialize */ 43 | ATS_read_args(argc, argv); 44 | ATS_init(argc, argv, num_xstreams); 45 | 46 | /* Create schedulers */ 47 | for (i = 0; i < num_xstreams; i++) { 48 | ret = ABT_sched_create_basic(ABT_SCHED_BASIC_WAIT, 0, NULL, 49 | ABT_SCHED_CONFIG_NULL, &scheds[i]); 50 | ATS_ERROR(ret, "ABT_sched_create_basic"); 51 | } 52 | 53 | /* Create Execution Streams */ 54 | ret = ABT_xstream_self(&xstreams[0]); 55 | ATS_ERROR(ret, "ABT_xstream_self"); 56 | ret = ABT_xstream_set_main_sched(xstreams[0], scheds[0]); 57 | ATS_ERROR(ret, "ABT_xstream_set_main_sched"); 58 | for (i = 1; i < num_xstreams; i++) { 59 | ret = ABT_xstream_create(scheds[i], &xstreams[i]); 60 | ATS_ERROR(ret, "ABT_xstream_create"); 61 | } 62 | 63 | /* Get the pools attached to an execution stream */ 64 | for (i = 0; i < num_xstreams; i++) { 65 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 66 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 67 | } 68 | 69 | /* Create ULTs */ 70 | for (i = 0; i < num_xstreams; i++) { 71 | for (j = 0; j < num_threads; j++) { 72 | size_t tid = i * num_threads + j + 1; 73 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 74 | ABT_THREAD_ATTR_NULL, NULL); 75 | ATS_ERROR(ret, "ABT_thread_create"); 76 | } 77 | } 78 | 79 | /* Join Execution Streams */ 80 | for (i = 1; i < num_xstreams; i++) { 81 | ret = ABT_xstream_join(xstreams[i]); 82 | ATS_ERROR(ret, "ABT_xstream_join"); 83 | } 84 | 85 | /* Free Execution Streams */ 86 | for (i = 1; i < num_xstreams; i++) { 87 | ret = ABT_xstream_free(&xstreams[i]); 88 | ATS_ERROR(ret, "ABT_xstream_free"); 89 | } 90 | 91 | /* Finalize */ 92 | ret = ATS_finalize(0); 93 | 94 | free(pools); 95 | free(scheds); 96 | free(xstreams); 97 | 98 | return ret; 99 | } 100 | -------------------------------------------------------------------------------- /test/basic/sched_stack.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | /* In this test, we use only one ES. We create one main pool (attached to the 7 | * main scheduler). First we push one task in this pool, then one 8 | * sub-scheduler, then another task, then another sub-scheduler and finally one 9 | * last task. In the tasks, we check the order of execution. 10 | */ 11 | 12 | #include 13 | #include 14 | #include "abt.h" 15 | #include "abttest.h" 16 | 17 | #define DEFAULT_NUM_TASKS 8 18 | 19 | long int value = 0; 20 | 21 | void task_func(void *arg) 22 | { 23 | long int v = (long int)arg; 24 | assert(v == value + 1); 25 | value++; 26 | } 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | 31 | int i, ret; 32 | int num_tasks = DEFAULT_NUM_TASKS; 33 | 34 | if (argc > 1) 35 | num_tasks = atoi(argv[1]); 36 | assert(num_tasks >= 0); 37 | 38 | ABT_xstream xstream; 39 | 40 | ABT_pool pool_mainsched, pool_subsched1, pool_subsched2; 41 | ABT_sched mainsched, subsched1, subsched2; 42 | 43 | /* Initialize */ 44 | ATS_read_args(argc, argv); 45 | ATS_init(argc, argv, 1); 46 | 47 | /* Creation of the main pool/sched */ 48 | ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_PRIV, ABT_TRUE, 49 | &pool_mainsched); 50 | ATS_ERROR(ret, "ABT_pool_create_basic"); 51 | ret = ABT_sched_create_basic(ABT_SCHED_DEFAULT, 1, &pool_mainsched, 52 | ABT_SCHED_CONFIG_NULL, &mainsched); 53 | ATS_ERROR(ret, "ABT_sched_create_basic"); 54 | 55 | /* Configure the main Execution Stream with mainsched */ 56 | ret = ABT_xstream_self(&xstream); 57 | ATS_ERROR(ret, "ABT_xstream_self"); 58 | ret = ABT_xstream_set_main_sched(xstream, mainsched); 59 | ATS_ERROR(ret, "ABT_xstream_set_main_sched"); 60 | 61 | /* Creation of subsched1 */ 62 | ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_PRIV, ABT_TRUE, 63 | &pool_subsched1); 64 | ATS_ERROR(ret, "ABT_pool_create_basic"); 65 | ret = ABT_sched_create_basic(ABT_SCHED_DEFAULT, 1, &pool_subsched1, 66 | ABT_SCHED_CONFIG_NULL, &subsched1); 67 | ATS_ERROR(ret, "ABT_sched_create_basic"); 68 | 69 | /* Creation of subsched2 */ 70 | ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_PRIV, ABT_TRUE, 71 | &pool_subsched2); 72 | ATS_ERROR(ret, "ABT_pool_create_basic"); 73 | ret = ABT_sched_create_basic(ABT_SCHED_DEFAULT, 1, &pool_subsched2, 74 | ABT_SCHED_CONFIG_NULL, &subsched2); 75 | ATS_ERROR(ret, "ABT_sched_create_basic"); 76 | 77 | long int num = 0; 78 | ret = ABT_task_create(pool_mainsched, task_func, (void *)++num, NULL); 79 | ATS_ERROR(ret, "ABT_task_create"); 80 | 81 | for (i = 0; i < num_tasks; i++) { 82 | ret = ABT_task_create(pool_subsched1, task_func, (void *)++num, NULL); 83 | ATS_ERROR(ret, "ABT_task_create"); 84 | } 85 | ret = ABT_pool_add_sched(pool_mainsched, subsched1); 86 | ATS_ERROR(ret, "ABT_pool_add_sched"); 87 | 88 | ret = ABT_task_create(pool_mainsched, task_func, (void *)++num, NULL); 89 | ATS_ERROR(ret, "ABT_task_create"); 90 | 91 | for (i = 0; i < num_tasks; i++) { 92 | ret = ABT_task_create(pool_subsched2, task_func, (void *)++num, NULL); 93 | ATS_ERROR(ret, "ABT_task_create"); 94 | } 95 | ret = ABT_pool_add_sched(pool_mainsched, subsched2); 96 | ATS_ERROR(ret, "ABT_pool_add_sched"); 97 | 98 | ret = ABT_task_create(pool_mainsched, task_func, (void *)++num, NULL); 99 | ATS_ERROR(ret, "ABT_task_create"); 100 | 101 | /* Finalize */ 102 | ret = ATS_finalize(0); 103 | 104 | assert(value == 3 + 2 * num_tasks); 105 | return ret; 106 | } 107 | -------------------------------------------------------------------------------- /test/basic/task_create.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 2 12 | #define DEFAULT_NUM_TASKS 4 13 | 14 | typedef struct { 15 | size_t num; 16 | unsigned long long result; 17 | } task_arg_t; 18 | 19 | void task_func1(void *arg) 20 | { 21 | size_t i; 22 | size_t num = (size_t)arg; 23 | unsigned long long result = 1; 24 | for (i = 2; i <= num; i++) { 25 | result += i; 26 | } 27 | ATS_printf(1, "task_func1: num=%lu result=%llu\n", num, result); 28 | } 29 | 30 | void task_func2(void *arg) 31 | { 32 | size_t i; 33 | task_arg_t *my_arg = (task_arg_t *)arg; 34 | unsigned long long result = 1; 35 | for (i = 2; i <= my_arg->num; i++) { 36 | result += i; 37 | } 38 | my_arg->result = result; 39 | } 40 | 41 | int main(int argc, char *argv[]) 42 | { 43 | int i, ret; 44 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 45 | int num_tasks = DEFAULT_NUM_TASKS; 46 | if (argc > 1) 47 | num_xstreams = atoi(argv[1]); 48 | assert(num_xstreams >= 0); 49 | if (argc > 2) 50 | num_tasks = atoi(argv[2]); 51 | assert(num_tasks >= 0); 52 | 53 | ABT_xstream *xstreams; 54 | ABT_pool *pools; 55 | ABT_task *tasks; 56 | task_arg_t *args; 57 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 58 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 59 | tasks = (ABT_task *)malloc(sizeof(ABT_task) * num_tasks); 60 | args = (task_arg_t *)malloc(sizeof(task_arg_t) * num_tasks); 61 | 62 | /* Initialize */ 63 | ATS_read_args(argc, argv); 64 | ATS_init(argc, argv, num_xstreams); 65 | 66 | /* Create Execution Streams */ 67 | ret = ABT_xstream_self(&xstreams[0]); 68 | ATS_ERROR(ret, "ABT_xstream_self"); 69 | for (i = 1; i < num_xstreams; i++) { 70 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 71 | ATS_ERROR(ret, "ABT_xstream_create"); 72 | } 73 | 74 | /* Get the pools attached to an execution stream */ 75 | for (i = 0; i < num_xstreams; i++) { 76 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 77 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 78 | } 79 | 80 | /* Create tasks with task_func1 */ 81 | for (i = 0; i < num_tasks; i++) { 82 | size_t num = 100 + i; 83 | ret = ABT_task_create(pools[i % num_xstreams], task_func1, (void *)num, 84 | NULL); 85 | ATS_ERROR(ret, "ABT_task_create"); 86 | } 87 | 88 | /* Create tasks with task_func2 */ 89 | for (i = 0; i < num_tasks; i++) { 90 | args[i].num = 100 + i; 91 | ret = ABT_task_create(pools[i % num_xstreams], task_func2, 92 | (void *)&args[i], &tasks[i]); 93 | ATS_ERROR(ret, "ABT_task_create"); 94 | } 95 | 96 | /* Results of task_funcs2 */ 97 | for (i = 0; i < num_tasks; i++) { 98 | ABT_task_state state; 99 | do { 100 | ABT_task_get_state(tasks[i], &state); 101 | ABT_thread_yield(); 102 | } while (state != ABT_TASK_STATE_TERMINATED); 103 | 104 | ATS_printf(1, "task_func2: num=%lu result=%llu\n", args[i].num, 105 | args[i].result); 106 | 107 | /* Free named tasks */ 108 | ret = ABT_task_free(&tasks[i]); 109 | ATS_ERROR(ret, "ABT_task_free"); 110 | } 111 | 112 | /* Join Execution Streams */ 113 | for (i = 1; i < num_xstreams; i++) { 114 | ret = ABT_xstream_join(xstreams[i]); 115 | ATS_ERROR(ret, "ABT_xstream_join"); 116 | } 117 | 118 | /* Free Execution Streams */ 119 | for (i = 1; i < num_xstreams; i++) { 120 | ret = ABT_xstream_free(&xstreams[i]); 121 | ATS_ERROR(ret, "ABT_xstream_free"); 122 | } 123 | 124 | /* Finalize */ 125 | ret = ATS_finalize(0); 126 | 127 | free(args); 128 | free(tasks); 129 | free(pools); 130 | free(xstreams); 131 | 132 | return ret; 133 | } 134 | -------------------------------------------------------------------------------- /test/basic/task_create_on_xstream.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 2 12 | #define DEFAULT_NUM_TASKS 4 13 | 14 | typedef struct { 15 | size_t num; 16 | unsigned long long result; 17 | } task_arg_t; 18 | 19 | void task_func1(void *arg) 20 | { 21 | size_t i; 22 | size_t num = (size_t)arg; 23 | unsigned long long result = 1; 24 | for (i = 2; i <= num; i++) { 25 | result += i; 26 | } 27 | ATS_printf(1, "task_func1: num=%lu result=%llu\n", num, result); 28 | } 29 | 30 | void task_func2(void *arg) 31 | { 32 | size_t i; 33 | task_arg_t *my_arg = (task_arg_t *)arg; 34 | unsigned long long result = 1; 35 | for (i = 2; i <= my_arg->num; i++) { 36 | result += i; 37 | } 38 | my_arg->result = result; 39 | } 40 | 41 | int main(int argc, char *argv[]) 42 | { 43 | int i, ret; 44 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 45 | int num_tasks = DEFAULT_NUM_TASKS; 46 | if (argc > 1) 47 | num_xstreams = atoi(argv[1]); 48 | assert(num_xstreams >= 0); 49 | if (argc > 2) 50 | num_tasks = atoi(argv[2]); 51 | assert(num_tasks >= 0); 52 | 53 | ABT_xstream *xstreams; 54 | ABT_task *tasks; 55 | task_arg_t *args; 56 | 57 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 58 | tasks = (ABT_task *)malloc(sizeof(ABT_task) * num_tasks); 59 | args = (task_arg_t *)malloc(sizeof(task_arg_t) * num_tasks); 60 | 61 | /* Initialize */ 62 | ATS_read_args(argc, argv); 63 | ATS_init(argc, argv, num_xstreams); 64 | 65 | /* Create Execution Streams */ 66 | ret = ABT_xstream_self(&xstreams[0]); 67 | ATS_ERROR(ret, "ABT_xstream_self"); 68 | for (i = 1; i < num_xstreams; i++) { 69 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 70 | ATS_ERROR(ret, "ABT_xstream_create"); 71 | } 72 | 73 | /* Create tasklets with task_func1 */ 74 | for (i = 0; i < num_tasks; i++) { 75 | size_t num = 100 + i; 76 | ret = ABT_task_create_on_xstream(xstreams[i % num_xstreams], task_func1, 77 | (void *)num, NULL); 78 | ATS_ERROR(ret, "ABT_task_create"); 79 | } 80 | 81 | /* Create tasklets with task_func2 */ 82 | for (i = 0; i < num_tasks; i++) { 83 | args[i].num = 100 + i; 84 | ret = ABT_task_create_on_xstream(xstreams[i % num_xstreams], task_func2, 85 | (void *)&args[i], &tasks[i]); 86 | ATS_ERROR(ret, "ABT_task_create"); 87 | } 88 | 89 | /* Results of task_funcs2 */ 90 | for (i = 0; i < num_tasks; i++) { 91 | ABT_task_state state; 92 | do { 93 | ABT_task_get_state(tasks[i], &state); 94 | ABT_thread_yield(); 95 | } while (state != ABT_TASK_STATE_TERMINATED); 96 | 97 | ATS_printf(1, "task_func2: num=%lu result=%llu\n", args[i].num, 98 | args[i].result); 99 | 100 | /* Free named tasklets */ 101 | ret = ABT_task_free(&tasks[i]); 102 | ATS_ERROR(ret, "ABT_task_free"); 103 | } 104 | 105 | /* Join Execution Streams */ 106 | for (i = 1; i < num_xstreams; i++) { 107 | ret = ABT_xstream_join(xstreams[i]); 108 | ATS_ERROR(ret, "ABT_xstream_join"); 109 | } 110 | 111 | /* Free Execution Streams */ 112 | for (i = 1; i < num_xstreams; i++) { 113 | ret = ABT_xstream_free(&xstreams[i]); 114 | ATS_ERROR(ret, "ABT_xstream_free"); 115 | } 116 | 117 | /* Finalize */ 118 | ret = ATS_finalize(0); 119 | 120 | free(args); 121 | free(tasks); 122 | free(xstreams); 123 | 124 | return ret; 125 | } 126 | -------------------------------------------------------------------------------- /test/basic/thread_attr.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ABT_thread thread; 18 | ABT_thread_attr attr; 19 | size_t stacksize1, stacksize2; 20 | int ret; 21 | 22 | ABT_thread_self(&thread); 23 | ret = ABT_thread_get_attr(thread, &attr); 24 | ATS_ERROR(ret, "ABT_thread_get_attr"); 25 | 26 | ret = ABT_thread_attr_get_stacksize(attr, &stacksize1); 27 | ATS_ERROR(ret, "ABT_thread_attr_get_stacksize"); 28 | ret = ABT_thread_get_stacksize(thread, &stacksize2); 29 | ATS_ERROR(ret, "ABT_thread_get_stacksize"); 30 | assert(stacksize1 == stacksize2); 31 | ATS_printf(1, "[TH%lu]: stacksize=%lu\n", my_id, stacksize1); 32 | 33 | ret = ABT_thread_attr_free(&attr); 34 | ATS_ERROR(ret, "ABT_thread_attr_free"); 35 | } 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | int i, j; 40 | int ret; 41 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 42 | int num_threads = DEFAULT_NUM_THREADS; 43 | if (argc > 1) 44 | num_xstreams = atoi(argv[1]); 45 | assert(num_xstreams >= 0); 46 | if (argc > 2) 47 | num_threads = atoi(argv[2]); 48 | assert(num_threads >= 0); 49 | 50 | ABT_thread_attr attr; 51 | ABT_xstream *xstreams; 52 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 53 | 54 | /* Initialize */ 55 | ATS_read_args(argc, argv); 56 | ATS_init(argc, argv, num_xstreams); 57 | 58 | /* Create Execution Streams */ 59 | ret = ABT_xstream_self(&xstreams[0]); 60 | ATS_ERROR(ret, "ABT_xstream_self"); 61 | for (i = 1; i < num_xstreams; i++) { 62 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 63 | ATS_ERROR(ret, "ABT_xstream_create"); 64 | } 65 | 66 | /* Get the pools attached to an execution stream */ 67 | ABT_pool *pools; 68 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 69 | for (i = 0; i < num_xstreams; i++) { 70 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 71 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 72 | } 73 | 74 | /* ULT attribute */ 75 | ret = ABT_thread_attr_create(&attr); 76 | ATS_ERROR(ret, "ABT_thread_attr_create"); 77 | ABT_thread_attr_set_stacksize(attr, 262144); 78 | 79 | /* Create threads */ 80 | for (i = 0; i < num_xstreams; i++) { 81 | for (j = 0; j < num_threads; j++) { 82 | size_t tid = i * num_threads + j + 1; 83 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 84 | (tid % 2 ? attr : ABT_THREAD_ATTR_NULL), 85 | NULL); 86 | ATS_ERROR(ret, "ABT_thread_create"); 87 | } 88 | } 89 | 90 | /* Free the attribute */ 91 | ret = ABT_thread_attr_free(&attr); 92 | ATS_ERROR(ret, "ABT_thread_attr_free"); 93 | 94 | thread_func((void *)0); 95 | 96 | /* Join Execution Streams */ 97 | for (i = 1; i < num_xstreams; i++) { 98 | ret = ABT_xstream_join(xstreams[i]); 99 | ATS_ERROR(ret, "ABT_xstream_join"); 100 | } 101 | 102 | /* Free Execution Streams */ 103 | for (i = 1; i < num_xstreams; i++) { 104 | ret = ABT_xstream_free(&xstreams[i]); 105 | ATS_ERROR(ret, "ABT_xstream_free"); 106 | } 107 | 108 | /* Finalize */ 109 | ret = ATS_finalize(0); 110 | 111 | free(pools); 112 | free(xstreams); 113 | 114 | return ret; 115 | } 116 | -------------------------------------------------------------------------------- /test/basic/thread_create.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | int i, j; 23 | int ret; 24 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 25 | int num_threads = DEFAULT_NUM_THREADS; 26 | if (argc > 1) 27 | num_xstreams = atoi(argv[1]); 28 | assert(num_xstreams >= 0); 29 | if (argc > 2) 30 | num_threads = atoi(argv[2]); 31 | assert(num_threads >= 0); 32 | 33 | ABT_xstream *xstreams; 34 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 35 | 36 | ABT_pool *pools; 37 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 38 | 39 | /* Initialize */ 40 | ATS_read_args(argc, argv); 41 | ATS_init(argc, argv, num_xstreams); 42 | 43 | /* Create Execution Streams */ 44 | ret = ABT_xstream_self(&xstreams[0]); 45 | ATS_ERROR(ret, "ABT_xstream_self"); 46 | for (i = 1; i < num_xstreams; i++) { 47 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 48 | ATS_ERROR(ret, "ABT_xstream_create"); 49 | } 50 | 51 | /* Get the pools attached to an execution stream */ 52 | for (i = 0; i < num_xstreams; i++) { 53 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 54 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 55 | } 56 | 57 | /* Create threads */ 58 | for (i = 0; i < num_xstreams; i++) { 59 | for (j = 0; j < num_threads; j++) { 60 | size_t tid = i * num_threads + j + 1; 61 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 62 | ABT_THREAD_ATTR_NULL, NULL); 63 | ATS_ERROR(ret, "ABT_thread_create"); 64 | } 65 | } 66 | 67 | /* Join Execution Streams */ 68 | for (i = 1; i < num_xstreams; i++) { 69 | ret = ABT_xstream_join(xstreams[i]); 70 | ATS_ERROR(ret, "ABT_xstream_join"); 71 | } 72 | 73 | /* Free Execution Streams */ 74 | for (i = 1; i < num_xstreams; i++) { 75 | ret = ABT_xstream_free(&xstreams[i]); 76 | ATS_ERROR(ret, "ABT_xstream_free"); 77 | } 78 | 79 | /* Finalize */ 80 | ret = ATS_finalize(0); 81 | 82 | free(pools); 83 | free(xstreams); 84 | 85 | return ret; 86 | } 87 | -------------------------------------------------------------------------------- /test/basic/thread_create2.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | int num_threads = DEFAULT_NUM_THREADS; 15 | 16 | void thread_func(void *arg) 17 | { 18 | size_t my_id = (size_t)arg; 19 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 20 | } 21 | 22 | void thread_create(void *arg) 23 | { 24 | int i, ret; 25 | size_t my_id = (size_t)arg; 26 | ABT_pool my_pool; 27 | 28 | ret = ABT_self_get_last_pool(&my_pool); 29 | ATS_ERROR(ret, "ABT_self_get_last_pool"); 30 | 31 | /* Create threads */ 32 | for (i = 0; i < num_threads; i++) { 33 | size_t tid = 100 * my_id + i; 34 | ret = ABT_thread_create(my_pool, thread_func, (void *)tid, 35 | ABT_THREAD_ATTR_NULL, NULL); 36 | ATS_ERROR(ret, "ABT_thread_create"); 37 | } 38 | 39 | ATS_printf(1, "[TH%lu]: created %d threads\n", my_id, num_threads); 40 | } 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | int i; 45 | int ret; 46 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 47 | if (argc > 1) 48 | num_xstreams = atoi(argv[1]); 49 | assert(num_xstreams >= 0); 50 | if (argc > 2) 51 | num_threads = atoi(argv[2]); 52 | assert(num_threads >= 0); 53 | 54 | ABT_xstream *xstreams; 55 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 56 | 57 | ABT_pool *pools; 58 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 59 | 60 | /* Initialize */ 61 | ATS_read_args(argc, argv); 62 | ATS_init(argc, argv, num_xstreams); 63 | 64 | /* Create Execution Streams */ 65 | ret = ABT_xstream_self(&xstreams[0]); 66 | ATS_ERROR(ret, "ABT_xstream_self"); 67 | for (i = 1; i < num_xstreams; i++) { 68 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 69 | ATS_ERROR(ret, "ABT_xstream_create"); 70 | } 71 | 72 | /* Get the pools attached to an execution stream */ 73 | for (i = 0; i < num_xstreams; i++) { 74 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 75 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 76 | } 77 | 78 | /* Create one thread for each ES */ 79 | for (i = 0; i < num_xstreams; i++) { 80 | size_t tid = i + 1; 81 | ret = ABT_thread_create(pools[i], thread_create, (void *)tid, 82 | ABT_THREAD_ATTR_NULL, NULL); 83 | ATS_ERROR(ret, "ABT_thread_create"); 84 | } 85 | 86 | /* Join Execution Streams */ 87 | for (i = 1; i < num_xstreams; i++) { 88 | ret = ABT_xstream_join(xstreams[i]); 89 | ATS_ERROR(ret, "ABT_xstream_join"); 90 | } 91 | 92 | /* Free Execution Streams */ 93 | for (i = 1; i < num_xstreams; i++) { 94 | ret = ABT_xstream_free(&xstreams[i]); 95 | ATS_ERROR(ret, "ABT_xstream_free"); 96 | } 97 | 98 | /* Finalize */ 99 | ret = ATS_finalize(0); 100 | 101 | free(pools); 102 | free(xstreams); 103 | 104 | return ret; 105 | } 106 | -------------------------------------------------------------------------------- /test/basic/thread_create4.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | /* This test checks the order of execution. */ 13 | 14 | int g_counter = 0; 15 | void thread_func(void *arg) 16 | { 17 | g_counter++; 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | int i; 23 | int ret; 24 | 25 | /* Initialize */ 26 | ATS_read_args(argc, argv); 27 | ATS_init(argc, argv, 1); 28 | 29 | ABT_pool main_pool; 30 | ret = ABT_self_get_last_pool(&main_pool); 31 | ATS_ERROR(ret, "ABT_self_get_last_pool"); 32 | 33 | for (i = 0; i < 5; i++) { 34 | ABT_thread thread; 35 | size_t size; 36 | g_counter = 0; 37 | 38 | /* Parent-first (ABT_thread_create) */ 39 | ret = ABT_thread_create(main_pool, thread_func, NULL, 40 | ABT_THREAD_ATTR_NULL, &thread); 41 | ATS_ERROR(ret, "ABT_thread_create"); 42 | assert(g_counter == 0); 43 | 44 | ret = ABT_pool_get_size(main_pool, &size); 45 | ATS_ERROR(ret, "ABT_pool_get_size"); 46 | assert(size == 1); 47 | 48 | ret = ABT_thread_join(thread); 49 | ATS_ERROR(ret, "ABT_thread_join"); 50 | assert(g_counter == 1); 51 | 52 | /* Parent-first (ABT_thread_revive) */ 53 | ret = ABT_thread_revive(main_pool, thread_func, NULL, &thread); 54 | ATS_ERROR(ret, "ABT_thread_revive"); 55 | assert(g_counter == 1); 56 | 57 | ret = ABT_pool_get_size(main_pool, &size); 58 | ATS_ERROR(ret, "ABT_pool_get_size"); 59 | assert(size == 1); 60 | 61 | ret = ABT_thread_join(thread); 62 | ATS_ERROR(ret, "ABT_thread_join"); 63 | assert(g_counter == 2); 64 | 65 | /* Child-first (ABT_thread_revive_to) */ 66 | ret = ABT_thread_revive_to(main_pool, thread_func, NULL, &thread); 67 | ATS_ERROR(ret, "ABT_thread_revive_to"); 68 | assert(g_counter == 3); 69 | 70 | ret = ABT_pool_get_size(main_pool, &size); 71 | ATS_ERROR(ret, "ABT_pool_get_size"); 72 | assert(size == 0); 73 | 74 | ret = ABT_thread_free(&thread); 75 | ATS_ERROR(ret, "ABT_thread_free"); 76 | assert(g_counter == 3); 77 | 78 | /* Child-first (ABT_thread_create_to) */ 79 | ret = ABT_thread_create_to(main_pool, thread_func, NULL, 80 | ABT_THREAD_ATTR_NULL, &thread); 81 | ATS_ERROR(ret, "ABT_thread_create_to"); 82 | assert(g_counter == 4); 83 | 84 | ret = ABT_pool_get_size(main_pool, &size); 85 | ATS_ERROR(ret, "ABT_pool_get_size"); 86 | assert(size == 0); 87 | 88 | ret = ABT_thread_join(thread); 89 | ATS_ERROR(ret, "ABT_thread_join"); 90 | assert(g_counter == 4); 91 | 92 | /* Parent-first (ABT_thread_revive) */ 93 | ret = ABT_thread_revive(main_pool, thread_func, NULL, &thread); 94 | ATS_ERROR(ret, "ABT_thread_revive"); 95 | assert(g_counter == 4); 96 | 97 | ret = ABT_pool_get_size(main_pool, &size); 98 | ATS_ERROR(ret, "ABT_pool_get_size"); 99 | assert(size == 1); 100 | 101 | ret = ABT_thread_join(thread); 102 | ATS_ERROR(ret, "ABT_thread_join"); 103 | assert(g_counter == 5); 104 | 105 | /* Child-first (ABT_thread_revive_to) */ 106 | ret = ABT_thread_revive_to(main_pool, thread_func, NULL, &thread); 107 | ATS_ERROR(ret, "ABT_thread_revive_to"); 108 | assert(g_counter == 6); 109 | 110 | ret = ABT_pool_get_size(main_pool, &size); 111 | ATS_ERROR(ret, "ABT_pool_get_size"); 112 | assert(size == 0); 113 | 114 | ret = ABT_thread_free(&thread); 115 | ATS_ERROR(ret, "ABT_thread_free"); 116 | assert(g_counter == 6); 117 | } 118 | 119 | /* Finalize */ 120 | ret = ATS_finalize(0); 121 | return ret; 122 | } 123 | -------------------------------------------------------------------------------- /test/basic/thread_create_on_xstream.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | int num_threads = DEFAULT_NUM_THREADS; 15 | 16 | void thread_func(void *arg) 17 | { 18 | size_t my_id = (size_t)arg; 19 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 20 | } 21 | 22 | void thread_create(void *arg) 23 | { 24 | int i, ret; 25 | size_t my_id = (size_t)arg; 26 | ABT_xstream my_xstream; 27 | 28 | ret = ABT_xstream_self(&my_xstream); 29 | ATS_ERROR(ret, "ABT_xstream_self"); 30 | 31 | /* Create ULTs */ 32 | for (i = 0; i < num_threads; i++) { 33 | size_t tid = 100 * my_id + i; 34 | ret = ABT_thread_create_on_xstream(my_xstream, thread_func, (void *)tid, 35 | ABT_THREAD_ATTR_NULL, NULL); 36 | ATS_ERROR(ret, "ABT_thread_create_on_xstream"); 37 | } 38 | 39 | ATS_printf(1, "[TH%lu]: created %d ULTs\n", my_id, num_threads); 40 | } 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | int i; 45 | int ret; 46 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 47 | if (argc > 1) 48 | num_xstreams = atoi(argv[1]); 49 | assert(num_xstreams >= 0); 50 | if (argc > 2) 51 | num_threads = atoi(argv[2]); 52 | assert(num_threads >= 0); 53 | 54 | ABT_xstream *xstreams; 55 | ABT_thread *threads; 56 | 57 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 58 | threads = (ABT_thread *)malloc(sizeof(ABT_thread) * num_xstreams); 59 | 60 | /* Initialize */ 61 | ATS_read_args(argc, argv); 62 | ATS_init(argc, argv, num_xstreams); 63 | 64 | /* Create Execution Streams */ 65 | ret = ABT_xstream_self(&xstreams[0]); 66 | ATS_ERROR(ret, "ABT_xstream_self"); 67 | for (i = 1; i < num_xstreams; i++) { 68 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 69 | ATS_ERROR(ret, "ABT_xstream_create"); 70 | } 71 | 72 | /* Create one ULT for each ES */ 73 | for (i = 0; i < num_xstreams; i++) { 74 | size_t tid = i + 1; 75 | ret = ABT_thread_create_on_xstream(xstreams[i], thread_create, 76 | (void *)tid, ABT_THREAD_ATTR_NULL, 77 | &threads[i]); 78 | ATS_ERROR(ret, "ABT_thread_create_on_xstream"); 79 | } 80 | 81 | /* Join and free ULTs */ 82 | for (i = 0; i < num_xstreams; i++) { 83 | ret = ABT_thread_join(threads[i]); 84 | ATS_ERROR(ret, "ABT_thread_join"); 85 | ret = ABT_thread_free(&threads[i]); 86 | ATS_ERROR(ret, "ABT_thread_free"); 87 | } 88 | 89 | /* Join and free Execution Streams */ 90 | for (i = 1; i < num_xstreams; i++) { 91 | ret = ABT_xstream_join(xstreams[i]); 92 | ATS_ERROR(ret, "ABT_xstream_join"); 93 | ret = ABT_xstream_free(&xstreams[i]); 94 | ATS_ERROR(ret, "ABT_xstream_free"); 95 | } 96 | 97 | free(xstreams); 98 | free(threads); 99 | 100 | /* Finalize */ 101 | ret = ATS_finalize(0); 102 | 103 | return ret; 104 | } 105 | -------------------------------------------------------------------------------- /test/basic/thread_exit.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "abt.h" 10 | #include "abttest.h" 11 | 12 | #define NUM_THREADS 100 13 | 14 | int g_count = 0; 15 | 16 | void thread_func(void *arg) 17 | { 18 | g_count++; 19 | if (arg == NULL) { 20 | ABT_thread_exit(); 21 | } else { 22 | ABT_self_exit(); 23 | } 24 | assert(0); 25 | } 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | int i, ret; 30 | 31 | /* Initialize */ 32 | ATS_read_args(argc, argv); 33 | ATS_init(argc, argv, 1); 34 | 35 | /* Get the pool attached to the primary execution stream */ 36 | ABT_xstream xstream; 37 | ret = ABT_self_get_xstream(&xstream); 38 | ATS_ERROR(ret, "ABT_self_get_xstream"); 39 | 40 | ABT_pool pool; 41 | ret = ABT_xstream_get_main_pools(xstream, 1, &pool); 42 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 43 | 44 | /* Fork and join threads */ 45 | ABT_thread *threads = 46 | (ABT_thread *)malloc(sizeof(ABT_thread) * NUM_THREADS); 47 | for (i = 0; i < NUM_THREADS; i++) { 48 | void *arg = (i < NUM_THREADS / 2) ? NULL : ((void *)(intptr_t)1); 49 | ret = ABT_thread_create(pool, thread_func, arg, ABT_THREAD_ATTR_NULL, 50 | &threads[i]); 51 | ATS_ERROR(ret, "ABT_thread_create"); 52 | } 53 | for (i = 0; i < NUM_THREADS; i++) { 54 | ret = ABT_thread_free(&threads[i]); 55 | ATS_ERROR(ret, "ABT_thread_free"); 56 | } 57 | free(threads); 58 | 59 | /* Finalize */ 60 | return ATS_finalize(0); 61 | } 62 | -------------------------------------------------------------------------------- /test/basic/thread_get_func_arg.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 8 13 | #define DEFAULT_NUM_TASKS 4 14 | 15 | void check_func_arg(void (*thread_f1)(void *), void *arg1) 16 | { 17 | int ret; 18 | void *arg2, *arg3; 19 | void (*thread_f2)(void *), (*thread_f3)(void *); 20 | 21 | ret = ABT_self_get_thread_func(&thread_f2); 22 | ATS_ERROR(ret, "ABT_self_get_thread_func"); 23 | assert(thread_f1 == thread_f2); 24 | ret = ABT_self_get_arg(&arg2); 25 | ATS_ERROR(ret, "ABT_self_get_arg"); 26 | assert(arg1 == arg2); 27 | 28 | ABT_thread self_thread; 29 | ret = ABT_self_get_thread(&self_thread); 30 | ATS_ERROR(ret, "ABT_self_get_thread"); 31 | ret = ABT_thread_get_thread_func(self_thread, &thread_f3); 32 | ATS_ERROR(ret, "ABT_thread_get_thread_func"); 33 | assert(thread_f1 == thread_f3); 34 | ret = ABT_thread_get_arg(self_thread, &arg3); 35 | ATS_ERROR(ret, "ABT_thread_get_arg"); 36 | assert(arg1 == arg3); 37 | } 38 | 39 | void thread_func(void *arg) 40 | { 41 | check_func_arg(thread_func, arg); 42 | int ret = ABT_self_yield(); 43 | ATS_ERROR(ret, "ABT_self_yield"); 44 | check_func_arg(thread_func, arg); 45 | } 46 | 47 | void task_func(void *arg) 48 | { 49 | check_func_arg(task_func, arg); 50 | } 51 | 52 | int main(int argc, char *argv[]) 53 | { 54 | int i; 55 | int ret; 56 | int num_xstreams, num_threads, num_tasks; 57 | 58 | /* Initialize */ 59 | ATS_read_args(argc, argv); 60 | if (argc < 2) { 61 | num_xstreams = DEFAULT_NUM_XSTREAMS; 62 | num_threads = DEFAULT_NUM_THREADS; 63 | num_tasks = DEFAULT_NUM_TASKS; 64 | } else { 65 | num_xstreams = ATS_get_arg_val(ATS_ARG_N_ES); 66 | num_threads = ATS_get_arg_val(ATS_ARG_N_ULT); 67 | num_tasks = ATS_get_arg_val(ATS_ARG_N_TASK); 68 | } 69 | 70 | ATS_init(argc, argv, num_xstreams); 71 | ABT_xstream *xstreams = 72 | (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 73 | ABT_thread *threads = 74 | (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads); 75 | ABT_thread *tasks = (ABT_thread *)malloc(sizeof(ABT_thread) * num_tasks); 76 | 77 | /* Create Execution Streams */ 78 | ret = ABT_xstream_self(&xstreams[0]); 79 | ATS_ERROR(ret, "ABT_xstream_self"); 80 | for (i = 1; i < num_xstreams; i++) { 81 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 82 | ATS_ERROR(ret, "ABT_xstream_create"); 83 | } 84 | 85 | /* Create ULTs for each ES */ 86 | for (i = 0; i < num_threads; i++) { 87 | void *arg = (void *)(uintptr_t)i; 88 | ret = ABT_thread_create_on_xstream(xstreams[i % num_xstreams], 89 | thread_func, arg, 90 | ABT_THREAD_ATTR_NULL, &threads[i]); 91 | ATS_ERROR(ret, "ABT_thread_create_on_xstream"); 92 | } 93 | 94 | /* Create tasklets for each ES */ 95 | for (i = 0; i < num_tasks; i++) { 96 | void *arg = (void *)(uintptr_t)i; 97 | ret = ABT_task_create_on_xstream(xstreams[i % num_xstreams], task_func, 98 | arg, &tasks[i]); 99 | ATS_ERROR(ret, "ABT_task_create_on_xstream"); 100 | } 101 | 102 | /* Join and free ULTs */ 103 | for (i = 0; i < num_threads; i++) { 104 | ret = ABT_thread_free(&threads[i]); 105 | ATS_ERROR(ret, "ABT_thread_join"); 106 | } 107 | 108 | /* Join and free tasklets */ 109 | for (i = 0; i < num_tasks; i++) { 110 | ret = ABT_thread_free(&tasks[i]); 111 | ATS_ERROR(ret, "ABT_thread_free"); 112 | } 113 | 114 | /* Join and free execution streams */ 115 | for (i = 1; i < num_xstreams; i++) { 116 | ret = ABT_xstream_free(&xstreams[i]); 117 | ATS_ERROR(ret, "ABT_xstream_free"); 118 | } 119 | 120 | free(xstreams); 121 | free(threads); 122 | free(tasks); 123 | 124 | /* Finalize */ 125 | ret = ATS_finalize(0); 126 | 127 | return ret; 128 | } 129 | -------------------------------------------------------------------------------- /test/basic/thread_id.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | ATS_UNUSED(arg); 17 | ABT_thread thread; 18 | ABT_unit_id thread_id; 19 | ABT_thread_self(&thread); 20 | ABT_thread_get_id(thread, &thread_id); 21 | ATS_printf(1, "My thread id is %lu\n", thread_id); 22 | } 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | int i, j; 27 | int ret; 28 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 29 | int num_threads = DEFAULT_NUM_THREADS; 30 | if (argc > 1) 31 | num_xstreams = atoi(argv[1]); 32 | assert(num_xstreams >= 0); 33 | if (argc > 2) 34 | num_threads = atoi(argv[2]); 35 | assert(num_threads >= 0); 36 | 37 | ABT_xstream *xstreams; 38 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 39 | 40 | /* Initialize */ 41 | ATS_read_args(argc, argv); 42 | ATS_init(argc, argv, num_xstreams); 43 | 44 | /* Create Execution Streams */ 45 | ret = ABT_xstream_self(&xstreams[0]); 46 | ATS_ERROR(ret, "ABT_xstream_self"); 47 | for (i = 1; i < num_xstreams; i++) { 48 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 49 | ATS_ERROR(ret, "ABT_xstream_create"); 50 | } 51 | 52 | /* Get the pools attached to an execution stream */ 53 | ABT_pool *pools; 54 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 55 | for (i = 0; i < num_xstreams; i++) { 56 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 57 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 58 | } 59 | 60 | /* Create threads */ 61 | for (i = 0; i < num_xstreams; i++) { 62 | for (j = 0; j < num_threads; j++) { 63 | size_t tid = i * num_threads + j + 1; 64 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 65 | ABT_THREAD_ATTR_NULL, NULL); 66 | ATS_ERROR(ret, "ABT_thread_create"); 67 | } 68 | } 69 | 70 | /* Join Execution Streams */ 71 | for (i = 1; i < num_xstreams; i++) { 72 | ret = ABT_xstream_join(xstreams[i]); 73 | ATS_ERROR(ret, "ABT_xstream_join"); 74 | } 75 | 76 | /* Free Execution Streams */ 77 | for (i = 1; i < num_xstreams; i++) { 78 | ret = ABT_xstream_free(&xstreams[i]); 79 | ATS_ERROR(ret, "ABT_xstream_free"); 80 | } 81 | 82 | /* Finalize */ 83 | ret = ATS_finalize(0); 84 | 85 | free(pools); 86 | free(xstreams); 87 | 88 | return ret; 89 | } 90 | -------------------------------------------------------------------------------- /test/basic/thread_migrate.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | int value = 0; 15 | 16 | void thread_func(void *arg) 17 | { 18 | int i; 19 | int ret; 20 | ABT_thread thread; 21 | size_t my_id = (size_t)arg; 22 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 23 | 24 | ABT_thread_self(&thread); 25 | for (i = 0; i < 3; i++) { 26 | ATS_printf(1, "[TH%lu]: request migration ...\n", my_id); 27 | ret = ABT_thread_migrate(thread); 28 | if (ret != ABT_ERR_MIGRATION_NA) 29 | ATS_ERROR(ret, "ABT_thread_migrate"); 30 | } 31 | 32 | __sync_fetch_and_add(&value, 1); 33 | } 34 | 35 | int main(int argc, char *argv[]) 36 | { 37 | int i, j; 38 | int ret; 39 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 40 | int num_threads = DEFAULT_NUM_THREADS; 41 | if (argc > 1) 42 | num_xstreams = atoi(argv[1]); 43 | assert(num_xstreams >= 0); 44 | if (argc > 2) 45 | num_threads = atoi(argv[2]); 46 | assert(num_threads >= 0); 47 | 48 | ABT_xstream *xstreams; 49 | ABT_thread **threads; 50 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 51 | threads = (ABT_thread **)malloc(sizeof(ABT_thread *) * num_xstreams); 52 | for (i = 0; i < num_xstreams; i++) { 53 | threads[i] = (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads); 54 | } 55 | 56 | /* Initialize */ 57 | ATS_read_args(argc, argv); 58 | ATS_init(argc, argv, num_xstreams); 59 | 60 | /* Create Execution Streams */ 61 | ret = ABT_xstream_self(&xstreams[0]); 62 | ATS_ERROR(ret, "ABT_xstream_self"); 63 | for (i = 1; i < num_xstreams; i++) { 64 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 65 | ATS_ERROR(ret, "ABT_xstream_create"); 66 | } 67 | 68 | /* Get the pools attached to an execution stream */ 69 | ABT_pool *pools; 70 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 71 | for (i = 0; i < num_xstreams; i++) { 72 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 73 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 74 | } 75 | 76 | /* Create threads */ 77 | for (i = 0; i < num_xstreams; i++) { 78 | for (j = 0; j < num_threads; j++) { 79 | size_t tid = i * num_threads + j + 1; 80 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 81 | ABT_THREAD_ATTR_NULL, &threads[i][j]); 82 | ATS_ERROR(ret, "ABT_thread_create"); 83 | } 84 | } 85 | 86 | /* Join and free threads */ 87 | for (i = 0; i < num_xstreams; i++) { 88 | for (j = 0; j < num_threads; j++) { 89 | ret = ABT_thread_free(&threads[i][j]); 90 | ATS_ERROR(ret, "ABT_thread_free"); 91 | } 92 | } 93 | 94 | /* Join Execution Streams */ 95 | for (i = 1; i < num_xstreams; i++) { 96 | ret = ABT_xstream_join(xstreams[i]); 97 | ATS_ERROR(ret, "ABT_xstream_join"); 98 | } 99 | 100 | /* Free Execution Streams */ 101 | for (i = 1; i < num_xstreams; i++) { 102 | ret = ABT_xstream_free(&xstreams[i]); 103 | ATS_ERROR(ret, "ABT_xstream_free"); 104 | } 105 | 106 | if (value != num_xstreams * num_threads) 107 | ATS_ERROR(ABT_ERR_OTHER, "wrong value"); 108 | 109 | /* Finalize */ 110 | ret = ATS_finalize(0); 111 | 112 | for (i = 0; i < num_xstreams; i++) { 113 | free(threads[i]); 114 | } 115 | free(threads); 116 | free(pools); 117 | free(xstreams); 118 | 119 | return ret; 120 | } 121 | -------------------------------------------------------------------------------- /test/basic/thread_task_arg.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | #define DEFAULT_NUM_TASKS 4 14 | #define DEFAULT_NUM_ITER 10 15 | 16 | void thread_func(void *arg) 17 | { 18 | ABT_thread self; 19 | int ret; 20 | void *ret_arg = NULL; 21 | 22 | ret = ABT_thread_self(&self); 23 | ATS_ERROR(ret, "ABT_thread_self"); 24 | 25 | ret = ABT_thread_get_arg(self, &ret_arg); 26 | ATS_ERROR(ret, "ABT_thread_get_arg"); 27 | assert(ret_arg == arg); 28 | 29 | ret_arg = NULL; 30 | ret = ABT_self_get_arg(&ret_arg); 31 | ATS_ERROR(ret, "ABT_self_get_arg"); 32 | assert(ret_arg == arg); 33 | } 34 | 35 | void task_func(void *arg) 36 | { 37 | ABT_task self; 38 | int ret; 39 | void *ret_arg = NULL; 40 | 41 | ret = ABT_task_self(&self); 42 | ATS_ERROR(ret, "ABT_task_self"); 43 | 44 | ret = ABT_task_get_arg(self, &ret_arg); 45 | ATS_ERROR(ret, "ABT_task_get_arg"); 46 | assert(ret_arg == arg); 47 | 48 | ret_arg = NULL; 49 | ret = ABT_self_get_arg(&ret_arg); 50 | ATS_ERROR(ret, "ABT_self_get_arg"); 51 | assert(ret_arg == arg); 52 | } 53 | 54 | int main(int argc, char *argv[]) 55 | { 56 | int num_xstreams, num_threads, num_tasks; 57 | ABT_xstream *xstreams; 58 | ABT_pool *pools; 59 | int i, k, ret; 60 | size_t tid; 61 | void *ret_arg; 62 | 63 | /* Initialize */ 64 | ATS_read_args(argc, argv); 65 | if (argc < 2) { 66 | num_xstreams = DEFAULT_NUM_XSTREAMS; 67 | num_threads = DEFAULT_NUM_THREADS; 68 | num_tasks = DEFAULT_NUM_TASKS; 69 | } else { 70 | num_xstreams = ATS_get_arg_val(ATS_ARG_N_ES); 71 | num_threads = ATS_get_arg_val(ATS_ARG_N_ULT); 72 | num_tasks = ATS_get_arg_val(ATS_ARG_N_TASK); 73 | } 74 | ATS_init(argc, argv, num_xstreams); 75 | 76 | ATS_printf(1, "# of ESs : %d\n", num_xstreams); 77 | ATS_printf(1, "# of ULTs/ES : %d\n", num_threads); 78 | ATS_printf(1, "# of tasks/ES: %d\n", num_tasks); 79 | 80 | xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); 81 | pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); 82 | 83 | /* Create ESs */ 84 | ret = ABT_xstream_self(&xstreams[0]); 85 | ATS_ERROR(ret, "ABT_xstream_self"); 86 | for (i = 1; i < num_xstreams; i++) { 87 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 88 | ATS_ERROR(ret, "ABT_xstream_create"); 89 | } 90 | 91 | /* Get the pool associated with each ES */ 92 | for (i = 0; i < num_xstreams; i++) { 93 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); 94 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 95 | } 96 | 97 | /* Create ULTs and tasklets for each ES */ 98 | for (i = 0; i < num_xstreams; i++) { 99 | for (k = 0; k < num_threads; k++) { 100 | tid = i * num_threads + k; 101 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 102 | ABT_THREAD_ATTR_NULL, NULL); 103 | ATS_ERROR(ret, "ABT_thread_create"); 104 | } 105 | 106 | for (k = 0; k < num_tasks; k++) { 107 | tid = i * num_tasks + k; 108 | ret = ABT_task_create(pools[i], task_func, (void *)tid, NULL); 109 | } 110 | } 111 | 112 | ret = ABT_self_get_arg(&ret_arg); 113 | ATS_ERROR(ret, "ABT_self_get_arg"); 114 | assert(ret_arg == NULL); 115 | 116 | /* Join and free ESs */ 117 | for (i = 1; i < num_xstreams; i++) { 118 | ret = ABT_xstream_join(xstreams[i]); 119 | ATS_ERROR(ret, "ABT_xstream_join"); 120 | ret = ABT_xstream_free(&xstreams[i]); 121 | ATS_ERROR(ret, "ABT_xstream_free"); 122 | } 123 | 124 | /* Finalize */ 125 | ret = ATS_finalize(0); 126 | 127 | free(xstreams); 128 | free(pools); 129 | 130 | return ret; 131 | } 132 | -------------------------------------------------------------------------------- /test/basic/thread_task_num.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_THREADS 4 12 | #define DEFAULT_NUM_TASKS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | ATS_UNUSED(arg); 17 | /* Do nothing */ 18 | } 19 | 20 | void task_func(void *arg) 21 | { 22 | ATS_UNUSED(arg); 23 | /* Do nothing */ 24 | } 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | int i, ret; 29 | int num_threads = DEFAULT_NUM_THREADS; 30 | int num_tasks = DEFAULT_NUM_TASKS; 31 | if (argc > 1) 32 | num_threads = atoi(argv[1]); 33 | assert(num_threads >= 0); 34 | if (argc > 2) 35 | num_tasks = atoi(argv[2]); 36 | assert(num_tasks >= 0); 37 | 38 | unsigned long num_units = (unsigned long)(num_threads + num_tasks); 39 | 40 | ABT_xstream xstream; 41 | size_t n_units; 42 | size_t pool_size; 43 | int err = 0; 44 | 45 | /* Initialize */ 46 | ATS_read_args(argc, argv); 47 | ATS_init(argc, argv, 1); 48 | 49 | /* Get the SELF Execution Stream */ 50 | ret = ABT_xstream_self(&xstream); 51 | ATS_ERROR(ret, "ABT_xstream_self"); 52 | 53 | /* Get the pools attached to an execution stream */ 54 | ABT_pool pool; 55 | ret = ABT_xstream_get_main_pools(xstream, 1, &pool); 56 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 57 | 58 | /* Create ULTs */ 59 | for (i = 0; i < num_threads; i++) { 60 | ret = ABT_thread_create(pool, thread_func, NULL, ABT_THREAD_ATTR_NULL, 61 | NULL); 62 | ATS_ERROR(ret, "ABT_thread_create"); 63 | } 64 | 65 | /* Create tasklets */ 66 | for (i = 0; i < num_tasks; i++) { 67 | ret = ABT_task_create(pool, task_func, NULL, NULL); 68 | ATS_ERROR(ret, "ABT_task_create"); 69 | } 70 | 71 | /* Get the numbers of ULTs and tasklets */ 72 | ABT_sched sched; 73 | ret = ABT_xstream_get_main_sched(xstream, &sched); 74 | ATS_ERROR(ret, "ABT_xstream_get_main_sched"); 75 | ABT_sched_get_total_size(sched, &n_units); 76 | ATS_ERROR(ret, "ABT_sched_get_total_size"); 77 | 78 | if (n_units != num_units) { 79 | err++; 80 | printf("# of units: expected(%lu) vs. result(%lu)\n", num_units, 81 | (unsigned long)n_units); 82 | } 83 | 84 | do { 85 | /* Switch to other work units */ 86 | ABT_thread_yield(); 87 | ret = ABT_pool_get_size(pool, &pool_size); 88 | ATS_ERROR(ret, "ABT_pool_get_size"); 89 | } while (pool_size > 0); 90 | 91 | /* Get the numbers of ULTs and tasklets */ 92 | ret = ABT_sched_get_total_size(sched, &n_units); 93 | ATS_ERROR(ret, "ABT_sched_get_total_size"); 94 | if (n_units != 0) { 95 | err++; 96 | printf("# of units: expected(%d) vs. result(%lu)\n", 0, 97 | (unsigned long)n_units); 98 | } 99 | 100 | /* Finalize */ 101 | ret = ATS_finalize(err); 102 | 103 | return ret; 104 | } 105 | -------------------------------------------------------------------------------- /test/basic/thread_yield.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ATS_printf(1, "[TH%lu]: before yield\n", my_id); 18 | ABT_thread_yield(); 19 | ATS_printf(1, "[TH%lu]: doing something ...\n", my_id); 20 | ABT_thread_yield(); 21 | ATS_printf(1, "[TH%lu]: after yield\n", my_id); 22 | } 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | int i, j; 27 | int ret; 28 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 29 | int num_threads = DEFAULT_NUM_THREADS; 30 | if (argc > 1) 31 | num_xstreams = atoi(argv[1]); 32 | assert(num_xstreams >= 0); 33 | if (argc > 2) 34 | num_threads = atoi(argv[2]); 35 | assert(num_threads >= 0); 36 | 37 | ABT_xstream *xstreams; 38 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 39 | 40 | /* Initialize */ 41 | ATS_read_args(argc, argv); 42 | ATS_init(argc, argv, num_xstreams); 43 | 44 | /* Create Execution Streams */ 45 | ret = ABT_xstream_self(&xstreams[0]); 46 | ATS_ERROR(ret, "ABT_xstream_self"); 47 | for (i = 1; i < num_xstreams; i++) { 48 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 49 | ATS_ERROR(ret, "ABT_xstream_create"); 50 | } 51 | 52 | /* Get the pools attached to an execution stream */ 53 | ABT_pool *pools; 54 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 55 | for (i = 0; i < num_xstreams; i++) { 56 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 57 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 58 | } 59 | 60 | /* Create threads */ 61 | for (i = 0; i < num_xstreams; i++) { 62 | for (j = 0; j < num_threads; j++) { 63 | size_t tid = i * num_threads + j + 1; 64 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 65 | ABT_THREAD_ATTR_NULL, NULL); 66 | ATS_ERROR(ret, "ABT_thread_create"); 67 | } 68 | } 69 | 70 | /* Join Execution Streams */ 71 | for (i = 1; i < num_xstreams; i++) { 72 | ret = ABT_xstream_join(xstreams[i]); 73 | ATS_ERROR(ret, "ABT_xstream_join"); 74 | } 75 | 76 | /* Free Execution Streams */ 77 | for (i = 1; i < num_xstreams; i++) { 78 | ret = ABT_xstream_free(&xstreams[i]); 79 | ATS_ERROR(ret, "ABT_xstream_free"); 80 | } 81 | 82 | /* Finalize */ 83 | ret = ATS_finalize(0); 84 | 85 | free(pools); 86 | free(xstreams); 87 | 88 | return ret; 89 | } 90 | -------------------------------------------------------------------------------- /test/basic/xstream_barrier.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_ITER 10 13 | 14 | static int num_iter = DEFAULT_NUM_ITER; 15 | static ABT_xstream_barrier barrier = ABT_XSTREAM_BARRIER_NULL; 16 | /* Neither volatile nor atomic operation is necessary for value, but PGI-20.1 is 17 | * broken so we need a workaround to make PGI pass this test. 18 | * See https://github.com/pmodels/argobots/issues/213 for details. */ 19 | volatile int value; 20 | 21 | void test_xstream_barrier(void *arg) 22 | { 23 | int rank = (int)(intptr_t)arg; 24 | int i, ret; 25 | 26 | for (i = 0; i < num_iter; i++) { 27 | if (rank == 0) 28 | ATS_atomic_store(&value, i); 29 | ret = ABT_xstream_barrier_wait(barrier); 30 | ATS_ERROR(ret, "ABT_xstream_barrier_wait"); 31 | 32 | assert(ATS_atomic_load(&value) == i); 33 | ret = ABT_xstream_barrier_wait(barrier); 34 | ATS_ERROR(ret, "ABT_xstream_barrier_wait"); 35 | } 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | int i, ret; 41 | ABT_xstream *xstreams; 42 | ABT_pool *pools; 43 | ABT_thread *threads; 44 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 45 | 46 | /* Initialize */ 47 | ATS_read_args(argc, argv); 48 | if (argc >= 2) { 49 | num_xstreams = ATS_get_arg_val(ATS_ARG_N_ES); 50 | num_iter = ATS_get_arg_val(ATS_ARG_N_ITER); 51 | } 52 | ATS_init(argc, argv, num_xstreams); 53 | 54 | ATS_printf(1, "# of ESs : %d\n", num_xstreams); 55 | ATS_printf(1, "# of iterations: %d\n", num_iter); 56 | 57 | /* Create an ES barrier */ 58 | ret = ABT_xstream_barrier_create(num_xstreams, &barrier); 59 | ATS_ERROR(ret, "ABT_xstream_barrier_create"); 60 | 61 | xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); 62 | pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); 63 | threads = (ABT_thread *)malloc(num_xstreams * sizeof(ABT_thread)); 64 | 65 | /* Create Execution Streams */ 66 | ret = ABT_xstream_self(&xstreams[0]); 67 | ATS_ERROR(ret, "ABT_xstream_self"); 68 | for (i = 1; i < num_xstreams; i++) { 69 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 70 | ATS_ERROR(ret, "ABT_xstream_create"); 71 | } 72 | 73 | /* Get the first pool of each ES */ 74 | for (i = 0; i < num_xstreams; i++) { 75 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); 76 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 77 | } 78 | 79 | /* Create one ULT for each ES */ 80 | for (i = 1; i < num_xstreams; i++) { 81 | ret = ABT_thread_create(pools[i], test_xstream_barrier, 82 | (void *)(intptr_t)i, ABT_THREAD_ATTR_NULL, 83 | &threads[i]); 84 | ATS_ERROR(ret, "ABT_thread_create"); 85 | } 86 | 87 | test_xstream_barrier((void *)0); 88 | 89 | /* Join and free ULTs */ 90 | for (i = 1; i < num_xstreams; i++) { 91 | ret = ABT_thread_free(&threads[i]); 92 | ATS_ERROR(ret, "ABT_thread_free"); 93 | } 94 | 95 | /* Join and free ESs */ 96 | for (i = 1; i < num_xstreams; i++) { 97 | ret = ABT_xstream_join(xstreams[i]); 98 | ATS_ERROR(ret, "ABT_xstream_join"); 99 | ret = ABT_xstream_free(&xstreams[i]); 100 | ATS_ERROR(ret, "ABT_xstream_free"); 101 | } 102 | 103 | /* Free the ES barrier */ 104 | ret = ABT_xstream_barrier_free(&barrier); 105 | ATS_ERROR(ret, "ABT_xstream_barrier_free"); 106 | 107 | /* Finalize */ 108 | ret = ATS_finalize(0); 109 | 110 | free(xstreams); 111 | free(pools); 112 | free(threads); 113 | 114 | return ret; 115 | } 116 | -------------------------------------------------------------------------------- /test/basic/xstream_create.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | ABT_xstream *xstreams; 16 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 17 | int i; 18 | int ret, tmp; 19 | 20 | /* Initialize */ 21 | ATS_read_args(argc, argv); 22 | if (argc > 1) { 23 | num_xstreams = ATS_get_arg_val(ATS_ARG_N_ES); 24 | } 25 | ATS_init(argc, argv, num_xstreams); 26 | 27 | ATS_printf(1, "# of ESs: %d\n", num_xstreams); 28 | 29 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 30 | assert(xstreams != NULL); 31 | 32 | /* Create Execution Streams */ 33 | ret = ABT_xstream_self(&xstreams[0]); 34 | ATS_ERROR(ret, "ABT_xstream_self"); 35 | for (i = 1; i < num_xstreams; i++) { 36 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 37 | ATS_ERROR(ret, "ABT_xstream_create"); 38 | } 39 | 40 | /* Get the number of Execution Streams */ 41 | ret = ABT_xstream_get_num(&tmp); 42 | ATS_ERROR(ret, "ABT_xstream_get_num"); 43 | assert(tmp == num_xstreams); 44 | 45 | /* Join Execution Streams */ 46 | for (i = 1; i < num_xstreams; i++) { 47 | ret = ABT_xstream_join(xstreams[i]); 48 | ATS_ERROR(ret, "ABT_xstream_join"); 49 | } 50 | 51 | /* Free Execution Streams */ 52 | for (i = 1; i < num_xstreams; i++) { 53 | ret = ABT_xstream_free(&xstreams[i]); 54 | ATS_ERROR(ret, "ABT_xstream_free"); 55 | } 56 | 57 | /* Finalize */ 58 | ret = ATS_finalize(0); 59 | 60 | free(xstreams); 61 | 62 | return ret; 63 | } 64 | -------------------------------------------------------------------------------- /test/basic/xstream_rank.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | ABT_xstream *xstreams; 16 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 17 | int i, ret; 18 | int rank; 19 | 20 | /* Initialize */ 21 | ATS_read_args(argc, argv); 22 | if (argc > 1) { 23 | num_xstreams = ATS_get_arg_val(ATS_ARG_N_ES); 24 | } 25 | ATS_init(argc, argv, num_xstreams); 26 | 27 | ATS_printf(1, "# of ESs: %d\n", num_xstreams); 28 | 29 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 30 | assert(xstreams != NULL); 31 | 32 | /* Create Execution Streams */ 33 | ret = ABT_xstream_self(&xstreams[0]); 34 | ATS_ERROR(ret, "ABT_xstream_self"); 35 | for (i = 1; i < num_xstreams; i++) { 36 | rank = num_xstreams - i; 37 | ret = ABT_xstream_create_with_rank(ABT_SCHED_NULL, rank, &xstreams[i]); 38 | ATS_ERROR(ret, "ABT_xstream_create_with_rank"); 39 | } 40 | 41 | /* Check the rank of each ES */ 42 | for (i = 1; i < num_xstreams; i++) { 43 | ret = ABT_xstream_get_rank(xstreams[i], &rank); 44 | ATS_ERROR(ret, "ABT_xstream_get_rank"); 45 | assert(rank == (num_xstreams - i)); 46 | } 47 | 48 | /* Test an invalid rank, which is already taken */ 49 | ABT_bool is_check_error = ABT_FALSE; 50 | ret = ABT_info_query_config(ABT_INFO_QUERY_KIND_ENABLED_CHECK_ERROR, 51 | (void *)&is_check_error); 52 | ATS_ERROR(ret, "ABT_info_query_config"); 53 | if (is_check_error) { 54 | ABT_xstream tmp; 55 | ret = ABT_xstream_create_with_rank(ABT_SCHED_NULL, 0, &tmp); 56 | assert(ret == ABT_ERR_INV_XSTREAM_RANK); 57 | } 58 | 59 | /* Join and free ESs */ 60 | for (i = 1; i < num_xstreams; i++) { 61 | ret = ABT_xstream_join(xstreams[i]); 62 | ATS_ERROR(ret, "ABT_xstream_join"); 63 | ret = ABT_xstream_free(&xstreams[i]); 64 | ATS_ERROR(ret, "ABT_xstream_free"); 65 | } 66 | 67 | /* Finalize */ 68 | ret = ATS_finalize(0); 69 | 70 | free(xstreams); 71 | 72 | return ret; 73 | } 74 | -------------------------------------------------------------------------------- /test/basic/xstream_revive.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | #define DEFAULT_NUM_XSTREAMS 4 12 | #define DEFAULT_NUM_THREADS 4 13 | 14 | void thread_func(void *arg) 15 | { 16 | size_t my_id = (size_t)arg; 17 | ATS_printf(1, "[TH%lu]: Hello, world!\n", my_id); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | int i, j, step; 23 | int ret; 24 | int num_xstreams = DEFAULT_NUM_XSTREAMS; 25 | int num_threads = DEFAULT_NUM_THREADS; 26 | if (argc > 1) 27 | num_xstreams = atoi(argv[1]); 28 | assert(num_xstreams >= 0); 29 | if (argc > 2) 30 | num_threads = atoi(argv[2]); 31 | assert(num_threads >= 0); 32 | 33 | ABT_xstream *xstreams; 34 | xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); 35 | 36 | ABT_pool *pools; 37 | pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); 38 | 39 | /* Initialize */ 40 | ATS_read_args(argc, argv); 41 | ATS_init(argc, argv, num_xstreams); 42 | 43 | /* Create Execution Streams */ 44 | ret = ABT_xstream_self(&xstreams[0]); 45 | ATS_ERROR(ret, "ABT_xstream_self"); 46 | for (i = 1; i < num_xstreams; i++) { 47 | ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); 48 | ATS_ERROR(ret, "ABT_xstream_create"); 49 | } 50 | 51 | /* Get the pools attached to an execution stream */ 52 | for (i = 0; i < num_xstreams; i++) { 53 | ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools + i); 54 | ATS_ERROR(ret, "ABT_xstream_get_main_pools"); 55 | } 56 | 57 | for (step = 0; step < 5; step++) { 58 | if (step != 0) { 59 | /* Revive Execution Streams */ 60 | for (i = 1; i < num_xstreams; i++) { 61 | ret = ABT_xstream_revive(xstreams[i]); 62 | ATS_ERROR(ret, "ABT_xstream_revive"); 63 | } 64 | } 65 | /* Create threads */ 66 | for (i = 0; i < num_xstreams; i++) { 67 | for (j = 0; j < num_threads; j++) { 68 | size_t tid = i * num_threads + j + 1; 69 | ret = ABT_thread_create(pools[i], thread_func, (void *)tid, 70 | ABT_THREAD_ATTR_NULL, NULL); 71 | ATS_ERROR(ret, "ABT_thread_create"); 72 | } 73 | } 74 | /* Join Execution Streams */ 75 | for (i = 1; i < num_xstreams; i++) { 76 | ret = ABT_xstream_join(xstreams[i]); 77 | ATS_ERROR(ret, "ABT_xstream_join"); 78 | } 79 | } 80 | 81 | /* Free Execution Streams */ 82 | for (i = 1; i < num_xstreams; i++) { 83 | ret = ABT_xstream_free(&xstreams[i]); 84 | ATS_ERROR(ret, "ABT_xstream_free"); 85 | } 86 | 87 | /* Finalize */ 88 | ret = ATS_finalize(0); 89 | 90 | free(pools); 91 | free(xstreams); 92 | 93 | return ret; 94 | } 95 | -------------------------------------------------------------------------------- /test/benchmark/init_finalize.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "abt.h" 9 | #include "abttest.h" 10 | 11 | enum { 12 | T_INIT_FINALIZE_COLD = 0, 13 | T_INIT, 14 | T_FINALIZE, 15 | T_INIT_FINALIZE, 16 | T_INIT_FINALIZE_WITH_WORK, 17 | T_LAST 18 | }; 19 | 20 | static char *t_names[] = { "init/finalize (cold)", "init", "finalize", 21 | "init/finalize", "init/finalize with work" }; 22 | 23 | static double t_timers[T_LAST]; 24 | 25 | void thread_func(void *arg) 26 | { 27 | ATS_UNUSED(arg); 28 | } 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | ABT_xstream xstream; 33 | ABT_pool pool; 34 | ABT_timer timer; 35 | int i, iter; 36 | double t_overhead; 37 | 38 | ATS_read_args(argc, argv); 39 | iter = ATS_get_arg_val(ATS_ARG_N_ITER); 40 | 41 | ABT_timer_create(&timer); 42 | ABT_timer_start(timer); 43 | ABT_timer_stop(timer); 44 | ABT_timer_get_overhead(&t_overhead); 45 | for (i = 0; i < T_LAST; i++) 46 | t_timers[i] = 0.0; 47 | 48 | /* measure init/finalize time (cold) */ 49 | ABT_timer_start(timer); 50 | ATS_init(argc, argv, 2); 51 | ATS_finalize(0); 52 | ABT_timer_stop_and_read(timer, &t_timers[T_INIT_FINALIZE_COLD]); 53 | t_timers[T_INIT_FINALIZE_COLD] -= t_overhead; 54 | 55 | /* measure init/finalize time */ 56 | for (i = 0; i < iter; i++) { 57 | ABT_timer_start(timer); 58 | ABT_init(argc, argv); 59 | ABT_timer_stop_and_add(timer, &t_timers[T_INIT]); 60 | 61 | ABT_timer_start(timer); 62 | ABT_finalize(); 63 | ABT_timer_stop_and_add(timer, &t_timers[T_FINALIZE]); 64 | } 65 | t_timers[T_INIT] /= iter; 66 | t_timers[T_INIT] -= t_overhead; 67 | t_timers[T_FINALIZE] /= iter; 68 | t_timers[T_FINALIZE] -= t_overhead; 69 | t_timers[T_INIT_FINALIZE] = t_timers[T_INIT] + t_timers[T_FINALIZE]; 70 | 71 | /* measure time of init/finalize with work */ 72 | for (i = 0; i < iter; i++) { 73 | ABT_timer_start(timer); 74 | ABT_init(argc, argv); 75 | ABT_timer_stop_and_add(timer, &t_timers[T_INIT_FINALIZE_WITH_WORK]); 76 | 77 | ABT_xstream_create(ABT_SCHED_NULL, &xstream); 78 | ABT_xstream_get_main_pools(xstream, 1, &pool); 79 | ABT_thread_create(pool, thread_func, NULL, ABT_THREAD_ATTR_NULL, NULL); 80 | ABT_xstream_join(xstream); 81 | ABT_xstream_free(&xstream); 82 | 83 | ABT_timer_start(timer); 84 | ABT_finalize(); 85 | ABT_timer_stop_and_add(timer, &t_timers[T_INIT_FINALIZE_WITH_WORK]); 86 | } 87 | t_timers[T_INIT_FINALIZE_WITH_WORK] /= iter; 88 | t_timers[T_INIT_FINALIZE_WITH_WORK] -= t_overhead; 89 | 90 | /* output */ 91 | int line_size = 45; 92 | ATS_print_line(stdout, '-', line_size); 93 | printf("Avg. execution time (in seconds, %d times)\n", iter); 94 | ATS_print_line(stdout, '-', line_size); 95 | for (i = 0; i < T_LAST; i++) { 96 | printf("%-23s %.9f\n", t_names[i], t_timers[i]); 97 | } 98 | ATS_print_line(stdout, '-', line_size); 99 | 100 | ABT_timer_free(&timer); 101 | 102 | return EXIT_SUCCESS; 103 | } 104 | -------------------------------------------------------------------------------- /test/leakcheck/.gitignore: -------------------------------------------------------------------------------- 1 | librtrace* 2 | affinity 3 | barrier 4 | cond 5 | eventual 6 | future 7 | init_finalize 8 | key 9 | mutex 10 | pool 11 | rwlock 12 | sched 13 | thread 14 | timer 15 | unit 16 | xstream 17 | xstream_barrier 18 | -------------------------------------------------------------------------------- /test/leakcheck/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | TESTS = \ 7 | affinity \ 8 | barrier \ 9 | cond \ 10 | eventual \ 11 | future \ 12 | init_finalize \ 13 | key \ 14 | mutex \ 15 | pool \ 16 | rwlock \ 17 | sched \ 18 | thread \ 19 | timer \ 20 | unit \ 21 | xstream \ 22 | xstream_barrier 23 | 24 | check_PROGRAMS = $(TESTS) 25 | noinst_PROGRAMS = $(TESTS) 26 | 27 | noinst_LTLIBRARIES = librtrace.la 28 | 29 | librtrace_la_SOURCES = rtrace.c 30 | librtrace_la_LIBADD = @ABT_RT_LDFLAGS@ 31 | 32 | if ABT_CONFIG_DISABLE_ERROR_CHECK 33 | # Do not compile rtrace with -DABT_RT_USE_DLVSYM 34 | librtrace_la_CFLAGS = 35 | else 36 | librtrace_la_CFLAGS = @ABT_RT_CFLAGS@ 37 | endif 38 | librtrace_la_LDFLAGS = $(all_libraries) 39 | # librtrace_la_CFLAGS = -fpic -shared 40 | 41 | include $(top_srcdir)/test/Makefile.mk 42 | 43 | LDADD += librtrace.la 44 | 45 | testing: 46 | -------------------------------------------------------------------------------- /test/leakcheck/affinity.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "rtrace.h" 10 | #include "util.h" 11 | 12 | /* Check ABT_init() and ABT_finalize(). */ 13 | 14 | void program(int must_succeed) 15 | { 16 | int ret; 17 | ret = ABT_init(0, 0); 18 | assert(!must_succeed || ret == ABT_SUCCESS); 19 | if (ret == ABT_SUCCESS) { 20 | ret = ABT_finalize(); 21 | /* This ABT_finalize() should not fail. */ 22 | assert(ret == ABT_SUCCESS); 23 | } 24 | } 25 | 26 | char *legal_affinity_strs[] = { "++1", "1:2,{1:2}" }; 27 | 28 | char *illegal_affinity_strs[] = { "{}", "1:1:1:1", "{1:2:3}:2:" }; 29 | 30 | int main() 31 | { 32 | int i; 33 | setup_env(); 34 | rtrace_init(); 35 | 36 | for (i = 0; i < (int)(sizeof(legal_affinity_strs) / 37 | sizeof(legal_affinity_strs[0])); 38 | i++) { 39 | int ret = setenv("ABT_SET_AFFINITY", legal_affinity_strs[i], 1); 40 | assert(ret == 0); 41 | if (use_rtrace()) { 42 | do { 43 | rtrace_start(); 44 | program(0); 45 | } while (!rtrace_stop()); 46 | } 47 | /* If no failure, it should succeed again. */ 48 | program(1); 49 | } 50 | /* Currently Argobots silently ignores an illegal affinity string. */ 51 | for (i = 0; i < (int)(sizeof(illegal_affinity_strs) / 52 | sizeof(illegal_affinity_strs[0])); 53 | i++) { 54 | int ret = setenv("ABT_SET_AFFINITY", illegal_affinity_strs[i], 1); 55 | assert(ret == 0); 56 | if (use_rtrace()) { 57 | do { 58 | rtrace_start(); 59 | program(0); 60 | } while (!rtrace_stop()); 61 | } 62 | /* If no failure, it should succeed again. */ 63 | program(1); 64 | } 65 | 66 | rtrace_finalize(); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /test/leakcheck/barrier.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "rtrace.h" 10 | #include "util.h" 11 | 12 | /* Check ABT_barrier. */ 13 | 14 | void thread_func(void *arg) 15 | { 16 | int ret = ABT_barrier_wait((ABT_barrier)arg); 17 | assert(ret == ABT_SUCCESS); 18 | } 19 | 20 | void *pthread_func(void *arg) 21 | { 22 | thread_func(arg); 23 | return NULL; 24 | } 25 | 26 | void program(int must_succeed) 27 | { 28 | int ret; 29 | rtrace_set_enabled(0); 30 | /* Checking ABT_init() should be done by other tests. */ 31 | ret = ABT_init(0, 0); 32 | assert(ret == ABT_SUCCESS); 33 | rtrace_set_enabled(1); 34 | 35 | ABT_barrier barrier = (ABT_barrier)RAND_PTR; 36 | ret = ABT_barrier_create(2, &barrier); 37 | assert(!must_succeed || ret == ABT_SUCCESS); 38 | if (ret == ABT_SUCCESS) { 39 | /* Make it large. */ 40 | ret = ABT_barrier_reinit(barrier, 128); 41 | assert(!must_succeed || ret == ABT_SUCCESS); 42 | if (ret == ABT_SUCCESS) { 43 | /* Shrink again. */ 44 | ret = ABT_barrier_reinit(barrier, 2); 45 | assert(!must_succeed || ret == ABT_SUCCESS); 46 | if (ret != ABT_SUCCESS) { 47 | /* If shrink fails, we cannot continue this test. */ 48 | ret = ABT_barrier_free(&barrier); 49 | assert(ret == ABT_SUCCESS && barrier == ABT_BARRIER_NULL); 50 | goto FINISH_TEST; 51 | } 52 | } 53 | /* Now # of waiters must be 2. */ 54 | uint32_t num_waiters; 55 | ret = ABT_barrier_get_num_waiters(barrier, &num_waiters); 56 | assert(ret == ABT_SUCCESS && num_waiters == 2); 57 | /* If an external thread is supported, use an external thread. */ 58 | ABT_bool external_thread_support; 59 | ret = ABT_info_query_config(ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD, 60 | &external_thread_support); 61 | assert(ret == ABT_SUCCESS); 62 | if (external_thread_support) { 63 | pthread_t pthread; 64 | ret = pthread_create(&pthread, NULL, pthread_func, (void *)barrier); 65 | assert(!must_succeed || ret == 0); 66 | if (ret == 0) { 67 | ret = ABT_barrier_wait(barrier); 68 | assert(ret == ABT_SUCCESS); 69 | ret = pthread_join(pthread, NULL); 70 | assert(ret == 0); 71 | } 72 | } 73 | /* Create a ULT and wait on a barrier together. */ 74 | ABT_xstream self_xstream; 75 | ret = ABT_self_get_xstream(&self_xstream); 76 | assert(ret == ABT_SUCCESS); 77 | ABT_thread thread = (ABT_thread)RAND_PTR; 78 | ret = ABT_thread_create_on_xstream(self_xstream, thread_func, 79 | (void *)barrier, 80 | ABT_THREAD_ATTR_NULL, &thread); 81 | assert(!must_succeed || ret == ABT_SUCCESS); 82 | if (ret == ABT_SUCCESS) { 83 | ret = ABT_barrier_wait(barrier); 84 | assert(ret == ABT_SUCCESS); 85 | ret = ABT_thread_free(&thread); 86 | assert(ret == ABT_SUCCESS && thread == ABT_THREAD_NULL); 87 | } else { 88 | #ifdef ABT_ENABLE_VER_20_API 89 | assert(thread == (ABT_thread)RAND_PTR); 90 | #else 91 | assert(thread == ABT_THREAD_NULL); 92 | #endif 93 | } 94 | /* Free barrier. */ 95 | ret = ABT_barrier_free(&barrier); 96 | assert(ret == ABT_SUCCESS && barrier == ABT_BARRIER_NULL); 97 | } else { 98 | #ifdef ABT_ENABLE_VER_20_API 99 | assert(barrier == (ABT_barrier)RAND_PTR); 100 | #else 101 | assert(barrier == ABT_BARRIER_NULL); 102 | #endif 103 | } 104 | 105 | FINISH_TEST: 106 | ret = ABT_finalize(); 107 | assert(ret == ABT_SUCCESS); 108 | } 109 | 110 | int main() 111 | { 112 | setup_env(); 113 | rtrace_init(); 114 | 115 | if (use_rtrace()) { 116 | do { 117 | rtrace_start(); 118 | program(0); 119 | } while (!rtrace_stop()); 120 | } 121 | 122 | /* If no failure, it should succeed again. */ 123 | program(1); 124 | 125 | rtrace_finalize(); 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /test/leakcheck/eventual.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "rtrace.h" 10 | #include "util.h" 11 | 12 | /* Check ABT_eventual. */ 13 | 14 | void thread_func(void *arg) 15 | { 16 | int ret; 17 | ret = ABT_eventual_wait((ABT_eventual)arg, NULL); 18 | assert(ret == ABT_SUCCESS); 19 | ABT_bool is_ready; 20 | ret = ABT_eventual_test((ABT_eventual)arg, NULL, &is_ready); 21 | assert(ret == ABT_SUCCESS && is_ready == ABT_TRUE); 22 | } 23 | 24 | void *pthread_func(void *arg) 25 | { 26 | thread_func(arg); 27 | return NULL; 28 | } 29 | 30 | void program(int must_succeed) 31 | { 32 | int ret, i; 33 | rtrace_set_enabled(0); 34 | /* Checking ABT_init() should be done by other tests. */ 35 | ret = ABT_init(0, 0); 36 | assert(ret == ABT_SUCCESS); 37 | rtrace_set_enabled(1); 38 | 39 | for (i = 0; i < 2; i++) { 40 | int nbytes = i * 128; 41 | ABT_eventual eventual = (ABT_eventual)RAND_PTR; 42 | ret = ABT_eventual_create(nbytes, &eventual); 43 | assert(!must_succeed || ret == ABT_SUCCESS); 44 | if (ret == ABT_SUCCESS) { 45 | /* If an external thread is supported, use an external thread. */ 46 | ABT_bool external_thread_support; 47 | ret = ABT_info_query_config( 48 | ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD, 49 | &external_thread_support); 50 | assert(ret == ABT_SUCCESS); 51 | if (external_thread_support) { 52 | pthread_t pthread; 53 | ret = pthread_create(&pthread, NULL, pthread_func, 54 | (void *)eventual); 55 | assert(!must_succeed || ret == 0); 56 | if (ret == 0) { 57 | ret = ABT_eventual_set(eventual, NULL, 0); 58 | assert(ret == ABT_SUCCESS); 59 | ret = pthread_join(pthread, NULL); 60 | assert(ret == 0); 61 | ret = ABT_eventual_reset(eventual); 62 | assert(ret == ABT_SUCCESS); 63 | } 64 | } 65 | /* Create a ULT and synchronize it with eventual. */ 66 | ABT_xstream self_xstream; 67 | ret = ABT_self_get_xstream(&self_xstream); 68 | assert(ret == ABT_SUCCESS); 69 | ABT_thread thread = (ABT_thread)RAND_PTR; 70 | ret = ABT_thread_create_on_xstream(self_xstream, thread_func, 71 | (void *)eventual, 72 | ABT_THREAD_ATTR_NULL, &thread); 73 | assert(!must_succeed || ret == ABT_SUCCESS); 74 | if (ret == ABT_SUCCESS) { 75 | ret = ABT_eventual_set(eventual, NULL, 0); 76 | assert(ret == ABT_SUCCESS); 77 | ret = ABT_thread_free(&thread); 78 | assert(ret == ABT_SUCCESS && thread == ABT_THREAD_NULL); 79 | } else { 80 | #ifdef ABT_ENABLE_VER_20_API 81 | assert(thread == (ABT_thread)RAND_PTR); 82 | #else 83 | assert(thread == ABT_THREAD_NULL); 84 | #endif 85 | } 86 | /* Free eventual. */ 87 | ret = ABT_eventual_free(&eventual); 88 | assert(ret == ABT_SUCCESS && eventual == ABT_EVENTUAL_NULL); 89 | } else { 90 | assert(eventual == (ABT_eventual)RAND_PTR); 91 | } 92 | } 93 | 94 | ret = ABT_finalize(); 95 | assert(ret == ABT_SUCCESS); 96 | } 97 | 98 | int main() 99 | { 100 | setup_env(); 101 | rtrace_init(); 102 | 103 | if (use_rtrace()) { 104 | do { 105 | rtrace_start(); 106 | program(0); 107 | } while (!rtrace_stop()); 108 | } 109 | 110 | /* If no failure, it should succeed again. */ 111 | program(1); 112 | 113 | rtrace_finalize(); 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /test/leakcheck/init_finalize.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "rtrace.h" 9 | #include "util.h" 10 | 11 | /* Check ABT_init() and ABT_finalize(). */ 12 | 13 | void program(int must_succeed) 14 | { 15 | int ret; 16 | ret = ABT_init(0, 0); 17 | assert(!must_succeed || ret == ABT_SUCCESS); 18 | if (ret == ABT_SUCCESS) { 19 | ret = ABT_finalize(); 20 | /* This ABT_finalize() should not fail. */ 21 | assert(ret == ABT_SUCCESS); 22 | } 23 | } 24 | 25 | int main() 26 | { 27 | setup_env(); 28 | rtrace_init(); 29 | 30 | if (use_rtrace()) { 31 | do { 32 | rtrace_start(); 33 | program(0); 34 | } while (!rtrace_stop()); 35 | } 36 | 37 | /* If no failure, it should succeed again. */ 38 | program(1); 39 | 40 | rtrace_finalize(); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /test/leakcheck/rwlock.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "rtrace.h" 10 | #include "util.h" 11 | 12 | /* Check ABT_rwlock. */ 13 | 14 | void thread_func(void *arg) 15 | { 16 | int ret, i, repeat; 17 | ABT_rwlock rwlock = (ABT_rwlock)arg; 18 | for (repeat = 0; repeat < 100; repeat++) { 19 | for (i = 0; i < 5; i++) { 20 | ret = ABT_rwlock_rdlock(rwlock); 21 | assert(ret == ABT_SUCCESS); 22 | } 23 | for (i = 0; i < 5; i++) { 24 | ret = ABT_rwlock_unlock(rwlock); 25 | assert(ret == ABT_SUCCESS); 26 | } 27 | ret = ABT_rwlock_wrlock(rwlock); 28 | assert(ret == ABT_SUCCESS); 29 | ret = ABT_rwlock_unlock(rwlock); 30 | assert(ret == ABT_SUCCESS); 31 | } 32 | } 33 | 34 | void *pthread_func(void *arg) 35 | { 36 | thread_func(arg); 37 | return NULL; 38 | } 39 | 40 | void program(int must_succeed) 41 | { 42 | int ret; 43 | rtrace_set_enabled(0); 44 | /* Checking ABT_init() should be done by other tests. */ 45 | ret = ABT_init(0, 0); 46 | assert(ret == ABT_SUCCESS); 47 | rtrace_set_enabled(1); 48 | 49 | ABT_rwlock rwlock = (ABT_rwlock)RAND_PTR; 50 | ret = ABT_rwlock_create(&rwlock); 51 | assert(!must_succeed || ret == ABT_SUCCESS); 52 | if (ret == ABT_SUCCESS) { 53 | /* If an external thread is supported, use an external thread. */ 54 | ABT_bool external_thread_support; 55 | ret = ABT_info_query_config(ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD, 56 | &external_thread_support); 57 | assert(ret == ABT_SUCCESS); 58 | if (external_thread_support) { 59 | pthread_t pthread; 60 | ret = pthread_create(&pthread, NULL, pthread_func, (void *)rwlock); 61 | assert(!must_succeed || ret == 0); 62 | if (ret == 0) { 63 | thread_func((void *)rwlock); 64 | ret = pthread_join(pthread, NULL); 65 | assert(ret == 0); 66 | } 67 | } 68 | /* Create a ULT and synchronize it with rwlock. */ 69 | ABT_xstream self_xstream; 70 | ret = ABT_self_get_xstream(&self_xstream); 71 | assert(ret == ABT_SUCCESS); 72 | ABT_thread thread = (ABT_thread)RAND_PTR; 73 | ret = ABT_thread_create_on_xstream(self_xstream, thread_func, 74 | (void *)rwlock, ABT_THREAD_ATTR_NULL, 75 | &thread); 76 | assert(!must_succeed || ret == ABT_SUCCESS); 77 | if (ret == ABT_SUCCESS) { 78 | thread_func((void *)rwlock); 79 | ret = ABT_thread_free(&thread); 80 | assert(ret == ABT_SUCCESS && thread == ABT_THREAD_NULL); 81 | } else { 82 | #ifdef ABT_ENABLE_VER_20_API 83 | assert(thread == (ABT_thread)RAND_PTR); 84 | #else 85 | assert(thread == ABT_THREAD_NULL); 86 | #endif 87 | } 88 | /* Free rwlock. */ 89 | ret = ABT_rwlock_free(&rwlock); 90 | assert(ret == ABT_SUCCESS && rwlock == ABT_RWLOCK_NULL); 91 | } else { 92 | #ifdef ABT_ENABLE_VER_20_API 93 | assert(rwlock == (ABT_rwlock)RAND_PTR); 94 | #else 95 | assert(rwlock == ABT_RWLOCK_NULL); 96 | #endif 97 | } 98 | 99 | ret = ABT_finalize(); 100 | assert(ret == ABT_SUCCESS); 101 | } 102 | 103 | int main() 104 | { 105 | setup_env(); 106 | rtrace_init(); 107 | 108 | if (use_rtrace()) { 109 | do { 110 | rtrace_start(); 111 | program(0); 112 | } while (!rtrace_stop()); 113 | } 114 | 115 | /* If no failure, it should succeed again. */ 116 | program(1); 117 | 118 | rtrace_finalize(); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /test/leakcheck/timer.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "rtrace.h" 9 | #include "util.h" 10 | 11 | /* Check ABT_init() and ABT_finalize(). */ 12 | 13 | void program(int must_succeed) 14 | { 15 | int ret; 16 | 17 | /* ABT_get_wtime() */ 18 | double wtime = ABT_get_wtime(); 19 | (void)wtime; 20 | 21 | /* ABT_timer start-stop-read functions */ 22 | ABT_timer timer = (ABT_timer)RAND_PTR; 23 | ret = ABT_timer_create(&timer); 24 | assert(!must_succeed || ret == ABT_SUCCESS); 25 | if (ret == ABT_SUCCESS) { 26 | double t; 27 | ret = ABT_timer_start(timer); 28 | assert(ret == ABT_SUCCESS); 29 | ret = ABT_timer_stop(timer); 30 | assert(ret == ABT_SUCCESS); 31 | ret = ABT_timer_read(timer, &t); 32 | assert(ret == ABT_SUCCESS && t >= 0.0); 33 | ret = ABT_timer_stop_and_add(timer, &t); 34 | assert(ret == ABT_SUCCESS && t >= 0.0); 35 | ret = ABT_timer_stop_and_read(timer, &t); 36 | assert(ret == ABT_SUCCESS && t >= 0.0); 37 | 38 | ABT_timer timer2 = (ABT_timer)RAND_PTR; 39 | ret = ABT_timer_dup(timer, &timer2); 40 | assert(!must_succeed || ret == ABT_SUCCESS); 41 | if (ret == ABT_SUCCESS) { 42 | double t2; 43 | ret = ABT_timer_read(timer2, &t2); 44 | assert(ret == ABT_SUCCESS && t == t2); 45 | ret = ABT_timer_free(&timer2); 46 | assert(ret == ABT_SUCCESS && timer2 == ABT_TIMER_NULL); 47 | } else { 48 | #ifdef ABT_ENABLE_VER_20_API 49 | assert(timer2 == (ABT_timer)RAND_PTR); 50 | #else 51 | assert(timer2 == ABT_TIMER_NULL); 52 | #endif 53 | } 54 | ret = ABT_timer_free(&timer); 55 | assert(ret == ABT_SUCCESS && timer == ABT_TIMER_NULL); 56 | } else { 57 | #ifdef ABT_ENABLE_VER_20_API 58 | assert(timer == (ABT_timer)RAND_PTR); 59 | #else 60 | assert(timer == ABT_TIMER_NULL); 61 | #endif 62 | } 63 | 64 | /* ABT_timer_get_overhead() */ 65 | double overhead = 999.9; 66 | ret = ABT_timer_get_overhead(&overhead); 67 | assert(!must_succeed || ret == ABT_SUCCESS); 68 | if (ret == ABT_SUCCESS) { 69 | assert(overhead >= 0.0); 70 | } else { 71 | assert(overhead == 999.9); 72 | } 73 | } 74 | 75 | int main() 76 | { 77 | setup_env(); 78 | rtrace_init(); 79 | 80 | if (use_rtrace()) { 81 | do { 82 | rtrace_start(); 83 | program(0); 84 | } while (!rtrace_stop()); 85 | } 86 | 87 | /* If no failure, it should succeed again. */ 88 | program(1); 89 | 90 | rtrace_finalize(); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /test/leakcheck/util.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #ifndef UTIL_H_INCLUDED 7 | #define UTIL_H_INCLUDED 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define RAND_PTR ((void *)(intptr_t)0x12345678) 14 | static void setup_env(void) 15 | { 16 | /* The following speeds up ABT_init(). */ 17 | int ret; 18 | ret = setenv("ABT_MEM_MAX_NUM_DESCS", "4", 1); 19 | assert(ret == 0); 20 | ret = setenv("ABT_MEM_MAX_NUM_STACKS", "4", 1); 21 | assert(ret == 0); 22 | } 23 | 24 | static int use_rtrace(void) 25 | { 26 | int ret; 27 | #ifndef ABT_ENABLE_VER_20_API 28 | ret = ABT_init(0, NULL); 29 | assert(ret == ABT_SUCCESS); 30 | #endif 31 | ABT_bool lazy_stack_alloc; 32 | ret = ABT_info_query_config(ABT_INFO_QUERY_KIND_ENABLED_LAZY_STACK_ALLOC, 33 | (void *)&lazy_stack_alloc); 34 | assert(ret == ABT_SUCCESS); 35 | #ifndef ABT_ENABLE_VER_20_API 36 | ret = ABT_finalize(); 37 | assert(ret == ABT_SUCCESS); 38 | #endif 39 | /* Currently the lazy stack allocation mechanism does not handle all the 40 | * memory leak cases properly. */ 41 | return lazy_stack_alloc ? 0 : 1; 42 | } 43 | #endif /* UTIL_H_INCLUDED */ 44 | -------------------------------------------------------------------------------- /test/leakcheck/xstream_barrier.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 2 | /* 3 | * See COPYRIGHT in top-level directory. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "rtrace.h" 10 | #include "util.h" 11 | 12 | /* Check ABT_xstream_barrier. */ 13 | 14 | void thread_func(void *arg) 15 | { 16 | int ret = ABT_xstream_barrier_wait((ABT_xstream_barrier)arg); 17 | assert(ret == ABT_SUCCESS); 18 | } 19 | 20 | void *pthread_func(void *arg) 21 | { 22 | thread_func(arg); 23 | return NULL; 24 | } 25 | 26 | void program(int must_succeed) 27 | { 28 | int ret; 29 | rtrace_set_enabled(0); 30 | /* Checking ABT_init() should be done by other tests. */ 31 | ret = ABT_init(0, 0); 32 | assert(ret == ABT_SUCCESS); 33 | rtrace_set_enabled(1); 34 | 35 | ABT_bool external_thread_support; 36 | ret = ABT_info_query_config(ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD, 37 | &external_thread_support); 38 | assert(ret == ABT_SUCCESS); 39 | 40 | ABT_xstream_barrier barrier = (ABT_xstream_barrier)RAND_PTR; 41 | ret = ABT_xstream_barrier_create(external_thread_support ? 2 : 1, &barrier); 42 | assert(!must_succeed || ret == ABT_SUCCESS); 43 | if (ret == ABT_SUCCESS) { 44 | if (external_thread_support) { 45 | /* num_waiters = 2. If an external thread is supported, use an 46 | * external thread. */ 47 | pthread_t pthread; 48 | ret = pthread_create(&pthread, NULL, pthread_func, (void *)barrier); 49 | assert(!must_succeed || ret == 0); 50 | if (ret == 0) { 51 | ret = ABT_xstream_barrier_wait(barrier); 52 | assert(ret == ABT_SUCCESS); 53 | ret = pthread_join(pthread, NULL); 54 | assert(ret == 0); 55 | } 56 | } else { 57 | /* num_waiters = 1 */ 58 | ret = ABT_xstream_barrier_wait(barrier); 59 | assert(ret == ABT_SUCCESS); 60 | } 61 | /* Free barrier. */ 62 | ret = ABT_xstream_barrier_free(&barrier); 63 | assert(ret == ABT_SUCCESS && barrier == ABT_XSTREAM_BARRIER_NULL); 64 | } else { 65 | #ifdef ABT_ENABLE_VER_20_API 66 | assert(barrier == (ABT_xstream_barrier)RAND_PTR); 67 | #else 68 | assert(barrier == ABT_XSTREAM_BARRIER_NULL); 69 | #endif 70 | } 71 | 72 | ret = ABT_finalize(); 73 | assert(ret == ABT_SUCCESS); 74 | } 75 | 76 | int main() 77 | { 78 | setup_env(); 79 | rtrace_init(); 80 | 81 | if (use_rtrace()) { 82 | do { 83 | rtrace_start(); 84 | program(0); 85 | } while (!rtrace_stop()); 86 | } 87 | 88 | /* If no failure, it should succeed again. */ 89 | program(1); 90 | 91 | rtrace_finalize(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /test/util/Makefile.am: -------------------------------------------------------------------------------- 1 | # -*- Mode: Makefile; -*- 2 | # 3 | # See COPYRIGHT in top-level directory. 4 | # 5 | 6 | AM_CPPFLAGS = $(DEPS_CPPFLAGS) 7 | AM_CPPFLAGS += -I$(top_builddir)/src/include -I$(top_srcdir)/test/util 8 | AM_LDFLAGS = $(DEPS_LDFLAGS) @libabt_timer_library@ 9 | 10 | noinst_LTLIBRARIES = libutil.la 11 | libutil_la_SOURCES = abttest.c 12 | --------------------------------------------------------------------------------