Changeset b826e6b for src/libcfa
- Timestamp:
- Jul 19, 2017, 11:49:33 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 9cc0472
- Parents:
- fea3faa (diff), a57cb58 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/libcfa
- Files:
-
- 8 added
- 32 edited
-
Makefile.am (modified) (3 diffs)
-
Makefile.in (modified) (32 diffs)
-
concurrency/CtxSwitch-i386.S (modified) (1 diff)
-
concurrency/CtxSwitch-x86_64.S (modified) (3 diffs)
-
concurrency/alarm.c (modified) (10 diffs)
-
concurrency/alarm.h (modified) (2 diffs)
-
concurrency/coroutine (modified) (4 diffs)
-
concurrency/coroutine.c (modified) (5 diffs)
-
concurrency/invoke.c (modified) (5 diffs)
-
concurrency/invoke.h (modified) (4 diffs)
-
concurrency/kernel (modified) (3 diffs)
-
concurrency/kernel.c (modified) (35 diffs)
-
concurrency/kernel_private.h (modified) (4 diffs)
-
concurrency/monitor (modified) (1 diff)
-
concurrency/monitor.c (modified) (23 diffs)
-
concurrency/preemption.c (modified) (3 diffs)
-
concurrency/thread (modified) (1 diff)
-
concurrency/thread.c (modified) (4 diffs)
-
exception.c (added)
-
exception.h (added)
-
fstream (modified) (3 diffs)
-
fstream.c (modified) (7 diffs)
-
gmp (modified) (1 diff)
-
iostream (modified) (6 diffs)
-
iostream.c (modified) (10 diffs)
-
iterator (modified) (2 diffs)
-
iterator.c (modified) (2 diffs)
-
libhdr/libalign.h (modified) (3 diffs)
-
libhdr/libdebug.h (modified) (2 diffs)
-
limits (modified) (2 diffs)
-
lsda.h (added)
-
math (modified) (2 diffs)
-
rational (modified) (3 diffs)
-
rational.c (modified) (18 diffs)
-
stdhdr/bfdlink.h (added)
-
stdhdr/hwloc.h (added)
-
stdhdr/krb5.h (added)
-
stdlib (modified) (2 diffs)
-
typeobject.c (added)
-
typeobject.h (added)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/Makefile.am
rfea3faa rb826e6b 10 10 ## Author : Peter A. Buhr 11 11 ## Created On : Sun May 31 08:54:01 2015 12 ## Last Modified By : Peter A. Buhr13 ## Last Modified On : Sun May 14 21:04:21201714 ## Update Count : 21 412 ## Last Modified By : Andrew Beach 13 ## Last Modified On : Fri Jun 14 17:00:00 2017 14 ## Update Count : 216 15 15 ############################################################################### 16 16 17 17 # create object files in directory with source files 18 18 AUTOMAKE_OPTIONS = subdir-objects 19 ARFLAGS = cr 19 20 20 21 libdir = ${CFA_LIBDIR} … … 50 51 51 52 libobjs = ${headers:=.o} 52 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} 53 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \ 54 exception.c typeobject.c 53 55 54 56 # not all platforms support concurrency, add option do disable it … … 64 66 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 65 67 68 libcfa_a-exception.o : exception.c 69 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 70 71 libcfa_a-typeobject.o : typeobject.c 72 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 73 66 74 concurrency/libcfa_d_a-invoke.o : concurrency/invoke.c 75 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 76 77 libcfa_d_a-exception.o : exception.c 78 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 79 80 libcfa_d_a-typeobject.o : typeobject.c 67 81 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 68 82 -
src/libcfa/Makefile.in
rfea3faa rb826e6b 1 # Makefile.in generated by automake 1.1 1.3from Makefile.am.1 # Makefile.in generated by automake 1.15 from Makefile.am. 2 2 # @configure_input@ 3 3 4 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 5 # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software 6 # Foundation, Inc. 4 # Copyright (C) 1994-2014 Free Software Foundation, Inc. 5 7 6 # This Makefile.in is free software; the Free Software Foundation 8 7 # gives unlimited permission to copy and/or distribute it, … … 21 20 22 21 VPATH = @srcdir@ 22 am__is_gnu_make = { \ 23 if test -z '$(MAKELEVEL)'; then \ 24 false; \ 25 elif test -n '$(MAKE_HOST)'; then \ 26 true; \ 27 elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ 28 true; \ 29 else \ 30 false; \ 31 fi; \ 32 } 33 am__make_running_with_option = \ 34 case $${target_option-} in \ 35 ?) ;; \ 36 *) echo "am__make_running_with_option: internal error: invalid" \ 37 "target option '$${target_option-}' specified" >&2; \ 38 exit 1;; \ 39 esac; \ 40 has_opt=no; \ 41 sane_makeflags=$$MAKEFLAGS; \ 42 if $(am__is_gnu_make); then \ 43 sane_makeflags=$$MFLAGS; \ 44 else \ 45 case $$MAKEFLAGS in \ 46 *\\[\ \ ]*) \ 47 bs=\\; \ 48 sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ 49 | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ 50 esac; \ 51 fi; \ 52 skip_next=no; \ 53 strip_trailopt () \ 54 { \ 55 flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ 56 }; \ 57 for flg in $$sane_makeflags; do \ 58 test $$skip_next = yes && { skip_next=no; continue; }; \ 59 case $$flg in \ 60 *=*|--*) continue;; \ 61 -*I) strip_trailopt 'I'; skip_next=yes;; \ 62 -*I?*) strip_trailopt 'I';; \ 63 -*O) strip_trailopt 'O'; skip_next=yes;; \ 64 -*O?*) strip_trailopt 'O';; \ 65 -*l) strip_trailopt 'l'; skip_next=yes;; \ 66 -*l?*) strip_trailopt 'l';; \ 67 -[dEDm]) skip_next=yes;; \ 68 -[JT]) skip_next=yes;; \ 69 esac; \ 70 case $$flg in \ 71 *$$target_option*) has_opt=yes; break;; \ 72 esac; \ 73 done; \ 74 test $$has_opt = yes 75 am__make_dryrun = (target_option=n; $(am__make_running_with_option)) 76 am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 23 77 pkgdatadir = $(datadir)/@PACKAGE@ 24 78 pkgincludedir = $(includedir)/@PACKAGE@ … … 48 102 @BUILD_CONCURRENCY_TRUE@am__append_4 = concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c concurrency/invoke.c concurrency/preemption.c 49 103 subdir = src/libcfa 50 DIST_COMMON = $(am__nobase_cfa_include_HEADERS_DIST) \51 $(srcdir)/Makefile.am $(srcdir)/Makefile.in52 104 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 53 105 am__aclocal_m4_deps = $(top_srcdir)/configure.ac 54 106 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 55 107 $(ACLOCAL_M4) 108 DIST_COMMON = $(srcdir)/Makefile.am \ 109 $(am__nobase_cfa_include_HEADERS_DIST) $(am__DIST_COMMON) 56 110 mkinstalldirs = $(install_sh) -d 57 111 CONFIG_HEADER = $(top_builddir)/config.h … … 88 142 LIBRARIES = $(lib_LIBRARIES) 89 143 AR = ar 90 ARFLAGS = cru91 144 AM_V_AR = $(am__v_AR_@AM_V@) 92 145 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) 93 am__v_AR_0 = @echo " AR " $@; 94 AM_V_at = $(am__v_at_@AM_V@) 95 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 96 am__v_at_0 = @ 146 am__v_AR_0 = @echo " AR " $@; 147 am__v_AR_1 = 97 148 libcfa_d_a_AR = $(AR) $(ARFLAGS) 98 149 libcfa_d_a_LIBADD = … … 102 153 containers/pair.c containers/result.c containers/vector.c \ 103 154 concurrency/coroutine.c concurrency/thread.c \ 104 concurrency/kernel.c concurrency/monitor.c \ 105 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 106 concurrency/invoke.c concurrency/preemption.c 155 concurrency/kernel.c concurrency/monitor.c exception.c \ 156 typeobject.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \ 157 concurrency/alarm.c concurrency/invoke.c \ 158 concurrency/preemption.c 107 159 am__dirstamp = $(am__leading_dot)dirstamp 108 160 @BUILD_CONCURRENCY_TRUE@am__objects_1 = concurrency/libcfa_d_a-coroutine.$(OBJEXT) \ … … 126 178 libcfa_d_a-interpose.$(OBJEXT) \ 127 179 libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \ 180 libcfa_d_a-exception.$(OBJEXT) libcfa_d_a-typeobject.$(OBJEXT) \ 128 181 $(am__objects_3) 129 182 am_libcfa_d_a_OBJECTS = $(am__objects_4) … … 136 189 containers/pair.c containers/result.c containers/vector.c \ 137 190 concurrency/coroutine.c concurrency/thread.c \ 138 concurrency/kernel.c concurrency/monitor.c \ 139 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 140 concurrency/invoke.c concurrency/preemption.c 191 concurrency/kernel.c concurrency/monitor.c exception.c \ 192 typeobject.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \ 193 concurrency/alarm.c concurrency/invoke.c \ 194 concurrency/preemption.c 141 195 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \ 142 196 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_a-thread.$(OBJEXT) \ … … 158 212 libcfa_a-interpose.$(OBJEXT) \ 159 213 libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \ 214 libcfa_a-exception.$(OBJEXT) libcfa_a-typeobject.$(OBJEXT) \ 160 215 $(am__objects_7) 161 216 am_libcfa_a_OBJECTS = $(am__objects_8) 162 217 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) 218 AM_V_P = $(am__v_P_@AM_V@) 219 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) 220 am__v_P_0 = false 221 am__v_P_1 = : 222 AM_V_GEN = $(am__v_GEN_@AM_V@) 223 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) 224 am__v_GEN_0 = @echo " GEN " $@; 225 am__v_GEN_1 = 226 AM_V_at = $(am__v_at_@AM_V@) 227 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 228 am__v_at_0 = @ 229 am__v_at_1 = 163 230 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 164 231 depcomp = $(SHELL) $(top_srcdir)/automake/depcomp … … 169 236 AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) 170 237 am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) 171 am__v_CPPAS_0 = @echo " CPPAS " $@; 238 am__v_CPPAS_0 = @echo " CPPAS " $@; 239 am__v_CPPAS_1 = 172 240 AM_V_lt = $(am__v_lt_@AM_V@) 173 241 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 174 242 am__v_lt_0 = --silent 243 am__v_lt_1 = 175 244 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 176 245 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 177 246 AM_V_CC = $(am__v_CC_@AM_V@) 178 247 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) 179 am__v_CC_0 = @echo " CC " $@; 248 am__v_CC_0 = @echo " CC " $@; 249 am__v_CC_1 = 180 250 CCLD = $(CC) 181 251 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 182 252 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 183 253 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) 184 am__v_CCLD_0 = @echo " CCLD " $@; 185 AM_V_GEN = $(am__v_GEN_@AM_V@) 186 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) 187 am__v_GEN_0 = @echo " GEN " $@; 254 am__v_CCLD_0 = @echo " CCLD " $@; 255 am__v_CCLD_1 = 188 256 SOURCES = $(libcfa_d_a_SOURCES) $(libcfa_a_SOURCES) 189 257 DIST_SOURCES = $(am__libcfa_d_a_SOURCES_DIST) \ 190 258 $(am__libcfa_a_SOURCES_DIST) 259 am__can_run_installinfo = \ 260 case $$AM_UPDATE_INFO_DIR in \ 261 n|no|NO) false;; \ 262 *) (install-info --version) >/dev/null 2>&1;; \ 263 esac 191 264 am__nobase_cfa_include_HEADERS_DIST = assert fstream iostream iterator \ 192 265 limits math rational stdlib containers/maybe containers/pair \ … … 195 268 ${shell echo stdhdr/*} gmp concurrency/invoke.h 196 269 HEADERS = $(nobase_cfa_include_HEADERS) 270 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 271 # Read a list of newline-separated strings from the standard input, 272 # and print each of them once, without duplicates. Input order is 273 # *not* preserved. 274 am__uniquify_input = $(AWK) '\ 275 BEGIN { nonempty = 0; } \ 276 { items[$$0] = 1; nonempty = 1; } \ 277 END { if (nonempty) { for (i in items) print i; }; } \ 278 ' 279 # Make sure the list of sources is unique. This is necessary because, 280 # e.g., the same source file might be shared among _SOURCES variables 281 # for different programs/libraries. 282 am__define_uniq_tagged_files = \ 283 list='$(am__tagged_files)'; \ 284 unique=`for i in $$list; do \ 285 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 286 done | $(am__uniquify_input)` 197 287 ETAGS = etags 198 288 CTAGS = ctags 289 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/automake/depcomp 199 290 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 200 291 ACLOCAL = @ACLOCAL@ … … 309 400 program_transform_name = @program_transform_name@ 310 401 psdir = @psdir@ 402 runstatedir = @runstatedir@ 311 403 sbindir = @sbindir@ 312 404 sharedstatedir = @sharedstatedir@ … … 320 412 # create object files in directory with source files 321 413 AUTOMAKE_OPTIONS = subdir-objects 414 ARFLAGS = cr 322 415 lib_LIBRARIES = $(am__append_1) $(am__append_2) 323 416 EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -I${abs_top_srcdir}/src/libcfa/libhdr -imacros libcfa-prelude.c @CFA_FLAGS@ … … 328 421 libobjs = ${headers:=.o} 329 422 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \ 330 $(am__append_4)423 exception.c typeobject.c $(am__append_4) 331 424 libcfa_a_SOURCES = ${libsrc} 332 425 libcfa_a_CFLAGS = -nodebug -O2 … … 353 446 $(am__cd) $(top_srcdir) && \ 354 447 $(AUTOMAKE) --foreign src/libcfa/Makefile 355 .PRECIOUS: Makefile356 448 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 357 449 @case '$?' in \ … … 373 465 install-libLIBRARIES: $(lib_LIBRARIES) 374 466 @$(NORMAL_INSTALL) 375 test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"376 467 @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ 377 468 list2=; for p in $$list; do \ … … 381 472 done; \ 382 473 test -z "$$list2" || { \ 474 echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ 475 $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ 383 476 echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ 384 477 $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } … … 448 541 concurrency/$(am__dirstamp) \ 449 542 concurrency/$(DEPDIR)/$(am__dirstamp) 543 450 544 libcfa-d.a: $(libcfa_d_a_OBJECTS) $(libcfa_d_a_DEPENDENCIES) $(EXTRA_libcfa_d_a_DEPENDENCIES) 451 545 $(AM_V_at)-rm -f libcfa-d.a … … 477 571 concurrency/$(am__dirstamp) \ 478 572 concurrency/$(DEPDIR)/$(am__dirstamp) 573 479 574 libcfa.a: $(libcfa_a_OBJECTS) $(libcfa_a_DEPENDENCIES) $(EXTRA_libcfa_a_DEPENDENCIES) 480 575 $(AM_V_at)-rm -f libcfa.a … … 484 579 mostlyclean-compile: 485 580 -rm -f *.$(OBJEXT) 486 -rm -f concurrency/CtxSwitch-@MACHINE_TYPE@.$(OBJEXT) 487 -rm -f concurrency/libcfa_a-alarm.$(OBJEXT) 488 -rm -f concurrency/libcfa_a-coroutine.$(OBJEXT) 489 -rm -f concurrency/libcfa_a-invoke.$(OBJEXT) 490 -rm -f concurrency/libcfa_a-kernel.$(OBJEXT) 491 -rm -f concurrency/libcfa_a-monitor.$(OBJEXT) 492 -rm -f concurrency/libcfa_a-preemption.$(OBJEXT) 493 -rm -f concurrency/libcfa_a-thread.$(OBJEXT) 494 -rm -f concurrency/libcfa_d_a-alarm.$(OBJEXT) 495 -rm -f concurrency/libcfa_d_a-coroutine.$(OBJEXT) 496 -rm -f concurrency/libcfa_d_a-invoke.$(OBJEXT) 497 -rm -f concurrency/libcfa_d_a-kernel.$(OBJEXT) 498 -rm -f concurrency/libcfa_d_a-monitor.$(OBJEXT) 499 -rm -f concurrency/libcfa_d_a-preemption.$(OBJEXT) 500 -rm -f concurrency/libcfa_d_a-thread.$(OBJEXT) 501 -rm -f containers/libcfa_a-maybe.$(OBJEXT) 502 -rm -f containers/libcfa_a-pair.$(OBJEXT) 503 -rm -f containers/libcfa_a-result.$(OBJEXT) 504 -rm -f containers/libcfa_a-vector.$(OBJEXT) 505 -rm -f containers/libcfa_d_a-maybe.$(OBJEXT) 506 -rm -f containers/libcfa_d_a-pair.$(OBJEXT) 507 -rm -f containers/libcfa_d_a-result.$(OBJEXT) 508 -rm -f containers/libcfa_d_a-vector.$(OBJEXT) 509 -rm -f libhdr/libcfa_a-libdebug.$(OBJEXT) 510 -rm -f libhdr/libcfa_d_a-libdebug.$(OBJEXT) 581 -rm -f concurrency/*.$(OBJEXT) 582 -rm -f containers/*.$(OBJEXT) 583 -rm -f libhdr/*.$(OBJEXT) 511 584 512 585 distclean-compile: … … 514 587 515 588 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-assert.Po@am__quote@ 589 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-exception.Po@am__quote@ 516 590 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-fstream.Po@am__quote@ 517 591 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-interpose.Po@am__quote@ … … 523 597 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@ 524 598 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@ 599 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-typeobject.Po@am__quote@ 525 600 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@ 601 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-exception.Po@am__quote@ 526 602 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-fstream.Po@am__quote@ 527 603 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-interpose.Po@am__quote@ … … 533 609 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@ 534 610 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@ 611 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-typeobject.Po@am__quote@ 535 612 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@MACHINE_TYPE@.Po@am__quote@ 536 613 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-alarm.Po@am__quote@ … … 850 927 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi` 851 928 929 libcfa_d_a-exception.obj: exception.c 930 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-exception.Tpo -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 931 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-exception.Tpo $(DEPDIR)/libcfa_d_a-exception.Po 932 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exception.c' object='libcfa_d_a-exception.obj' libtool=no @AMDEPBACKSLASH@ 933 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 934 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 935 936 libcfa_d_a-typeobject.obj: typeobject.c 937 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-typeobject.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-typeobject.Tpo -c -o libcfa_d_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi` 938 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-typeobject.Tpo $(DEPDIR)/libcfa_d_a-typeobject.Po 939 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='typeobject.c' object='libcfa_d_a-typeobject.obj' libtool=no @AMDEPBACKSLASH@ 940 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 941 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi` 942 852 943 concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c 853 944 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-alarm.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-alarm.Tpo -c -o concurrency/libcfa_d_a-alarm.o `test -f 'concurrency/alarm.c' || echo '$(srcdir)/'`concurrency/alarm.c … … 1144 1235 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi` 1145 1236 1237 libcfa_a-exception.obj: exception.c 1238 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_a-exception.Tpo -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 1239 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-exception.Tpo $(DEPDIR)/libcfa_a-exception.Po 1240 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exception.c' object='libcfa_a-exception.obj' libtool=no @AMDEPBACKSLASH@ 1241 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1242 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 1243 1244 libcfa_a-typeobject.obj: typeobject.c 1245 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-typeobject.obj -MD -MP -MF $(DEPDIR)/libcfa_a-typeobject.Tpo -c -o libcfa_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi` 1246 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-typeobject.Tpo $(DEPDIR)/libcfa_a-typeobject.Po 1247 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='typeobject.c' object='libcfa_a-typeobject.obj' libtool=no @AMDEPBACKSLASH@ 1248 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1249 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi` 1250 1146 1251 concurrency/libcfa_a-alarm.o: concurrency/alarm.c 1147 1252 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_a-alarm.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_a-alarm.Tpo -c -o concurrency/libcfa_a-alarm.o `test -f 'concurrency/alarm.c' || echo '$(srcdir)/'`concurrency/alarm.c … … 1180 1285 install-nobase_cfa_includeHEADERS: $(nobase_cfa_include_HEADERS) 1181 1286 @$(NORMAL_INSTALL) 1182 test -z "$(cfa_includedir)" || $(MKDIR_P) "$(DESTDIR)$(cfa_includedir)"1183 1287 @list='$(nobase_cfa_include_HEADERS)'; test -n "$(cfa_includedir)" || list=; \ 1288 if test -n "$$list"; then \ 1289 echo " $(MKDIR_P) '$(DESTDIR)$(cfa_includedir)'"; \ 1290 $(MKDIR_P) "$(DESTDIR)$(cfa_includedir)" || exit 1; \ 1291 fi; \ 1184 1292 $(am__nobase_list) | while read dir files; do \ 1185 1293 xfiles=; for file in $$files; do \ … … 1188 1296 test -z "$$xfiles" || { \ 1189 1297 test "x$$dir" = x. || { \ 1190 echo " $(MKDIR_P) '$(DESTDIR)$(cfa_includedir)/$$dir'"; \1298 echo " $(MKDIR_P) '$(DESTDIR)$(cfa_includedir)/$$dir'"; \ 1191 1299 $(MKDIR_P) "$(DESTDIR)$(cfa_includedir)/$$dir"; }; \ 1192 1300 echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(cfa_includedir)/$$dir'"; \ … … 1200 1308 dir='$(DESTDIR)$(cfa_includedir)'; $(am__uninstall_files_from_dir) 1201 1309 1202 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) 1203 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 1204 unique=`for i in $$list; do \ 1205 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 1206 done | \ 1207 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ 1208 END { if (nonempty) { for (i in files) print i; }; }'`; \ 1209 mkid -fID $$unique 1210 tags: TAGS 1211 1212 TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 1213 $(TAGS_FILES) $(LISP) 1310 ID: $(am__tagged_files) 1311 $(am__define_uniq_tagged_files); mkid -fID $$unique 1312 tags: tags-am 1313 TAGS: tags 1314 1315 tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 1214 1316 set x; \ 1215 1317 here=`pwd`; \ 1216 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 1217 unique=`for i in $$list; do \ 1218 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 1219 done | \ 1220 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ 1221 END { if (nonempty) { for (i in files) print i; }; }'`; \ 1318 $(am__define_uniq_tagged_files); \ 1222 1319 shift; \ 1223 1320 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ … … 1231 1328 fi; \ 1232 1329 fi 1233 ctags: CTAGS 1234 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 1235 $(TAGS_FILES) $(LISP) 1236 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 1237 unique=`for i in $$list; do \ 1238 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 1239 done | \ 1240 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ 1241 END { if (nonempty) { for (i in files) print i; }; }'`; \ 1330 ctags: ctags-am 1331 1332 CTAGS: ctags 1333 ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 1334 $(am__define_uniq_tagged_files); \ 1242 1335 test -z "$(CTAGS_ARGS)$$unique" \ 1243 1336 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ … … 1248 1341 && $(am__cd) $(top_srcdir) \ 1249 1342 && gtags -i $(GTAGS_ARGS) "$$here" 1343 cscopelist: cscopelist-am 1344 1345 cscopelist-am: $(am__tagged_files) 1346 list='$(am__tagged_files)'; \ 1347 case "$(srcdir)" in \ 1348 [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ 1349 *) sdir=$(subdir)/$(srcdir) ;; \ 1350 esac; \ 1351 for i in $$list; do \ 1352 if test -f "$$i"; then \ 1353 echo "$(subdir)/$$i"; \ 1354 else \ 1355 echo "$$sdir/$$i"; \ 1356 fi; \ 1357 done >> $(top_builddir)/cscope.files 1250 1358 1251 1359 distclean-tags: … … 1399 1507 .MAKE: install-am install-strip 1400 1508 1401 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \1402 clean-libLIBRARIES c tags distclean distclean-compile\1403 distclean- generic distclean-tags distdir dvi dvi-am html\1404 html-am info info-am install install-am install-data\1405 install-data -am install-dvi install-dvi-am install-exec\1406 install-exec -am install-html install-html-am install-info\1407 install-info -am install-libLIBRARIES install-man \1509 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ 1510 clean-libLIBRARIES cscopelist-am ctags ctags-am distclean \ 1511 distclean-compile distclean-generic distclean-tags distdir dvi \ 1512 dvi-am html html-am info info-am install install-am \ 1513 install-data install-data-am install-dvi install-dvi-am \ 1514 install-exec install-exec-am install-html install-html-am \ 1515 install-info install-info-am install-libLIBRARIES install-man \ 1408 1516 install-nobase_cfa_includeHEADERS install-pdf install-pdf-am \ 1409 1517 install-ps install-ps-am install-strip installcheck \ … … 1411 1519 maintainer-clean-generic maintainer-clean-local mostlyclean \ 1412 1520 mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ 1413 tags uninstall uninstall-am uninstall-libLIBRARIES \1521 tags tags-am uninstall uninstall-am uninstall-libLIBRARIES \ 1414 1522 uninstall-nobase_cfa_includeHEADERS 1523 1524 .PRECIOUS: Makefile 1415 1525 1416 1526 … … 1428 1538 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 1429 1539 1540 libcfa_a-exception.o : exception.c 1541 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 1542 1543 libcfa_a-typeobject.o : typeobject.c 1544 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $< 1545 1430 1546 concurrency/libcfa_d_a-invoke.o : concurrency/invoke.c 1547 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 1548 1549 libcfa_d_a-exception.o : exception.c 1550 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 1551 1552 libcfa_d_a-typeobject.o : typeobject.c 1431 1553 ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $< 1432 1554 -
src/libcfa/concurrency/CtxSwitch-i386.S
rfea3faa rb826e6b 98 98 ret 99 99 100 .text101 .align 2102 .globl CtxGet103 CtxGet:104 movl %esp,SP_OFFSET(%eax)105 movl %ebp,FP_OFFSET(%eax)106 107 ret108 109 100 // Local Variables: // 110 101 // compile-command: "make install" // -
src/libcfa/concurrency/CtxSwitch-x86_64.S
rfea3faa rb826e6b 1 // -*- Mode: Asm -*- 1 // -*- Mode: Asm -*- 2 2 // 3 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 18 18 // Free Software Foundation; either version 2.1 of the License, or (at your 19 19 // option) any later version. 20 // 20 // 21 21 // This library is distributed in the hope that it will be useful, but WITHOUT 22 22 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 23 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 24 24 // for more details. 25 // 25 // 26 26 // You should have received a copy of the GNU Lesser General Public License 27 27 // along with this library. 28 // 28 // 29 29 30 30 // This context switch routine depends on the fact that the stack of a new … … 93 93 .globl CtxInvokeStub 94 94 CtxInvokeStub: 95 movq %rbx, %rdi 95 movq %rbx, %rdi 96 96 jmp *%r12 97 98 .text99 .align 2100 .globl CtxGet101 CtxGet:102 movq %rsp,SP_OFFSET(%rdi)103 movq %rbp,FP_OFFSET(%rdi)104 105 ret106 97 107 98 // Local Variables: // -
src/libcfa/concurrency/alarm.c
rfea3faa rb826e6b 16 16 17 17 extern "C" { 18 #include <errno.h> 19 #include <stdio.h> 20 #include <string.h> 18 21 #include <time.h> 22 #include <unistd.h> 19 23 #include <sys/time.h> 20 24 } 25 26 #include "libhdr.h" 21 27 22 28 #include "alarm.h" … … 25 31 26 32 //============================================================================================= 33 // time type 34 //============================================================================================= 35 36 #define one_second 1_000_000_000ul 37 #define one_milisecond 1_000_000ul 38 #define one_microsecond 1_000ul 39 #define one_nanosecond 1ul 40 41 __cfa_time_t zero_time = { 0 }; 42 43 void ?{}( __cfa_time_t * this ) { this->val = 0; } 44 void ?{}( __cfa_time_t * this, zero_t zero ) { this->val = 0; } 45 46 void ?{}( itimerval * this, __cfa_time_t * alarm ) { 47 this->it_value.tv_sec = alarm->val / one_second; // seconds 48 this->it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds 49 this->it_interval.tv_sec = 0; 50 this->it_interval.tv_usec = 0; 51 } 52 53 54 void ?{}( __cfa_time_t * this, timespec * curr ) { 55 uint64_t secs = curr->tv_sec; 56 uint64_t nsecs = curr->tv_nsec; 57 this->val = (secs * one_second) + nsecs; 58 } 59 60 __cfa_time_t ?=?( __cfa_time_t * this, zero_t rhs ) { 61 this->val = 0; 62 return *this; 63 } 64 65 __cfa_time_t from_s ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; } 66 __cfa_time_t from_ms( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000ul; return ret; } 67 __cfa_time_t from_us( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000ul; return ret; } 68 __cfa_time_t from_ns( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1ul; return ret; } 69 70 //============================================================================================= 27 71 // Clock logic 28 72 //============================================================================================= … … 31 75 timespec curr; 32 76 clock_gettime( CLOCK_REALTIME, &curr ); 33 return ( (__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;77 return (__cfa_time_t){ &curr }; 34 78 } 35 79 36 80 void __kernel_set_timer( __cfa_time_t alarm ) { 37 itimerval val; 38 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds 39 val.it_value.tv_usec = (alarm % TIMEGRAN) / ( TIMEGRAN / 1_000_000L ); // microseconds 40 val.it_interval.tv_sec = 0; 41 val.it_interval.tv_usec = 0; 81 itimerval val = { &alarm }; 42 82 setitimer( ITIMER_REAL, &val, NULL ); 43 83 } … … 47 87 //============================================================================================= 48 88 49 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {89 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 50 90 this->thrd = thrd; 51 91 this->alarm = alarm; … … 56 96 } 57 97 58 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {98 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 59 99 this->proc = proc; 60 100 this->alarm = alarm; … … 71 111 } 72 112 113 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) { 114 alarm_node_t ** it = &this->head; 115 while( (*it) ) { 116 it = &(*it)->next; 117 } 118 119 return it == this->tail; 120 }) 121 73 122 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 74 assert( !n->next );123 verify( !n->next ); 75 124 if( p == this->tail ) { 76 125 this->tail = &n->next; … … 80 129 } 81 130 *p = n; 131 132 verify( validate( this ) ); 82 133 } 83 134 … … 89 140 90 141 insert_at( this, n, it ); 142 143 verify( validate( this ) ); 91 144 } 92 145 … … 100 153 head->next = NULL; 101 154 } 155 verify( validate( this ) ); 102 156 return head; 103 157 } … … 105 159 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 106 160 verify( it ); 107 verify( (*it) ->next== n );108 109 (*it) ->next= n->next;161 verify( (*it) == n ); 162 163 (*it) = n->next; 110 164 if( !n-> next ) { 111 165 this->tail = it; 112 166 } 113 167 n->next = NULL; 168 169 verify( validate( this ) ); 114 170 } 115 171 116 172 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 117 173 alarm_node_t ** it = &this->head; 118 while( (*it) && (*it) ->next!= n ) {174 while( (*it) && (*it) != n ) { 119 175 it = &(*it)->next; 120 176 } 121 177 178 verify( validate( this ) ); 179 122 180 if( *it ) { remove_at( this, n, it ); } 181 182 verify( validate( this ) ); 123 183 } 124 184 125 185 void register_self( alarm_node_t * this ) { 186 alarm_list_t * alarms = &event_kernel->alarms; 187 126 188 disable_interrupts(); 127 assert( !systemProcessor->pending_alarm ); 128 lock( &systemProcessor->alarm_lock ); 189 lock( &event_kernel->lock DEBUG_CTX2 ); 129 190 { 130 insert( &systemProcessor->alarms, this ); 131 if( systemProcessor->pending_alarm ) { 132 tick_preemption(); 191 verify( validate( alarms ) ); 192 bool first = !alarms->head; 193 194 insert( alarms, this ); 195 if( first ) { 196 __kernel_set_timer( alarms->head->alarm - __kernel_get_time() ); 133 197 } 134 198 } 135 unlock( & systemProcessor->alarm_lock );199 unlock( &event_kernel->lock ); 136 200 this->set = true; 137 enable_interrupts( );201 enable_interrupts( DEBUG_CTX ); 138 202 } 139 203 140 204 void unregister_self( alarm_node_t * this ) { 141 205 disable_interrupts(); 142 lock( &systemProcessor->alarm_lock ); 143 remove( &systemProcessor->alarms, this ); 144 unlock( &systemProcessor->alarm_lock ); 145 disable_interrupts(); 206 lock( &event_kernel->lock DEBUG_CTX2 ); 207 { 208 verify( validate( &event_kernel->alarms ) ); 209 remove( &event_kernel->alarms, this ); 210 } 211 unlock( &event_kernel->lock ); 212 enable_interrupts( DEBUG_CTX ); 146 213 this->set = false; 147 214 } -
src/libcfa/concurrency/alarm.h
rfea3faa rb826e6b 19 19 20 20 #include <stdbool.h> 21 #include <stdint.h> 21 22 22 23 #include "assert" 23 24 typedef unsigned long int __cfa_time_t;25 24 26 25 struct thread_desc; 27 26 struct processor; 28 27 28 struct timespec; 29 struct itimerval; 30 31 //============================================================================================= 32 // time type 33 //============================================================================================= 34 35 struct __cfa_time_t { 36 uint64_t val; 37 }; 38 39 // ctors 40 void ?{}( __cfa_time_t * this ); 41 void ?{}( __cfa_time_t * this, zero_t zero ); 42 void ?{}( __cfa_time_t * this, timespec * curr ); 43 void ?{}( itimerval * this, __cfa_time_t * alarm ); 44 45 __cfa_time_t ?=?( __cfa_time_t * this, zero_t rhs ); 46 47 // logical ops 48 static inline bool ?==?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val == rhs.val; } 49 static inline bool ?!=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val != rhs.val; } 50 static inline bool ?>? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val > rhs.val; } 51 static inline bool ?<? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val < rhs.val; } 52 static inline bool ?>=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >= rhs.val; } 53 static inline bool ?<=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <= rhs.val; } 54 55 static inline bool ?==?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val == rhs; } 56 static inline bool ?!=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val != rhs; } 57 static inline bool ?>? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val > rhs; } 58 static inline bool ?<? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val < rhs; } 59 static inline bool ?>=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >= rhs; } 60 static inline bool ?<=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <= rhs; } 61 62 // addition/substract 63 static inline __cfa_time_t ?+?( __cfa_time_t lhs, __cfa_time_t rhs ) { 64 __cfa_time_t ret; 65 ret.val = lhs.val + rhs.val; 66 return ret; 67 } 68 69 static inline __cfa_time_t ?-?( __cfa_time_t lhs, __cfa_time_t rhs ) { 70 __cfa_time_t ret; 71 ret.val = lhs.val - rhs.val; 72 return ret; 73 } 74 75 __cfa_time_t from_s ( uint64_t ); 76 __cfa_time_t from_ms( uint64_t ); 77 __cfa_time_t from_us( uint64_t ); 78 __cfa_time_t from_ns( uint64_t ); 79 80 extern __cfa_time_t zero_time; 81 29 82 //============================================================================================= 30 83 // Clock logic 31 84 //============================================================================================= 32 33 #define TIMEGRAN 1_000_000_000L // nanosecond granularity, except for timeval34 85 35 86 __cfa_time_t __kernel_get_time(); … … 56 107 typedef alarm_node_t ** __alarm_it_t; 57 108 58 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0);59 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0);109 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ); 110 void ?{}( alarm_node_t * this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ); 60 111 void ^?{}( alarm_node_t * this ); 61 112 -
src/libcfa/concurrency/coroutine
rfea3faa rb826e6b 63 63 64 64 // Get current coroutine 65 coroutine_desc * this_coroutine(void);65 extern volatile thread_local coroutine_desc * this_coroutine; 66 66 67 67 // Private wrappers for context switch and stack creation … … 71 71 // Suspend implementation inlined for performance 72 72 static inline void suspend() { 73 coroutine_desc * src = this_coroutine (); // optimization73 coroutine_desc * src = this_coroutine; // optimization 74 74 75 75 assertf( src->last != 0, … … 88 88 forall(dtype T | is_coroutine(T)) 89 89 static inline void resume(T * cor) { 90 coroutine_desc * src = this_coroutine (); // optimization90 coroutine_desc * src = this_coroutine; // optimization 91 91 coroutine_desc * dst = get_coroutine(cor); 92 92 … … 112 112 113 113 static inline void resume(coroutine_desc * dst) { 114 coroutine_desc * src = this_coroutine (); // optimization114 coroutine_desc * src = this_coroutine; // optimization 115 115 116 116 // not resuming self ? -
src/libcfa/concurrency/coroutine.c
rfea3faa rb826e6b 32 32 #include "invoke.h" 33 33 34 extern thread_local processor * this_processor;34 extern volatile thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- … … 44 44 // Coroutine ctors and dtors 45 45 void ?{}(coStack_t* this) { 46 this->size = 10240; // size of stack46 this->size = 65000; // size of stack 47 47 this->storage = NULL; // pointer to stack 48 48 this->limit = NULL; // stack grows towards stack limit … … 50 50 this->context = NULL; // address of cfa_context_t 51 51 this->top = NULL; // address of top of storage 52 this->userStack = false; 52 this->userStack = false; 53 53 } 54 54 … … 106 106 107 107 // set state of current coroutine to inactive 108 src->state = Inactive;108 src->state = src->state == Halted ? Halted : Inactive; 109 109 110 110 // set new coroutine that task is executing 111 this_ processor->current_coroutine = dst;111 this_coroutine = dst; 112 112 113 113 // context switch to specified coroutine 114 assert( src->stack.context ); 114 115 CtxSwitch( src->stack.context, dst->stack.context ); 115 // when CtxSwitch returns we are back in the src coroutine 116 // when CtxSwitch returns we are back in the src coroutine 116 117 117 118 // set state of new coroutine to active … … 131 132 this->size = libCeiling( storageSize, 16 ); 132 133 // use malloc/memalign because "new" raises an exception for out-of-memory 133 134 134 135 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 135 136 LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) ); -
src/libcfa/concurrency/invoke.c
rfea3faa rb826e6b 29 29 30 30 extern void __suspend_internal(void); 31 extern void __leave_monitor_desc( struct monitor_desc * this ); 31 extern void __leave_thread_monitor( struct thread_desc * this ); 32 extern void disable_interrupts(); 33 extern void enable_interrupts( DEBUG_CTX_PARAM ); 32 34 33 35 void CtxInvokeCoroutine( 34 void (*main)(void *), 35 struct coroutine_desc *(*get_coroutine)(void *), 36 void (*main)(void *), 37 struct coroutine_desc *(*get_coroutine)(void *), 36 38 void *this 37 39 ) { … … 56 58 57 59 void CtxInvokeThread( 58 void (*dtor)(void *), 59 void (*main)(void *), 60 struct thread_desc *(*get_thread)(void *), 60 void (*dtor)(void *), 61 void (*main)(void *), 62 struct thread_desc *(*get_thread)(void *), 61 63 void *this 62 64 ) { 65 // First suspend, once the thread arrives here, 66 // the function pointer to main can be invalidated without risk 63 67 __suspend_internal(); 64 68 69 // Fetch the thread handle from the user defined thread structure 65 70 struct thread_desc* thrd = get_thread( this ); 66 struct coroutine_desc* cor = &thrd->cor;67 struct monitor_desc* mon = &thrd->mon;68 cor->state = Active;69 71 70 // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this); 72 // Officially start the thread by enabling preemption 73 enable_interrupts( DEBUG_CTX ); 74 75 // Call the main of the thread 71 76 main( this ); 72 77 73 __leave_monitor_desc( mon ); 74 78 // To exit a thread we must : 79 // 1 - Mark it as halted 80 // 2 - Leave its monitor 81 // 3 - Disable the interupts 82 // 4 - Final suspend 83 // The order of these 4 operations is very important 75 84 //Final suspend, should never return 76 __ suspend_internal();85 __leave_thread_monitor( thrd ); 77 86 abortf("Resumed dead thread"); 78 87 } … … 80 89 81 90 void CtxStart( 82 void (*main)(void *), 83 struct coroutine_desc *(*get_coroutine)(void *), 84 void *this, 91 void (*main)(void *), 92 struct coroutine_desc *(*get_coroutine)(void *), 93 void *this, 85 94 void (*invoke)(void *) 86 95 ) { … … 108 117 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 109 118 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 110 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 119 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 111 120 112 121 #elif defined( __x86_64__ ) … … 128 137 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 129 138 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 130 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 139 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 131 140 #else 132 141 #error Only __i386__ and __x86_64__ is supported for threads in cfa -
src/libcfa/concurrency/invoke.h
rfea3faa rb826e6b 31 31 struct spinlock { 32 32 volatile int lock; 33 #ifdef __CFA_DEBUG__ 34 const char * prev_name; 35 void* prev_thrd; 36 #endif 33 37 }; 34 38 … … 83 87 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 84 88 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 85 struct monitor_desc * stack_owner; // if bulk acquiring was used we need to synchronize signals with an other monitor86 89 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 87 90 }; … … 99 102 #ifndef _INVOKE_PRIVATE_H_ 100 103 #define _INVOKE_PRIVATE_H_ 101 104 102 105 struct machine_context_t { 103 106 void *SP; … … 109 112 extern void CtxInvokeStub( void ); 110 113 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 111 void CtxGet( void * this ) asm ("CtxGet"); 114 115 #if defined( __x86_64__ ) 116 #define CtxGet( ctx ) __asm__ ( \ 117 "movq %%rsp,%0\n" \ 118 "movq %%rbp,%1\n" \ 119 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 120 #elif defined( __i386__ ) 121 #define CtxGet( ctx ) __asm__ ( \ 122 "movl %%esp,%0\n" \ 123 "movl %%ebp,%1\n" \ 124 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 125 #endif 112 126 113 127 #endif //_INVOKE_PRIVATE_H_ -
src/libcfa/concurrency/kernel
rfea3faa rb826e6b 28 28 //----------------------------------------------------------------------------- 29 29 // Locks 30 bool try_lock( spinlock * ); 31 void lock( spinlock * ); 32 void unlock( spinlock * ); 30 void lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, spin if already acquired 31 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, yield repeatedly if already acquired 32 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, return false if already acquired 33 void unlock ( spinlock * ); // Unlock the spinlock 33 34 34 struct s ignal_once {35 volatile bool cond;36 struct spinlock lock;37 struct __thread_queue_t blocked;35 struct semaphore { 36 spinlock lock; 37 int count; 38 __thread_queue_t waiting; 38 39 }; 39 40 40 void ?{}(signal_once * this); 41 void ^?{}(signal_once * this); 41 void ?{}(semaphore * this, int count = 1); 42 void ^?{}(semaphore * this); 43 void P(semaphore * this); 44 void V(semaphore * this); 42 45 43 void wait( signal_once * );44 void signal( signal_once * );45 46 46 47 //----------------------------------------------------------------------------- 47 48 // Cluster 48 49 struct cluster { 49 __thread_queue_t ready_queue; 50 spinlock lock; 50 spinlock ready_queue_lock; // Ready queue locks 51 __thread_queue_t ready_queue; // Ready queue for threads 52 unsigned long long int preemption; // Preemption rate on this cluster 51 53 }; 52 54 … … 68 70 unsigned short thrd_count; 69 71 }; 70 static inline void ?{}(FinishAction * this) { 72 static inline void ?{}(FinishAction * this) { 71 73 this->action_code = No_Action; 72 74 this->thrd = NULL; … … 75 77 static inline void ^?{}(FinishAction * this) {} 76 78 79 // Processor 80 // Wrapper around kernel threads 77 81 struct processor { 78 struct processorCtx_t * runner; 79 cluster * cltr; 80 coroutine_desc * current_coroutine; 81 thread_desc * current_thread; 82 pthread_t kernel_thread; 83 84 signal_once terminated; 85 volatile bool is_terminated; 82 // Main state 83 struct processorCtx_t * runner; // Coroutine ctx who does keeps the state of the processor 84 cluster * cltr; // Cluster from which to get threads 85 pthread_t kernel_thread; // Handle to pthreads 86 86 87 struct FinishAction finish; 87 // Termination 88 volatile bool do_terminate; // Set to true to notify the processor should terminate 89 semaphore terminated; // Termination synchronisation 88 90 89 struct alarm_node_t * preemption_alarm;90 unsigned int preemption;91 // RunThread data 92 struct FinishAction finish; // Action to do after a thread is ran 91 93 92 unsigned short disable_preempt_count; 94 // Preemption data 95 struct alarm_node_t * preemption_alarm; // Node which is added in the discrete event simulaiton 96 bool pending_preemption; // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 93 97 94 bool pending_preemption; 98 #ifdef __CFA_DEBUG__ 99 char * last_enable; // Last function to enable preemption on this processor 100 #endif 95 101 }; 96 102 -
src/libcfa/concurrency/kernel.c
rfea3faa rb826e6b 15 15 // 16 16 17 #include "startup.h" 18 19 //Start and stop routine for the kernel, declared first to make sure they run first 20 void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) )); 21 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) )); 22 23 //Header 24 #include "kernel_private.h" 17 #include "libhdr.h" 25 18 26 19 //C Includes … … 35 28 36 29 //CFA Includes 37 #include " libhdr.h"30 #include "kernel_private.h" 38 31 #include "preemption.h" 32 #include "startup.h" 39 33 40 34 //Private includes … … 42 36 #include "invoke.h" 43 37 38 //Start and stop routine for the kernel, declared first to make sure they run first 39 void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) )); 40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) )); 41 44 42 //----------------------------------------------------------------------------- 45 43 // Kernel storage 46 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)] 47 48 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); 49 KERNEL_STORAGE(cluster, systemCluster); 50 KERNEL_STORAGE(system_proc_t, systemProcessor); 51 KERNEL_STORAGE(thread_desc, mainThread); 52 KERNEL_STORAGE(machine_context_t, mainThread_context); 53 54 cluster * systemCluster; 55 system_proc_t * systemProcessor; 44 KERNEL_STORAGE(cluster, mainCluster); 45 KERNEL_STORAGE(processor, mainProcessor); 46 KERNEL_STORAGE(processorCtx_t, mainProcessorCtx); 47 KERNEL_STORAGE(thread_desc, mainThread); 48 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 49 50 cluster * mainCluster; 51 processor * mainProcessor; 56 52 thread_desc * mainThread; 57 53 … … 59 55 // Global state 60 56 61 thread_local processor * this_processor; 62 63 coroutine_desc * this_coroutine(void) { 64 return this_processor->current_coroutine; 65 } 66 67 thread_desc * this_thread(void) { 68 return this_processor->current_thread; 69 } 57 volatile thread_local coroutine_desc * this_coroutine; 58 volatile thread_local thread_desc * this_thread; 59 volatile thread_local processor * this_processor; 60 61 volatile thread_local bool preemption_in_progress = 0; 62 volatile thread_local unsigned short disable_preempt_count = 1; 70 63 71 64 //----------------------------------------------------------------------------- 72 65 // Main thread construction 73 66 struct current_stack_info_t { 74 machine_context_t ctx; 67 machine_context_t ctx; 75 68 unsigned int size; // size of stack 76 69 void *base; // base of stack … … 82 75 83 76 void ?{}( current_stack_info_t * this ) { 84 CtxGet( &this->ctx );77 CtxGet( this->ctx ); 85 78 this->base = this->ctx.FP; 86 79 this->storage = this->ctx.SP; … … 91 84 92 85 this->limit = (void *)(((intptr_t)this->base) - this->size); 93 this->context = & mainThread_context_storage;86 this->context = &storage_mainThreadCtx; 94 87 this->top = this->base; 95 88 } … … 106 99 107 100 void ?{}( coroutine_desc * this, current_stack_info_t * info) { 108 (&this->stack){ info }; 101 (&this->stack){ info }; 109 102 this->name = "Main Thread"; 110 103 this->errno_ = 0; … … 131 124 132 125 void ?{}(processor * this) { 133 this{ systemCluster };126 this{ mainCluster }; 134 127 } 135 128 136 129 void ?{}(processor * this, cluster * cltr) { 137 130 this->cltr = cltr; 138 this->current_coroutine = NULL; 139 this->current_thread = NULL; 140 (&this->terminated){}; 141 this->is_terminated = false; 131 (&this->terminated){ 0 }; 132 this->do_terminate = false; 142 133 this->preemption_alarm = NULL; 143 this->preemption = default_preemption();144 this->disable_preempt_count = 1; //Start with interrupts disabled145 134 this->pending_preemption = false; 146 135 … … 150 139 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) { 151 140 this->cltr = cltr; 152 this->current_coroutine = NULL; 153 this->current_thread = NULL; 154 (&this->terminated){}; 155 this->is_terminated = false; 156 this->disable_preempt_count = 0; 141 (&this->terminated){ 0 }; 142 this->do_terminate = false; 143 this->preemption_alarm = NULL; 157 144 this->pending_preemption = false; 145 this->kernel_thread = pthread_self(); 158 146 159 147 this->runner = runner; 160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);148 LIB_DEBUG_PRINT_SAFE("Kernel : constructing main processor context %p\n", runner); 161 149 runner{ this }; 162 150 } 163 151 164 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {165 (&this->alarms){};166 (&this->alarm_lock){};167 this->pending_alarm = false;168 169 (&this->proc){ cltr, runner };170 }171 172 152 void ^?{}(processor * this) { 173 if( ! this-> is_terminated) {153 if( ! this->do_terminate ) { 174 154 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 175 this->is_terminated = true; 176 wait( &this->terminated ); 155 this->do_terminate = true; 156 P( &this->terminated ); 157 pthread_join( this->kernel_thread, NULL ); 177 158 } 178 159 } … … 180 161 void ?{}(cluster * this) { 181 162 ( &this->ready_queue ){}; 182 ( &this->lock ){}; 163 ( &this->ready_queue_lock ){}; 164 165 this->preemption = default_preemption(); 183 166 } 184 167 185 168 void ^?{}(cluster * this) { 186 169 187 170 } 188 171 … … 203 186 204 187 thread_desc * readyThread = NULL; 205 for( unsigned int spin_count = 0; ! this-> is_terminated; spin_count++ )188 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ ) 206 189 { 207 190 readyThread = nextThread( this->cltr ); … … 209 192 if(readyThread) 210 193 { 194 verify( disable_preempt_count > 0 ); 195 211 196 runThread(this, readyThread); 197 198 verify( disable_preempt_count > 0 ); 212 199 213 200 //Some actions need to be taken from the kernel … … 225 212 } 226 213 227 signal( &this->terminated ); 214 V( &this->terminated ); 215 228 216 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this); 229 217 } 230 218 231 // runThread runs a thread by context switching 232 // from the processor coroutine to the target thread 219 // runThread runs a thread by context switching 220 // from the processor coroutine to the target thread 233 221 void runThread(processor * this, thread_desc * dst) { 234 222 coroutine_desc * proc_cor = get_coroutine(this->runner); 235 223 coroutine_desc * thrd_cor = get_coroutine(dst); 236 224 237 225 //Reset the terminating actions here 238 226 this->finish.action_code = No_Action; 239 227 240 228 //Update global state 241 this ->current_thread = dst;229 this_thread = dst; 242 230 243 231 // Context Switch to the thread … … 246 234 } 247 235 248 // Once a thread has finished running, some of 236 // Once a thread has finished running, some of 249 237 // its final actions must be executed from the kernel 250 238 void finishRunning(processor * this) { … … 256 244 } 257 245 else if( this->finish.action_code == Release_Schedule ) { 258 unlock( this->finish.lock ); 246 unlock( this->finish.lock ); 259 247 ScheduleThread( this->finish.thrd ); 260 248 } … … 289 277 processor * proc = (processor *) arg; 290 278 this_processor = proc; 279 this_coroutine = NULL; 280 this_thread = NULL; 281 disable_preempt_count = 1; 291 282 // SKULLDUGGERY: We want to create a context for the processor coroutine 292 283 // which is needed for the 2-step context switch. However, there is no reason 293 // to waste the perfectly valid stack create by pthread. 284 // to waste the perfectly valid stack create by pthread. 294 285 current_stack_info_t info; 295 286 machine_context_t ctx; … … 300 291 301 292 //Set global state 302 proc->current_coroutine = &proc->runner->__cor;303 proc->current_thread = NULL;293 this_coroutine = &proc->runner->__cor; 294 this_thread = NULL; 304 295 305 296 //We now have a proper context from which to schedule threads 306 297 LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx); 307 298 308 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 309 // resume it to start it like it normally would, it will just context switch 310 // back to here. Instead directly call the main since we already are on the 299 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 300 // resume it to start it like it normally would, it will just context switch 301 // back to here. Instead directly call the main since we already are on the 311 302 // appropriate stack. 312 303 proc_cor_storage.__cor.state = Active; … … 315 306 316 307 // Main routine of the core returned, the core is now fully terminated 317 LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 308 LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 318 309 319 310 return NULL; … … 322 313 void start(processor * this) { 323 314 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 324 315 325 316 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 326 317 327 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 318 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 328 319 } 329 320 … … 331 322 // Scheduler routines 332 323 void ScheduleThread( thread_desc * thrd ) { 333 if( !thrd ) return; 324 // if( !thrd ) return; 325 assert( thrd ); 326 assert( thrd->cor.state != Halted ); 327 328 verify( disable_preempt_count > 0 ); 334 329 335 330 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 336 337 lock( &systemProcessor->proc.cltr->lock ); 338 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 339 unlock( &systemProcessor->proc.cltr->lock ); 331 332 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 ); 333 append( &this_processor->cltr->ready_queue, thrd ); 334 unlock( &this_processor->cltr->ready_queue_lock ); 335 336 verify( disable_preempt_count > 0 ); 340 337 } 341 338 342 339 thread_desc * nextThread(cluster * this) { 343 lock( &this->lock ); 340 verify( disable_preempt_count > 0 ); 341 lock( &this->ready_queue_lock DEBUG_CTX2 ); 344 342 thread_desc * head = pop_head( &this->ready_queue ); 345 unlock( &this->lock ); 343 unlock( &this->ready_queue_lock ); 344 verify( disable_preempt_count > 0 ); 346 345 return head; 347 346 } 348 347 349 void ScheduleInternal() { 350 suspend(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 348 void BlockInternal() { 349 disable_interrupts(); 350 verify( disable_preempt_count > 0 ); 351 suspend(); 352 verify( disable_preempt_count > 0 ); 353 enable_interrupts( DEBUG_CTX ); 354 } 355 356 void BlockInternal( spinlock * lock ) { 357 disable_interrupts(); 354 358 this_processor->finish.action_code = Release; 355 359 this_processor->finish.lock = lock; 356 suspend(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 360 361 verify( disable_preempt_count > 0 ); 362 suspend(); 363 verify( disable_preempt_count > 0 ); 364 365 enable_interrupts( DEBUG_CTX ); 366 } 367 368 void BlockInternal( thread_desc * thrd ) { 369 disable_interrupts(); 370 assert( thrd->cor.state != Halted ); 360 371 this_processor->finish.action_code = Schedule; 361 372 this_processor->finish.thrd = thrd; 362 suspend(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 373 374 verify( disable_preempt_count > 0 ); 375 suspend(); 376 verify( disable_preempt_count > 0 ); 377 378 enable_interrupts( DEBUG_CTX ); 379 } 380 381 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 382 disable_interrupts(); 366 383 this_processor->finish.action_code = Release_Schedule; 367 384 this_processor->finish.lock = lock; 368 385 this_processor->finish.thrd = thrd; 369 suspend(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 386 387 verify( disable_preempt_count > 0 ); 388 suspend(); 389 verify( disable_preempt_count > 0 ); 390 391 enable_interrupts( DEBUG_CTX ); 392 } 393 394 void BlockInternal(spinlock ** locks, unsigned short count) { 395 disable_interrupts(); 373 396 this_processor->finish.action_code = Release_Multi; 374 397 this_processor->finish.locks = locks; 375 398 this_processor->finish.lock_count = count; 376 suspend(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 399 400 verify( disable_preempt_count > 0 ); 401 suspend(); 402 verify( disable_preempt_count > 0 ); 403 404 enable_interrupts( DEBUG_CTX ); 405 } 406 407 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 408 disable_interrupts(); 380 409 this_processor->finish.action_code = Release_Multi_Schedule; 381 410 this_processor->finish.locks = locks; … … 383 412 this_processor->finish.thrds = thrds; 384 413 this_processor->finish.thrd_count = thrd_count; 414 415 verify( disable_preempt_count > 0 ); 416 suspend(); 417 verify( disable_preempt_count > 0 ); 418 419 enable_interrupts( DEBUG_CTX ); 420 } 421 422 void LeaveThread(spinlock * lock, thread_desc * thrd) { 423 verify( disable_preempt_count > 0 ); 424 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 425 this_processor->finish.lock = lock; 426 this_processor->finish.thrd = thrd; 427 385 428 suspend(); 386 429 } … … 392 435 // Kernel boot procedures 393 436 void kernel_startup(void) { 394 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 437 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 395 438 396 439 // Start by initializing the main thread 397 // SKULLDUGGERY: the mainThread steals the process main thread 398 // which will then be scheduled by the systemProcessor normally399 mainThread = (thread_desc *)& mainThread_storage;440 // SKULLDUGGERY: the mainThread steals the process main thread 441 // which will then be scheduled by the mainProcessor normally 442 mainThread = (thread_desc *)&storage_mainThread; 400 443 current_stack_info_t info; 401 444 mainThread{ &info }; … … 403 446 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 404 447 448 // Initialize the main cluster 449 mainCluster = (cluster *)&storage_mainCluster; 450 mainCluster{}; 451 452 LIB_DEBUG_PRINT_SAFE("Kernel : main cluster ready\n"); 453 454 // Initialize the main processor and the main processor ctx 455 // (the coroutine that contains the processing control flow) 456 mainProcessor = (processor *)&storage_mainProcessor; 457 mainProcessor{ mainCluster, (processorCtx_t *)&storage_mainProcessorCtx }; 458 459 //initialize the global state variables 460 this_processor = mainProcessor; 461 this_thread = mainThread; 462 this_coroutine = &mainThread->cor; 463 405 464 // Enable preemption 406 465 kernel_start_preemption(); 407 466 408 // Initialize the system cluster 409 systemCluster = (cluster *)&systemCluster_storage; 410 systemCluster{}; 411 412 LIB_DEBUG_PRINT_SAFE("Kernel : System cluster ready\n"); 413 414 // Initialize the system processor and the system processor ctx 415 // (the coroutine that contains the processing control flow) 416 systemProcessor = (system_proc_t *)&systemProcessor_storage; 417 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage }; 418 419 // Add the main thread to the ready queue 420 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread 467 // Add the main thread to the ready queue 468 // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread 421 469 ScheduleThread(mainThread); 422 470 423 //initialize the global state variables 424 this_processor = &systemProcessor->proc; 425 this_processor->current_thread = mainThread; 426 this_processor->current_coroutine = &mainThread->cor; 427 428 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 471 // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX 429 472 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 430 // mainThread is on the ready queue when this call is made. 431 resume( systemProcessor->proc.runner );473 // mainThread is on the ready queue when this call is made. 474 resume( mainProcessor->runner ); 432 475 433 476 … … 435 478 // THE SYSTEM IS NOW COMPLETELY RUNNING 436 479 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 480 481 enable_interrupts( DEBUG_CTX ); 437 482 } 438 483 … … 440 485 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 441 486 442 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. 487 disable_interrupts(); 488 489 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. 443 490 // When its coroutine terminates, it return control to the mainThread 444 491 // which is currently here 445 systemProcessor->proc.is_terminated= true;492 mainProcessor->do_terminate = true; 446 493 suspend(); 447 494 448 495 // THE SYSTEM IS NOW COMPLETELY STOPPED 449 496 450 // Destroy the system processor and its context in reverse order of construction 497 // Disable preemption 498 kernel_stop_preemption(); 499 500 // Destroy the main processor and its context in reverse order of construction 451 501 // These were manually constructed so we need manually destroy them 452 ^( systemProcessor->proc.runner){};453 ^( systemProcessor){};502 ^(mainProcessor->runner){}; 503 ^(mainProcessor){}; 454 504 455 505 // Final step, destroy the main thread since it is no longer needed … … 457 507 ^(mainThread){}; 458 508 459 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 509 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 460 510 } 461 511 … … 467 517 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 468 518 // the globalAbort flag is true. 469 lock( &kernel_abort_lock );519 lock( &kernel_abort_lock DEBUG_CTX2 ); 470 520 471 521 // first task to abort ? … … 473 523 kernel_abort_called = true; 474 524 unlock( &kernel_abort_lock ); 475 } 525 } 476 526 else { 477 527 unlock( &kernel_abort_lock ); 478 528 479 529 sigset_t mask; 480 530 sigemptyset( &mask ); … … 482 532 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals 483 533 sigsuspend( &mask ); // block the processor to prevent further damage during abort 484 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 485 } 486 487 return this_thread ();534 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 535 } 536 537 return this_thread; 488 538 } 489 539 … … 494 544 __lib_debug_write( STDERR_FILENO, abort_text, len ); 495 545 496 if ( thrd != this_coroutine ()) {497 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine ()->name, this_coroutine());546 if ( thrd != this_coroutine ) { 547 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine ); 498 548 __lib_debug_write( STDERR_FILENO, abort_text, len ); 499 } 549 } 500 550 else { 501 551 __lib_debug_write( STDERR_FILENO, ".\n", 2 ); … … 505 555 extern "C" { 506 556 void __lib_debug_acquire() { 507 lock( &kernel_debug_lock);557 lock( &kernel_debug_lock DEBUG_CTX2 ); 508 558 } 509 559 510 560 void __lib_debug_release() { 511 unlock( &kernel_debug_lock);561 unlock( &kernel_debug_lock ); 512 562 } 513 563 } … … 525 575 } 526 576 527 bool try_lock( spinlock * this ) {577 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) { 528 578 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0; 529 579 } 530 580 531 void lock( spinlock * this ) {581 void lock( spinlock * this DEBUG_CTX_PARAM2 ) { 532 582 for ( unsigned int i = 1;; i += 1 ) { 533 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break; 534 } 535 } 583 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 584 } 585 LIB_DEBUG_DO( 586 this->prev_name = caller; 587 this->prev_thrd = this_thread; 588 ) 589 } 590 591 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) { 592 for ( unsigned int i = 1;; i += 1 ) { 593 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 594 yield(); 595 } 596 LIB_DEBUG_DO( 597 this->prev_name = caller; 598 this->prev_thrd = this_thread; 599 ) 600 } 601 536 602 537 603 void unlock( spinlock * this ) { … … 539 605 } 540 606 541 void ?{}( signal_once * this ) { 542 this->cond = false; 543 } 544 void ^?{}( signal_once * this ) { 545 546 } 547 548 void wait( signal_once * this ) { 549 lock( &this->lock ); 550 if( !this->cond ) { 551 append( &this->blocked, this_thread() ); 552 ScheduleInternal( &this->lock ); 553 lock( &this->lock ); 554 } 607 void ?{}( semaphore * this, int count = 1 ) { 608 (&this->lock){}; 609 this->count = count; 610 (&this->waiting){}; 611 } 612 void ^?{}(semaphore * this) {} 613 614 void P(semaphore * this) { 615 lock( &this->lock DEBUG_CTX2 ); 616 this->count -= 1; 617 if ( this->count < 0 ) { 618 // queue current task 619 append( &this->waiting, (thread_desc *)this_thread ); 620 621 // atomically release spin lock and block 622 BlockInternal( &this->lock ); 623 } 624 else { 625 unlock( &this->lock ); 626 } 627 } 628 629 void V(semaphore * this) { 630 thread_desc * thrd = NULL; 631 lock( &this->lock DEBUG_CTX2 ); 632 this->count += 1; 633 if ( this->count <= 0 ) { 634 // remove task at head of waiting list 635 thrd = pop_head( &this->waiting ); 636 } 637 555 638 unlock( &this->lock ); 556 } 557 558 void signal( signal_once * this ) { 559 lock( &this->lock ); 560 { 561 this->cond = true; 562 563 thread_desc * it; 564 while( it = pop_head( &this->blocked) ) { 565 ScheduleThread( it ); 566 } 567 } 568 unlock( &this->lock ); 639 640 // make new owner 641 WakeThread( thrd ); 569 642 } 570 643 … … 590 663 } 591 664 head->next = NULL; 592 } 665 } 593 666 return head; 594 667 } … … 609 682 this->top = top->next; 610 683 top->next = NULL; 611 } 684 } 612 685 return top; 613 686 } -
src/libcfa/concurrency/kernel_private.h
rfea3faa rb826e6b 18 18 #define KERNEL_PRIVATE_H 19 19 20 #include "libhdr.h" 21 20 22 #include "kernel" 21 23 #include "thread" … … 23 25 #include "alarm.h" 24 26 25 #include "libhdr.h"26 27 27 28 //----------------------------------------------------------------------------- 28 29 // Scheduler 30 31 extern "C" { 32 void disable_interrupts(); 33 void enable_interrupts_noPoll(); 34 void enable_interrupts( DEBUG_CTX_PARAM ); 35 } 36 29 37 void ScheduleThread( thread_desc * ); 38 static inline void WakeThread( thread_desc * thrd ) { 39 if( !thrd ) return; 40 41 disable_interrupts(); 42 ScheduleThread( thrd ); 43 enable_interrupts( DEBUG_CTX ); 44 } 30 45 thread_desc * nextThread(cluster * this); 31 46 32 void ScheduleInternal(void); 33 void ScheduleInternal(spinlock * lock); 34 void ScheduleInternal(thread_desc * thrd); 35 void ScheduleInternal(spinlock * lock, thread_desc * thrd); 36 void ScheduleInternal(spinlock ** locks, unsigned short count); 37 void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count); 47 //Block current thread and release/wake-up the following resources 48 void BlockInternal(void); 49 void BlockInternal(spinlock * lock); 50 void BlockInternal(thread_desc * thrd); 51 void BlockInternal(spinlock * lock, thread_desc * thrd); 52 void BlockInternal(spinlock ** locks, unsigned short count); 53 void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count); 54 void LeaveThread(spinlock * lock, thread_desc * thrd); 38 55 39 56 //----------------------------------------------------------------------------- … … 49 66 void spin(processor * this, unsigned int * spin_count); 50 67 51 struct system_proc_t { 52 processor proc; 53 68 struct event_kernel_t { 54 69 alarm_list_t alarms; 55 spinlock alarm_lock; 56 57 bool pending_alarm; 70 spinlock lock; 58 71 }; 59 72 60 extern cluster * systemCluster; 61 extern system_proc_t * systemProcessor; 62 extern thread_local processor * this_processor; 73 extern event_kernel_t * event_kernel; 63 74 64 static inline void disable_interrupts() { 65 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 66 assert( prev != (unsigned short) -1 ); 67 } 68 69 static inline void enable_interrupts_noRF() { 70 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 71 verify( prev != (unsigned short) 0 ); 72 } 73 74 static inline void enable_interrupts() { 75 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 76 verify( prev != (unsigned short) 0 ); 77 if( prev == 1 && this_processor->pending_preemption ) { 78 ScheduleInternal( this_processor->current_thread ); 79 this_processor->pending_preemption = false; 80 } 81 } 75 extern volatile thread_local processor * this_processor; 76 extern volatile thread_local coroutine_desc * this_coroutine; 77 extern volatile thread_local thread_desc * this_thread; 78 extern volatile thread_local bool preemption_in_progress; 79 extern volatile thread_local unsigned short disable_preempt_count; 82 80 83 81 //----------------------------------------------------------------------------- … … 90 88 extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 91 89 90 //----------------------------------------------------------------------------- 91 // Utils 92 #define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)] 93 92 94 #endif //KERNEL_PRIVATE_H 93 95 -
src/libcfa/concurrency/monitor
rfea3faa rb826e6b 26 26 static inline void ?{}(monitor_desc * this) { 27 27 this->owner = NULL; 28 this->stack_owner = NULL;29 28 this->recursion = 0; 30 29 } -
src/libcfa/concurrency/monitor.c
rfea3faa rb826e6b 19 19 #include <stdlib> 20 20 21 #include "libhdr.h" 21 22 #include "kernel_private.h" 22 #include "libhdr.h"23 23 24 24 //----------------------------------------------------------------------------- … … 44 44 45 45 extern "C" { 46 void __enter_monitor_desc( monitor_desc * this) {47 lock ( &this->lock);48 thread_desc * thrd = this_thread ();49 50 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);46 void __enter_monitor_desc( monitor_desc * this ) { 47 lock_yield( &this->lock DEBUG_CTX2 ); 48 thread_desc * thrd = this_thread; 49 50 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 51 51 52 52 if( !this->owner ) { … … 62 62 //Some one else has the monitor, wait in line for it 63 63 append( &this->entry_queue, thrd ); 64 LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);65 ScheduleInternal( &this->lock );66 67 // ScheduleInternal will unlock spinlock, no need to unlock ourselves68 return; 64 // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 65 BlockInternal( &this->lock ); 66 67 //BlockInternal will unlock spinlock, no need to unlock ourselves 68 return; 69 69 } 70 70 … … 75 75 // leave pseudo code : 76 76 // TODO 77 void __leave_monitor_desc( monitor_desc * this) {78 lock ( &this->lock);79 80 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);81 verifyf( this_thread () == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );77 void __leave_monitor_desc( monitor_desc * this ) { 78 lock_yield( &this->lock DEBUG_CTX2 ); 79 80 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion); 81 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion ); 82 82 83 83 //Leaving a recursion level, decrement the counter … … 96 96 unlock( &this->lock ); 97 97 98 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);98 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner); 99 99 100 100 //We need to wake-up the thread 101 ScheduleThread( new_owner ); 101 WakeThread( new_owner ); 102 } 103 104 void __leave_thread_monitor( thread_desc * thrd ) { 105 monitor_desc * this = &thrd->mon; 106 lock_yield( &this->lock DEBUG_CTX2 ); 107 108 disable_interrupts(); 109 110 thrd->cor.state = Halted; 111 112 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 113 114 //Leaving a recursion level, decrement the counter 115 this->recursion -= 1; 116 117 //If we haven't left the last level of recursion 118 //it means we don't need to do anything 119 if( this->recursion != 0) { 120 unlock( &this->lock ); 121 return; 122 } 123 124 thread_desc * new_owner = next_thread( this ); 125 126 LeaveThread( &this->lock, new_owner ); 102 127 } 103 128 } … … 121 146 enter( this->m, this->count ); 122 147 123 this->prev_mntrs = this_thread ()->current_monitors;124 this->prev_count = this_thread ()->current_monitor_count;125 126 this_thread ()->current_monitors = m;127 this_thread ()->current_monitor_count = count;148 this->prev_mntrs = this_thread->current_monitors; 149 this->prev_count = this_thread->current_monitor_count; 150 151 this_thread->current_monitors = m; 152 this_thread->current_monitor_count = count; 128 153 } 129 154 … … 131 156 leave( this->m, this->count ); 132 157 133 this_thread ()->current_monitors = this->prev_mntrs;134 this_thread ()->current_monitor_count = this->prev_count;158 this_thread->current_monitors = this->prev_mntrs; 159 this_thread->current_monitor_count = this->prev_count; 135 160 } 136 161 … … 159 184 // Internal scheduling 160 185 void wait( condition * this, uintptr_t user_info = 0 ) { 161 LIB_DEBUG_PRINT_SAFE("Waiting\n");186 // LIB_DEBUG_PRINT_SAFE("Waiting\n"); 162 187 163 188 brand_condition( this ); … … 170 195 unsigned short count = this->monitor_count; 171 196 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 172 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal173 174 LIB_DEBUG_PRINT_SAFE("count %i\n", count);175 176 __condition_node_t waiter = { this_thread(), count, user_info };197 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 198 199 // LIB_DEBUG_PRINT_SAFE("count %i\n", count); 200 201 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info }; 177 202 178 203 __condition_criterion_t criteria[count]; 179 204 for(int i = 0; i < count; i++) { 180 205 (&criteria[i]){ this->monitors[i], &waiter }; 181 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );206 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 182 207 } 183 208 … … 201 226 } 202 227 203 LIB_DEBUG_PRINT_SAFE("Will unblock: ");228 // LIB_DEBUG_PRINT_SAFE("Will unblock: "); 204 229 for(int i = 0; i < thread_count; i++) { 205 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);206 } 207 LIB_DEBUG_PRINT_SAFE("\n");230 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 231 } 232 // LIB_DEBUG_PRINT_SAFE("\n"); 208 233 209 234 // Everything is ready to go to sleep 210 ScheduleInternal( locks, count, threads, thread_count );235 BlockInternal( locks, count, threads, thread_count ); 211 236 212 237 … … 222 247 bool signal( condition * this ) { 223 248 if( is_empty( this ) ) { 224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");249 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 225 250 return false; 226 251 } … … 231 256 232 257 unsigned short count = this->monitor_count; 233 258 234 259 //Some more checking in debug 235 260 LIB_DEBUG_DO( 236 thread_desc * this_thrd = this_thread ();261 thread_desc * this_thrd = this_thread; 237 262 if ( this->monitor_count != this_thrd->current_monitor_count ) { 238 263 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); … … 248 273 //Lock all the monitors 249 274 lock_all( this->monitors, NULL, count ); 250 LIB_DEBUG_PRINT_SAFE("Signalling");275 // LIB_DEBUG_PRINT_SAFE("Signalling"); 251 276 252 277 //Pop the head of the waiting queue … … 256 281 for(int i = 0; i < count; i++) { 257 282 __condition_criterion_t * crit = &node->criteria[i]; 258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);283 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 259 284 assert( !crit->ready ); 260 285 push( &crit->target->signal_stack, crit ); 261 286 } 262 287 263 LIB_DEBUG_PRINT_SAFE("\n");288 // LIB_DEBUG_PRINT_SAFE("\n"); 264 289 265 290 //Release … … 281 306 unsigned short count = this->monitor_count; 282 307 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 283 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal308 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 284 309 285 310 lock_all( this->monitors, locks, count ); 286 311 287 312 //create creteria 288 __condition_node_t waiter = { this_thread(), count, 0 };313 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 }; 289 314 290 315 __condition_criterion_t criteria[count]; 291 316 for(int i = 0; i < count; i++) { 292 317 (&criteria[i]){ this->monitors[i], &waiter }; 293 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );318 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 294 319 push( &criteria[i].target->signal_stack, &criteria[i] ); 295 320 } … … 309 334 310 335 //Everything is ready to go to sleep 311 ScheduleInternal( locks, count, &signallee, 1 );336 BlockInternal( locks, count, &signallee, 1 ); 312 337 313 338 … … 325 350 326 351 uintptr_t front( condition * this ) { 327 verifyf( !is_empty(this), 352 verifyf( !is_empty(this), 328 353 "Attempt to access user data on an empty condition.\n" 329 354 "Possible cause is not checking if the condition is empty before reading stored data." … … 335 360 // Internal scheduling 336 361 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 337 // thread_desc * this = this_thread ();362 // thread_desc * this = this_thread; 338 363 339 364 // unsigned short count = this->current_monitor_count; 340 365 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal366 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 342 367 343 368 // lock_all( this->current_monitors, locks, count ); … … 348 373 349 374 // // // Everything is ready to go to sleep 350 // // ScheduleInternal( locks, count, threads, thread_count );375 // // BlockInternal( locks, count, threads, thread_count ); 351 376 352 377 … … 393 418 static inline void lock_all( spinlock ** locks, unsigned short count ) { 394 419 for( int i = 0; i < count; i++ ) { 395 lock ( locks[i]);420 lock_yield( locks[i] DEBUG_CTX2 ); 396 421 } 397 422 } … … 400 425 for( int i = 0; i < count; i++ ) { 401 426 spinlock * l = &source[i]->lock; 402 lock ( l);427 lock_yield( l DEBUG_CTX2 ); 403 428 if(locks) locks[i] = l; 404 429 } … … 443 468 for( int i = 0; i < count; i++ ) { 444 469 445 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );470 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 446 471 if( &criteria[i] == target ) { 447 472 criteria[i].ready = true; 448 LIB_DEBUG_PRINT_SAFE( "True\n" );473 // LIB_DEBUG_PRINT_SAFE( "True\n" ); 449 474 } 450 475 … … 452 477 } 453 478 454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );479 // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 455 480 return ready2run ? node->waiting_thread : NULL; 456 481 } 457 482 458 483 static inline void brand_condition( condition * this ) { 459 thread_desc * thrd = this_thread ();484 thread_desc * thrd = this_thread; 460 485 if( !this->monitors ) { 461 LIB_DEBUG_PRINT_SAFE("Branding\n");486 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 462 487 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 463 488 this->monitor_count = thrd->current_monitor_count; -
src/libcfa/concurrency/preemption.c
rfea3faa rb826e6b 15 15 // 16 16 17 #include "libhdr.h" 17 18 #include "preemption.h" 18 19 19 20 extern "C" { 21 #include <errno.h> 22 #include <execinfo.h> 23 #define __USE_GNU 20 24 #include <signal.h> 21 } 22 23 #define __CFA_DEFAULT_PREEMPTION__ 10 24 25 #undef __USE_GNU 26 #include <stdio.h> 27 #include <string.h> 28 #include <unistd.h> 29 } 30 31 32 #ifdef __USE_STREAM__ 33 #include "fstream" 34 #endif 35 36 //TODO move to defaults 37 #define __CFA_DEFAULT_PREEMPTION__ 10000 38 39 //TODO move to defaults 25 40 __attribute__((weak)) unsigned int default_preemption() { 26 41 return __CFA_DEFAULT_PREEMPTION__; 27 42 } 28 43 44 // Short hands for signal context information 45 #define __CFA_SIGCXT__ ucontext_t * 46 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt 47 48 // FwdDeclarations : timeout handlers 29 49 static void preempt( processor * this ); 30 50 static void timeout( thread_desc * this ); 31 51 52 // FwdDeclarations : Signal handlers 53 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 54 void sigHandler_segv ( __CFA_SIGPARMS__ ); 55 void sigHandler_abort ( __CFA_SIGPARMS__ ); 56 57 // FwdDeclarations : sigaction wrapper 58 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ); 59 60 // FwdDeclarations : alarm thread main 61 void * alarm_loop( __attribute__((unused)) void * args ); 62 63 // Machine specific register name 64 #ifdef __x86_64__ 65 #define CFA_REG_IP REG_RIP 66 #else 67 #define CFA_REG_IP REG_EIP 68 #endif 69 70 KERNEL_STORAGE(event_kernel_t, event_kernel); // private storage for event kernel 71 event_kernel_t * event_kernel; // kernel public handle to even kernel 72 static pthread_t alarm_thread; // pthread handle to alarm thread 73 74 void ?{}(event_kernel_t * this) { 75 (&this->alarms){}; 76 (&this->lock){}; 77 } 78 32 79 //============================================================================================= 33 80 // Kernel Preemption logic 34 81 //============================================================================================= 35 82 36 void kernel_start_preemption() { 37 38 } 39 83 // Get next expired node 84 static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_t currtime ) { 85 if( !alarms->head ) return NULL; // If no alarms return null 86 if( alarms->head->alarm >= currtime ) return NULL; // If alarms head not expired return null 87 return pop(alarms); // Otherwise just pop head 88 } 89 90 // Tick one frame of the Discrete Event Simulation for alarms 40 91 void tick_preemption() { 41 alarm_list_t * alarms = &systemProcessor->alarms; 42 __cfa_time_t currtime = __kernel_get_time(); 43 while( alarms->head && alarms->head->alarm < currtime ) { 44 alarm_node_t * node = pop(alarms); 92 alarm_node_t * node = NULL; // Used in the while loop but cannot be declared in the while condition 93 alarm_list_t * alarms = &event_kernel->alarms; // Local copy for ease of reading 94 __cfa_time_t currtime = __kernel_get_time(); // Check current time once so we everything "happens at once" 95 96 //Loop throught every thing expired 97 while( node = get_expired( alarms, currtime ) ) { 98 99 // Check if this is a kernel 45 100 if( node->kernel_alarm ) { 46 101 preempt( node->proc ); … … 50 105 } 51 106 52 if( node->period > 0 ) { 53 node->alarm += node->period; 54 insert( alarms, node ); 107 // Check if this is a periodic alarm 108 __cfa_time_t period = node->period; 109 if( period > 0 ) { 110 node->alarm = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) 111 insert( alarms, node ); // Reinsert the node for the next time it triggers 55 112 } 56 113 else { 57 node->set = false; 58 } 59 } 60 61 if( alarms->head ) {62 __kernel_set_timer( alarms->head->alarm - currtime );63 }64 } 65 114 node->set = false; // Node is one-shot, just mark it as not pending 115 } 116 } 117 118 // If there are still alarms pending, reset the timer 119 if( alarms->head ) { __kernel_set_timer( alarms->head->alarm - currtime ); } 120 } 121 122 // Update the preemption of a processor and notify interested parties 66 123 void update_preemption( processor * this, __cfa_time_t duration ) { 67 // assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );68 124 alarm_node_t * alarm = this->preemption_alarm; 69 125 … … 89 145 } 90 146 147 //============================================================================================= 148 // Kernel Signal Tools 149 //============================================================================================= 150 151 LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; ) 152 153 extern "C" { 154 // Disable interrupts by incrementing the counter 155 void disable_interrupts() { 156 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 157 verify( new_val < 65_000u ); // If this triggers someone is disabling interrupts without enabling them 158 } 159 160 // Enable interrupts by decrementing the counter 161 // If counter reaches 0, execute any pending CtxSwitch 162 void enable_interrupts( DEBUG_CTX_PARAM ) { 163 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 164 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 165 166 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 167 verify( prev != 0u ); // If this triggers someone is enabled already enabled interruptsverify( prev != 0u ); 168 169 // Check if we need to prempt the thread because an interrupt was missed 170 if( prev == 1 && proc->pending_preemption ) { 171 proc->pending_preemption = false; 172 BlockInternal( thrd ); 173 } 174 175 // For debugging purposes : keep track of the last person to enable the interrupts 176 LIB_DEBUG_DO( proc->last_enable = caller; ) 177 } 178 179 // Disable interrupts by incrementint the counter 180 // Don't execute any pending CtxSwitch even if counter reaches 0 181 void enable_interrupts_noPoll() { 182 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 183 verify( prev != 0u ); // If this triggers someone is enabled already enabled interrupts 184 } 185 } 186 187 // sigprocmask wrapper : unblock a single signal 188 static inline void signal_unblock( int sig ) { 189 sigset_t mask; 190 sigemptyset( &mask ); 191 sigaddset( &mask, sig ); 192 193 if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) { 194 abortf( "internal error, pthread_sigmask" ); 195 } 196 } 197 198 // sigprocmask wrapper : block a single signal 199 static inline void signal_block( int sig ) { 200 sigset_t mask; 201 sigemptyset( &mask ); 202 sigaddset( &mask, sig ); 203 204 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 205 abortf( "internal error, pthread_sigmask" ); 206 } 207 } 208 209 // kill wrapper : signal a processor 210 static void preempt( processor * this ) { 211 pthread_kill( this->kernel_thread, SIGUSR1 ); 212 } 213 214 // reserved for future use 215 static void timeout( thread_desc * this ) { 216 //TODO : implement waking threads 217 } 218 219 220 // Check if a CtxSwitch signal handler shoud defer 221 // If true : preemption is safe 222 // If false : preemption is unsafe and marked as pending 223 static inline bool preemption_ready() { 224 bool ready = disable_preempt_count == 0 && !preemption_in_progress; // Check if preemption is safe 225 this_processor->pending_preemption = !ready; // Adjust the pending flag accordingly 226 return ready; 227 } 228 229 //============================================================================================= 230 // Kernel Signal Startup/Shutdown logic 231 //============================================================================================= 232 233 // Startup routine to activate preemption 234 // Called from kernel_startup 235 void kernel_start_preemption() { 236 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n"); 237 238 // Start with preemption disabled until ready 239 disable_preempt_count = 1; 240 241 // Initialize the event kernel 242 event_kernel = (event_kernel_t *)&storage_event_kernel; 243 event_kernel{}; 244 245 // Setup proper signal handlers 246 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); // CtxSwitch handler 247 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler 248 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler 249 250 signal_block( SIGALRM ); 251 252 pthread_create( &alarm_thread, NULL, alarm_loop, NULL ); 253 } 254 255 // Shutdown routine to deactivate preemption 256 // Called from kernel_shutdown 257 void kernel_stop_preemption() { 258 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n"); 259 260 // Block all signals since we are already shutting down 261 sigset_t mask; 262 sigfillset( &mask ); 263 sigprocmask( SIG_BLOCK, &mask, NULL ); 264 265 // Notify the alarm thread of the shutdown 266 sigval val = { 1 }; 267 pthread_sigqueue( alarm_thread, SIGALRM, val ); 268 269 // Wait for the preemption thread to finish 270 pthread_join( alarm_thread, NULL ); 271 272 // Preemption is now fully stopped 273 274 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n"); 275 } 276 277 // Raii ctor/dtor for the preemption_scope 278 // Used by thread to control when they want to receive preemption signals 91 279 void ?{}( preemption_scope * this, processor * proc ) { 92 (&this->alarm){ proc };280 (&this->alarm){ proc, zero_time, zero_time }; 93 281 this->proc = proc; 94 282 this->proc->preemption_alarm = &this->alarm; 95 update_preemption( this->proc, this->proc->preemption ); 283 284 update_preemption( this->proc, from_us(this->proc->cltr->preemption) ); 96 285 } 97 286 98 287 void ^?{}( preemption_scope * this ) { 99 update_preemption( this->proc, 0 ); 100 } 101 102 //============================================================================================= 103 // Kernel Signal logic 104 //============================================================================================= 105 106 static inline bool preemption_ready() { 107 return this_processor->disable_preempt_count == 0; 108 } 109 110 static inline void defer_ctxSwitch() { 111 this_processor->pending_preemption = true; 112 } 113 114 static inline void defer_alarm() { 115 systemProcessor->pending_alarm = true; 116 } 117 118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) { 119 if( preemption_ready() ) { 120 ScheduleInternal( this_processor->current_thread ); 121 } 122 else { 123 defer_ctxSwitch(); 124 } 125 } 126 127 void sigHandler_alarm( __attribute__((unused)) int sig ) { 128 if( try_lock( &systemProcessor->alarm_lock ) ) { 129 tick_preemption(); 130 unlock( &systemProcessor->alarm_lock ); 131 } 132 else { 133 defer_alarm(); 134 } 135 } 136 137 static void preempt( processor * this ) { 138 pthread_kill( this->kernel_thread, SIGUSR1 ); 139 } 140 141 static void timeout( thread_desc * this ) { 142 //TODO : implement waking threads 143 } 288 disable_interrupts(); 289 290 update_preemption( this->proc, zero_time ); 291 } 292 293 //============================================================================================= 294 // Kernel Signal Handlers 295 //============================================================================================= 296 297 // Context switch signal handler 298 // Receives SIGUSR1 signal and causes the current thread to yield 299 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 300 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 301 302 // Check if it is safe to preempt here 303 if( !preemption_ready() ) { return; } 304 305 preemption_in_progress = true; // Sync flag : prevent recursive calls to the signal handler 306 signal_unblock( SIGUSR1 ); // We are about to CtxSwitch out of the signal handler, let other handlers in 307 preemption_in_progress = false; // Clear the in progress flag 308 309 // Preemption can occur here 310 311 BlockInternal( (thread_desc*)this_thread ); // Do the actual CtxSwitch 312 } 313 314 // Main of the alarm thread 315 // Waits on SIGALRM and send SIGUSR1 to whom ever needs it 316 void * alarm_loop( __attribute__((unused)) void * args ) { 317 // Block sigalrms to control when they arrive 318 sigset_t mask; 319 sigemptyset( &mask ); 320 sigaddset( &mask, SIGALRM ); 321 322 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 323 abortf( "internal error, pthread_sigmask" ); 324 } 325 326 // Main loop 327 while( true ) { 328 // Wait for a sigalrm 329 siginfo_t info; 330 int sig = sigwaitinfo( &mask, &info ); 331 332 // If another signal arrived something went wrong 333 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 334 335 LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int ); 336 // Switch on the code (a.k.a. the sender) to 337 switch( info.si_code ) 338 { 339 // Timers can apparently be marked as sent for the kernel 340 // In either case, tick preemption 341 case SI_TIMER: 342 case SI_KERNEL: 343 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 344 lock( &event_kernel->lock DEBUG_CTX2 ); 345 tick_preemption(); 346 unlock( &event_kernel->lock ); 347 break; 348 // Signal was not sent by the kernel but by an other thread 349 case SI_QUEUE: 350 // For now, other thread only signal the alarm thread to shut it down 351 // If this needs to change use info.si_value and handle the case here 352 goto EXIT; 353 } 354 } 355 356 EXIT: 357 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n"); 358 return NULL; 359 } 360 361 // Sigaction wrapper : register an signal handler 362 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) { 363 struct sigaction act; 364 365 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; 366 act.sa_flags = flags; 367 368 if ( sigaction( sig, &act, NULL ) == -1 ) { 369 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, 370 " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n", 371 sig, handler, flags, errno, strerror( errno ) 372 ); 373 _exit( EXIT_FAILURE ); 374 } 375 } 376 377 // Sigaction wrapper : restore default handler 378 static void __kernel_sigdefault( int sig ) { 379 struct sigaction act; 380 381 act.sa_handler = SIG_DFL; 382 act.sa_flags = 0; 383 sigemptyset( &act.sa_mask ); 384 385 if ( sigaction( sig, &act, NULL ) == -1 ) { 386 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, 387 " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n", 388 sig, errno, strerror( errno ) 389 ); 390 _exit( EXIT_FAILURE ); 391 } 392 } 393 394 //============================================================================================= 395 // Terminating Signals logic 396 //============================================================================================= 397 398 LIB_DEBUG_DO( 399 static void __kernel_backtrace( int start ) { 400 // skip first N stack frames 401 402 enum { Frames = 50 }; 403 void * array[Frames]; 404 int size = backtrace( array, Frames ); 405 char ** messages = backtrace_symbols( array, size ); 406 407 // find executable name 408 *index( messages[0], '(' ) = '\0'; 409 #ifdef __USE_STREAM__ 410 serr | "Stack back trace for:" | messages[0] | endl; 411 #else 412 fprintf( stderr, "Stack back trace for: %s\n", messages[0]); 413 #endif 414 415 // skip last 2 stack frames after main 416 for ( int i = start; i < size && messages != NULL; i += 1 ) { 417 char * name = NULL; 418 char * offset_begin = NULL; 419 char * offset_end = NULL; 420 421 for ( char *p = messages[i]; *p; ++p ) { 422 // find parantheses and +offset 423 if ( *p == '(' ) { 424 name = p; 425 } 426 else if ( *p == '+' ) { 427 offset_begin = p; 428 } 429 else if ( *p == ')' ) { 430 offset_end = p; 431 break; 432 } 433 } 434 435 // if line contains symbol print it 436 int frameNo = i - start; 437 if ( name && offset_begin && offset_end && name < offset_begin ) { 438 // delimit strings 439 *name++ = '\0'; 440 *offset_begin++ = '\0'; 441 *offset_end++ = '\0'; 442 443 #ifdef __USE_STREAM__ 444 serr | "(" | frameNo | ")" | messages[i] | ":" 445 | name | "+" | offset_begin | offset_end | endl; 446 #else 447 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end); 448 #endif 449 } 450 // otherwise, print the whole line 451 else { 452 #ifdef __USE_STREAM__ 453 serr | "(" | frameNo | ")" | messages[i] | endl; 454 #else 455 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] ); 456 #endif 457 } 458 } 459 460 free( messages ); 461 } 462 ) 463 464 // void sigHandler_segv( __CFA_SIGPARMS__ ) { 465 // LIB_DEBUG_DO( 466 // #ifdef __USE_STREAM__ 467 // serr | "*CFA runtime error* program cfa-cpp terminated with" 468 // | (sig == SIGSEGV ? "segment fault." : "bus error.") 469 // | endl; 470 // #else 471 // fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." ); 472 // #endif 473 474 // // skip first 2 stack frames 475 // __kernel_backtrace( 1 ); 476 // ) 477 // exit( EXIT_FAILURE ); 478 // } 479 480 // void sigHandler_abort( __CFA_SIGPARMS__ ) { 481 // // skip first 6 stack frames 482 // LIB_DEBUG_DO( __kernel_backtrace( 6 ); ) 483 484 // // reset default signal handler 485 // __kernel_sigdefault( SIGABRT ); 486 487 // raise( SIGABRT ); 488 // } -
src/libcfa/concurrency/thread
rfea3faa rb826e6b 54 54 } 55 55 56 thread_desc * this_thread(void);56 extern volatile thread_local thread_desc * this_thread; 57 57 58 58 forall( dtype T | is_thread(T) ) -
src/libcfa/concurrency/thread.c
rfea3faa rb826e6b 28 28 } 29 29 30 extern thread_local processor * this_processor;30 extern volatile thread_local processor * this_processor; 31 31 32 32 //----------------------------------------------------------------------------- … … 71 71 coroutine_desc* thrd_c = get_coroutine(this); 72 72 thread_desc* thrd_h = get_thread (this); 73 thrd_c->last = this_coroutine(); 74 this_processor->current_coroutine = thrd_c; 73 thrd_c->last = this_coroutine; 75 74 76 LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);75 // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 77 76 77 disable_interrupts(); 78 78 create_stack(&thrd_c->stack, thrd_c->stack.size); 79 this_coroutine = thrd_c; 79 80 CtxStart(this, CtxInvokeThread); 81 assert( thrd_c->last->stack.context ); 80 82 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 81 83 82 84 ScheduleThread(thrd_h); 85 enable_interrupts( DEBUG_CTX ); 83 86 } 84 87 85 88 void yield( void ) { 86 ScheduleInternal( this_processor->current_thread );89 BlockInternal( (thread_desc *)this_thread ); 87 90 } 88 91 … … 95 98 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 96 99 // set state of current coroutine to inactive 97 src->state = Inactive;100 src->state = src->state == Halted ? Halted : Inactive; 98 101 dst->state = Active; 99 102 … … 103 106 // set new coroutine that the processor is executing 104 107 // and context switch to it 105 this_processor->current_coroutine = dst; 108 this_coroutine = dst; 109 assert( src->stack.context ); 106 110 CtxSwitch( src->stack.context, dst->stack.context ); 107 this_ processor->current_coroutine = src;111 this_coroutine = src; 108 112 109 113 // set state of new coroutine to active 110 dst->state = Inactive;114 dst->state = dst->state == Halted ? Halted : Inactive; 111 115 src->state = Active; 112 116 } -
src/libcfa/fstream
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:11:09201713 // Update Count : 1 0412 // Last Modified On : Fri Jul 7 08:32:38 2017 13 // Update Count : 117 14 14 // 15 15 16 #ifndef __FSTREAM_H__ 17 #define __FSTREAM_H__ 16 #pragma once 18 17 19 18 #include "iostream" 20 19 21 enum { sep arateSize = 16 };20 enum { sepSize = 16 }; 22 21 struct ofstream { 23 22 void * file; 24 23 _Bool sepDefault; 25 24 _Bool sepOnOff; 25 _Bool sawNL; 26 26 const char * sepCur; 27 char separator[sep arateSize];28 char tupleSeparator[sep arateSize];27 char separator[sepSize]; 28 char tupleSeparator[sepSize]; 29 29 }; // ofstream 30 30 … … 35 35 const char * sepGetCur( ofstream * ); 36 36 void sepSetCur( ofstream *, const char * ); 37 _Bool getNL( ofstream * ); 38 void setNL( ofstream *, _Bool ); 37 39 38 40 // public … … 73 75 extern ifstream * sin; 74 76 75 #endif // __FSTREAM_H__76 77 77 // Local Variables: // 78 78 // mode: c // -
src/libcfa/fstream.c
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:11:11201713 // Update Count : 2 3412 // Last Modified On : Thu Jul 6 18:38:25 2017 13 // Update Count : 251 14 14 // 15 15 … … 39 39 40 40 // private 41 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; }41 _Bool sepPrt( ofstream * os ) { setNL( os, false ); return os->sepOnOff; } 42 42 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 43 43 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 44 44 const char * sepGetCur( ofstream * os ) { return os->sepCur; } 45 45 void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; } 46 _Bool getNL( ofstream * os ) { return os->sawNL; } 47 void setNL( ofstream * os, _Bool state ) { os->sawNL = state; } 46 48 47 49 // public 48 void sepOn( ofstream * os ) { os->sepOnOff = 1; }49 void sepOff( ofstream * os ) { os->sepOnOff = 0; }50 void sepOn( ofstream * os ) { os->sepOnOff = ! getNL( os ); } 51 void sepOff( ofstream * os ) { os->sepOnOff = false; } 50 52 51 53 _Bool sepDisable( ofstream *os ) { … … 66 68 void sepSet( ofstream * os, const char * s ) { 67 69 assert( s ); 68 strncpy( os->separator, s, sep arateSize - 1 );69 os->separator[sep arateSize - 1] = '\0';70 strncpy( os->separator, s, sepSize - 1 ); 71 os->separator[sepSize - 1] = '\0'; 70 72 } // sepSet 71 73 … … 73 75 void sepSetTuple( ofstream * os, const char * s ) { 74 76 assert( s ); 75 strncpy( os->tupleSeparator, s, sep arateSize - 1 );76 os->tupleSeparator[sep arateSize - 1] = '\0';77 strncpy( os->tupleSeparator, s, sepSize - 1 ); 78 os->tupleSeparator[sepSize - 1] = '\0'; 77 79 } // sepSet 78 80 … … 92 94 exit( EXIT_FAILURE ); 93 95 } // if 94 ?{}( os, file, 1, 0, " ", ", " );96 ?{}( os, file, true, false, " ", ", " ); 95 97 } // open 96 98 … … 132 134 } // fmt 133 135 134 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, " ", ", " };136 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " }; 135 137 ofstream *sout = &soutFile; 136 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, " ", ", " };138 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " }; 137 139 ofstream *serr = &serrFile; 138 140 … … 150 152 151 153 void open( ifstream * is, const char * name, const char * mode ) { 152 FILE * t= fopen( name, mode );153 if ( t == 0 ) {// do not change unless successful154 FILE *file = fopen( name, mode ); 155 if ( file == 0 ) { // do not change unless successful 154 156 fprintf( stderr, IO_MSG "open input file \"%s\", ", name ); 155 157 perror( 0 ); 156 158 exit( EXIT_FAILURE ); 157 159 } // if 158 is->file = t;160 is->file = file; 159 161 } // open 160 162 -
src/libcfa/gmp
rfea3faa rb826e6b 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 27 09:55:51201713 // Update Count : 1 412 // Last Modified On : Fri Jul 7 09:33:20 2017 13 // Update Count : 15 14 14 // 15 15 16 16 // https://gmplib.org/gmp-man-6.1.1.pdf 17 18 #pragma once 17 19 18 20 #include <gmp.h> // GNU multi-precise integers -
src/libcfa/iostream
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:08:44201713 // Update Count : 1 0512 // Last Modified On : Fri Jul 7 08:35:59 2017 13 // Update Count : 118 14 14 // 15 15 16 #ifndef __IOSTREAM_H__ 17 #define __IOSTREAM_H__ 16 #pragma once 18 17 19 18 #include "iterator" … … 26 25 const char * sepGetCur( ostype * ); // get current separator string 27 26 void sepSetCur( ostype *, const char * ); // set current separator string 27 _Bool getNL( ostype * ); // check newline 28 void setNL( ostype *, _Bool ); // saw newline 28 29 // public 29 30 void sepOn( ostype * ); // turn separator state on … … 43 44 ostype * write( ostype *, const char *, unsigned long int ); 44 45 int fmt( ostype *, const char fmt[], ... ); 45 }; 46 }; // ostream 46 47 47 48 trait writeable( otype T ) { 48 49 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T ); 49 }; 50 }; // writeable 50 51 51 52 // implement writable for intrinsic types … … 81 82 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, ostype * (*)( ostype * ) ); 82 83 forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * ); 84 forall( dtype ostype | ostream( ostype ) ) ostype * sep( ostype * ); 85 forall( dtype ostype | ostream( ostype ) ) ostype * sepTuple( ostype * ); 83 86 forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * ); 84 87 forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * ); … … 103 106 istype * ungetc( istype *, char ); 104 107 int fmt( istype *, const char fmt[], ... ); 105 }; 108 }; // istream 106 109 107 110 trait readable( otype T ) { 108 111 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T ); 109 }; 112 }; // readable 110 113 111 114 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, char * ); … … 136 139 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC ); 137 140 138 #endif // __IOSTREAM_H139 140 141 // Local Variables: // 141 142 // mode: c // -
src/libcfa/iostream.c
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 8 18:24:23 201713 // Update Count : 3 6912 // Last Modified On : Sun Jul 16 21:12:03 2017 13 // Update Count : 398 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <stdio.h> 20 #include <stdbool.h> // true/false 20 21 #include <string.h> // strlen 21 22 #include <float.h> // DBL_DIG, LDBL_DIG … … 24 25 25 26 forall( dtype ostype | ostream( ostype ) ) 26 ostype * ?|?( ostype * os, char c ) { 27 fmt( os, "%c", c ); 27 ostype * ?|?( ostype * os, char ch ) { 28 fmt( os, "%c", ch ); 29 if ( ch == '\n' ) setNL( os, true ); 28 30 sepOff( os ); 29 31 return os; … … 123 125 forall( dtype ostype | ostream( ostype ) ) 124 126 ostype * ?|?( ostype * os, float _Complex fc ) { 125 os | crealf( fc ); 126 _Bool temp = sepDisable( os ); // disable separators within complex value 127 if ( cimagf( fc ) >= 0 ) os | '+'; // negative value prints '-' 128 os | cimagf( fc ) | 'i'; 129 sepReset( os, temp ); // reset separator 127 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); 128 fmt( os, "%g%+gi", crealf( fc ), cimagf( fc ) ); 130 129 return os; 131 130 } // ?|? … … 133 132 forall( dtype ostype | ostream( ostype ) ) 134 133 ostype * ?|?( ostype * os, double _Complex dc ) { 135 os | creal( dc ); 136 _Bool temp = sepDisable( os ); // disable separators within complex value 137 if ( cimag( dc ) >= 0 ) os | '+'; // negative value prints '-' 138 os | cimag( dc ) | 'i'; 139 sepReset( os, temp ); // reset separator 134 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); 135 fmt( os, "%.*lg%+.*lgi", DBL_DIG, creal( dc ), DBL_DIG, cimag( dc ) ); 140 136 return os; 141 137 } // ?|? … … 143 139 forall( dtype ostype | ostream( ostype ) ) 144 140 ostype * ?|?( ostype * os, long double _Complex ldc ) { 145 os | creall( ldc ); 146 _Bool temp = sepDisable( os ); // disable separators within complex value 147 if ( cimagl( ldc ) >= 0 ) os | '+'; // negative value prints '-' 148 os | cimagl( ldc ) | 'i'; 149 sepReset( os, temp ); // reset separator 141 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); 142 fmt( os, "%.*Lg%+.*Lgi", LDBL_DIG, creall( ldc ), LDBL_DIG, cimagl( ldc ) ); 150 143 return os; 151 144 } // ?|? … … 180 173 181 174 // last character IS spacing or opening punctuation => turn off separator for next item 182 unsigned int len = strlen( cp ), posn = len - 1;183 ch = cp[ posn];// must make unsigned175 size_t len = strlen( cp ); 176 ch = cp[len - 1]; // must make unsigned 184 177 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) { 185 178 sepOn( os ); … … 187 180 sepOff( os ); 188 181 } // if 182 if ( ch == '\n' ) setNL( os, true ); // check *AFTER* sepPrt call above as it resets NL flag 189 183 return write( os, cp, len ); 190 184 } // ?|? … … 201 195 forall( dtype ostype, otype T, ttype Params | ostream( ostype ) | writeable( T ) | { ostype * ?|?( ostype *, Params ); } ) 202 196 ostype * ?|?( ostype * os, T arg, Params rest ) { 197 os | arg; // print first argument 203 198 sepSetCur( os, sepGetTuple( os ) ); // switch to tuple separator 204 os | arg; // print first argument205 199 os | rest; // print remaining arguments 206 200 sepSetCur( os, sepGet( os ) ); // switch to regular separator … … 216 210 217 211 forall( dtype ostype | ostream( ostype ) ) 212 ostype * sep( ostype * os ) { 213 os | sepGet( os ); 214 return os; 215 } // sep 216 217 forall( dtype ostype | ostream( ostype ) ) 218 ostype * sepTuple( ostype * os ) { 219 os | sepGetTuple( os ); 220 return os; 221 } // sepTuple 222 223 forall( dtype ostype | ostream( ostype ) ) 218 224 ostype * endl( ostype * os ) { 219 225 os | '\n'; 226 setNL( os, true ); 220 227 flush( os ); 221 228 sepOff( os ); // prepare for next line -
src/libcfa/iterator
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 18:06:05 201613 // Update Count : 912 // Last Modified On : Fri Jul 7 08:37:25 2017 13 // Update Count : 10 14 14 // 15 15 16 #ifndef ITERATOR_H 17 #define ITERATOR_H 16 #pragma once 18 17 19 18 // An iterator can be used to traverse a data structure. … … 39 38 40 39 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 41 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) );40 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 42 41 43 42 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 44 void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) ); 45 46 #endif // ITERATOR_H 43 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 47 44 48 45 // Local Variables: // -
src/libcfa/iterator.c
rfea3faa rb826e6b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 18:08:11 201613 // Update Count : 2 712 // Last Modified On : Fri Jul 7 08:38:23 2017 13 // Update Count : 28 14 14 // 15 15 … … 17 17 18 18 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 19 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {19 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 20 20 for ( iterator_type i = begin; i != end; ++i ) { 21 21 func( *i ); 22 } 23 } 22 } // for 23 } // for_each 24 24 25 25 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 26 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {26 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 27 27 for ( iterator_type i = end; i != begin; ) { 28 28 --i; 29 29 func( *i ); 30 } 31 } 30 } // for 31 } // for_each_reverse 32 32 33 33 // Local Variables: // -
src/libcfa/libhdr/libalign.h
rfea3faa rb826e6b 1 // -*- Mode: C++ -*- 1 // -*- Mode: C++ -*- 2 2 // 3 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 18 18 // Free Software Foundation; either version 2.1 of the License, or (at your 19 19 // option) any later version. 20 // 20 // 21 21 // This library is distributed in the hope that it will be useful, but WITHOUT 22 22 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 23 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 24 24 // for more details. 25 // 25 // 26 26 // You should have received a copy of the GNU Lesser General Public License 27 27 // along with this library. 28 // 28 // 29 29 30 30 … … 33 33 34 34 #include "assert" 35 #include <stdbool.h> 35 36 36 // Minimum size used to align memory boundaries for memory allocations. 37 // Minimum size used to align memory boundaries for memory allocations. 37 38 #define libAlign() (sizeof(double)) 38 39 -
src/libcfa/libhdr/libdebug.h
rfea3faa rb826e6b 18 18 19 19 #ifdef __CFA_DEBUG__ 20 #define LIB_DEBUG_DO(x) x 21 #define LIB_NO_DEBUG_DO(x) ((void)0) 20 #define LIB_DEBUG_DO(...) __VA_ARGS__ 21 #define LIB_NO_DEBUG_DO(...) 22 #define DEBUG_CTX __PRETTY_FUNCTION__ 23 #define DEBUG_CTX2 , __PRETTY_FUNCTION__ 24 #define DEBUG_CTX_PARAM const char * caller 25 #define DEBUG_CTX_PARAM2 , const char * caller 22 26 #else 23 #define LIB_DEBUG_DO(x) ((void)0) 24 #define LIB_NO_DEBUG_DO(x) x 27 #define LIB_DEBUG_DO(...) 28 #define LIB_NO_DEBUG_DO(...) __VA_ARGS__ 29 #define DEBUG_CTX 30 #define DEBUG_CTX2 31 #define DEBUG_CTX_PARAM 32 #define DEBUG_CTX_PARAM2 25 33 #endif 26 34 … … 51 59 52 60 #ifdef __CFA_DEBUG_PRINT__ 53 #define LIB_DEBUG_WRITE( fd, buffer, len ) __lib_debug_write( fd, buffer, len ) 54 #define LIB_DEBUG_ACQUIRE() __lib_debug_acquire() 55 #define LIB_DEBUG_RELEASE() __lib_debug_release() 56 #define LIB_DEBUG_PRINT_SAFE(...) __lib_debug_print_safe (__VA_ARGS__) 57 #define LIB_DEBUG_PRINT_NOLOCK(...) __lib_debug_print_nolock (__VA_ARGS__) 58 #define LIB_DEBUG_PRINT_BUFFER(...) __lib_debug_print_buffer (__VA_ARGS__) 61 #define LIB_DEBUG_WRITE( fd, buffer, len ) __lib_debug_write( fd, buffer, len ) 62 #define LIB_DEBUG_ACQUIRE() __lib_debug_acquire() 63 #define LIB_DEBUG_RELEASE() __lib_debug_release() 64 #define LIB_DEBUG_PRINT_SAFE(...) __lib_debug_print_safe (__VA_ARGS__) 65 #define LIB_DEBUG_PRINT_NOLOCK(...) __lib_debug_print_nolock (__VA_ARGS__) 66 #define LIB_DEBUG_PRINT_BUFFER(...) __lib_debug_print_buffer (__VA_ARGS__) 67 #define LIB_DEBUG_PRINT_BUFFER_DECL(fd, ...) char text[256]; int len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len ); 68 #define LIB_DEBUG_PRINT_BUFFER_LOCAL(fd, ...) len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len ); 59 69 #else 60 #define LIB_DEBUG_WRITE(...) ((void)0) 61 #define LIB_DEBUG_ACQUIRE() ((void)0) 62 #define LIB_DEBUG_RELEASE() ((void)0) 63 #define LIB_DEBUG_PRINT_SAFE(...) ((void)0) 64 #define LIB_DEBUG_PRINT_NOLOCK(...) ((void)0) 65 #define LIB_DEBUG_PRINT_BUFFER(...) ((void)0) 70 #define LIB_DEBUG_WRITE(...) ((void)0) 71 #define LIB_DEBUG_ACQUIRE() ((void)0) 72 #define LIB_DEBUG_RELEASE() ((void)0) 73 #define LIB_DEBUG_PRINT_SAFE(...) ((void)0) 74 #define LIB_DEBUG_PRINT_NOLOCK(...) ((void)0) 75 #define LIB_DEBUG_PRINT_BUFFER(...) ((void)0) 76 #define LIB_DEBUG_PRINT_BUFFER_DECL(...) ((void)0) 77 #define LIB_DEBUG_PRINT_BUFFER_LOCAL(...) ((void)0) 66 78 #endif 67 79 -
src/libcfa/limits
rfea3faa rb826e6b 10 10 // Created On : Wed Apr 6 18:06:52 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 6 21:08:16 201613 // Update Count : 612 // Last Modified On : Fri Jul 7 09:33:57 2017 13 // Update Count : 7 14 14 // 15 15 16 #ifndef LIMITS_H 17 #define LIMITS_H 16 #pragma once 18 17 19 18 // Integral Constants … … 110 109 extern const long _Complex _1_SQRT_2; // 1 / sqrt(2) 111 110 112 #endif // LIMITS_H113 114 111 // Local Variables: // 115 112 // mode: c // -
src/libcfa/math
rfea3faa rb826e6b 10 10 // Created On : Mon Apr 18 23:37:04 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 24 17:40:39 2017 13 // Update Count : 60 14 // 15 16 #ifndef MATH_H 17 #define MATH_H 12 // Last Modified On : Fri Jul 7 09:34:15 2017 13 // Update Count : 61 14 // 15 16 #pragma once 18 17 19 18 extern "C" { … … 345 344 long double scalbln( long double, long int ); 346 345 347 #endif // MATH_H348 349 346 // Local Variables: // 350 347 // mode: c // -
src/libcfa/rational
rfea3faa rb826e6b 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Mon May 15 21:30:12201715 // Update Count : 9 014 // Last Modified On : Fri Jul 7 09:34:33 2017 15 // Update Count : 93 16 16 // 17 17 18 #ifndef RATIONAL_H 19 #define RATIONAL_H 18 #pragma once 20 19 21 20 #include "iostream" … … 47 46 // implementation 48 47 49 forall ( otype RationalImpl | arithmetic( RationalImpl ) )48 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 50 49 struct Rational { 51 50 RationalImpl numerator, denominator; // invariant: denominator > 0 … … 54 53 // constructors 55 54 56 forall ( otype RationalImpl | arithmetic( RationalImpl ) )55 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 57 56 void ?{}( Rational(RationalImpl) * r ); 58 57 59 forall ( otype RationalImpl | arithmetic( RationalImpl ) )58 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 60 59 void ?{}( Rational(RationalImpl) * r, RationalImpl n ); 61 60 62 forall ( otype RationalImpl | arithmetic( RationalImpl ) )61 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 63 62 void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ); 64 63 65 forall ( otype RationalImpl | arithmetic( RationalImpl ) )64 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 66 65 void ?{}( Rational(RationalImpl) * r, zero_t ); 67 66 68 forall ( otype RationalImpl | arithmetic( RationalImpl ) )67 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 69 68 void ?{}( Rational(RationalImpl) * r, one_t ); 70 69 71 // getter for numerator/denominator70 // numerator/denominator getter 72 71 73 forall ( otype RationalImpl | arithmetic( RationalImpl ) )72 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 74 73 RationalImpl numerator( Rational(RationalImpl) r ); 75 74 76 forall ( otype RationalImpl | arithmetic( RationalImpl ) )75 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 77 76 RationalImpl denominator( Rational(RationalImpl) r ); 78 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 77 78 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 79 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ); 80 80 81 // setter for numerator/denominator81 // numerator/denominator setter 82 82 83 forall ( otype RationalImpl | arithmetic( RationalImpl ) )83 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 84 84 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ); 85 85 86 forall ( otype RationalImpl | arithmetic( RationalImpl ) )86 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 87 87 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ); 88 88 89 89 // comparison 90 90 91 forall ( otype RationalImpl | arithmetic( RationalImpl ) )91 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 92 92 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 93 93 94 forall ( otype RationalImpl | arithmetic( RationalImpl ) )94 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 95 95 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 96 96 97 forall ( otype RationalImpl | arithmetic( RationalImpl ) )97 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 98 98 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 99 99 100 forall ( otype RationalImpl | arithmetic( RationalImpl ) )100 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 101 101 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 102 102 103 forall ( otype RationalImpl | arithmetic( RationalImpl ) )103 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 104 104 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 105 105 106 forall ( otype RationalImpl | arithmetic( RationalImpl ) )106 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 107 107 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 108 108 109 109 // arithmetic 110 110 111 forall ( otype RationalImpl | arithmetic( RationalImpl ) )111 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 112 112 Rational(RationalImpl) +?( Rational(RationalImpl) r ); 113 113 114 forall ( otype RationalImpl | arithmetic( RationalImpl ) )114 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 115 115 Rational(RationalImpl) -?( Rational(RationalImpl) r ); 116 116 117 forall ( otype RationalImpl | arithmetic( RationalImpl ) )117 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 118 118 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 119 119 120 forall ( otype RationalImpl | arithmetic( RationalImpl ) )120 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 121 121 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 122 122 123 forall ( otype RationalImpl | arithmetic( RationalImpl ) )123 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 124 124 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 125 125 126 forall ( otype RationalImpl | arithmetic( RationalImpl ) )126 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 127 127 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 128 128 129 129 // conversion 130 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )130 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 131 131 double widen( Rational(RationalImpl) r ); 132 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} )132 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} ) 133 133 Rational(RationalImpl) narrow( double f, RationalImpl md ); 134 134 135 135 // I/O 136 forall ( otype RationalImpl | arithmetic( RationalImpl ) )136 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 137 137 forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } ) 138 138 istype * ?|?( istype *, Rational(RationalImpl) * ); 139 139 140 forall ( otype RationalImpl | arithmetic( RationalImpl ) )140 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 141 141 forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } ) 142 142 ostype * ?|?( ostype *, Rational(RationalImpl ) ); 143 144 #endif // RATIONAL_H145 143 146 144 // Local Variables: // -
src/libcfa/rational.c
rfea3faa rb826e6b 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 21:29:23201713 // Update Count : 1 4912 // Last Modified On : Tue May 16 18:35:36 2017 13 // Update Count : 150 14 14 // 15 15 … … 22 22 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals. 23 23 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm 24 forall ( otype RationalImpl | arithmetic( RationalImpl ) )24 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 25 25 static RationalImpl gcd( RationalImpl a, RationalImpl b ) { 26 26 for ( ;; ) { // Euclid's algorithm … … 33 33 } // gcd 34 34 35 forall ( otype RationalImpl | arithmetic( RationalImpl ) )35 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 36 36 static RationalImpl simplify( RationalImpl * n, RationalImpl * d ) { 37 37 if ( *d == (RationalImpl){0} ) { … … 46 46 // constructors 47 47 48 forall ( otype RationalImpl | arithmetic( RationalImpl ) )48 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 49 49 void ?{}( Rational(RationalImpl) * r ) { 50 50 r{ (RationalImpl){0}, (RationalImpl){1} }; 51 51 } // rational 52 52 53 forall ( otype RationalImpl | arithmetic( RationalImpl ) )53 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 54 54 void ?{}( Rational(RationalImpl) * r, RationalImpl n ) { 55 55 r{ n, (RationalImpl){1} }; 56 56 } // rational 57 57 58 forall ( otype RationalImpl | arithmetic( RationalImpl ) )58 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 59 59 void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ) { 60 60 RationalImpl t = simplify( &n, &d ); // simplify … … 66 66 // getter for numerator/denominator 67 67 68 forall ( otype RationalImpl | arithmetic( RationalImpl ) )68 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 69 69 RationalImpl numerator( Rational(RationalImpl) r ) { 70 70 return r.numerator; 71 71 } // numerator 72 72 73 forall ( otype RationalImpl | arithmetic( RationalImpl ) )73 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 74 74 RationalImpl denominator( Rational(RationalImpl) r ) { 75 75 return r.denominator; 76 76 } // denominator 77 77 78 forall ( otype RationalImpl | arithmetic( RationalImpl ) )78 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 79 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) { 80 80 return *dest = src.[ numerator, denominator ]; … … 83 83 // setter for numerator/denominator 84 84 85 forall ( otype RationalImpl | arithmetic( RationalImpl ) )85 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 86 86 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) { 87 87 RationalImpl prev = r.numerator; … … 92 92 } // numerator 93 93 94 forall ( otype RationalImpl | arithmetic( RationalImpl ) )94 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 95 95 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) { 96 96 RationalImpl prev = r.denominator; … … 104 104 // comparison 105 105 106 forall ( otype RationalImpl | arithmetic( RationalImpl ) )106 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 107 107 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 108 108 return l.numerator * r.denominator == l.denominator * r.numerator; 109 109 } // ?==? 110 110 111 forall ( otype RationalImpl | arithmetic( RationalImpl ) )111 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 112 112 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 113 113 return ! ( l == r ); 114 114 } // ?!=? 115 115 116 forall ( otype RationalImpl | arithmetic( RationalImpl ) )116 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 117 117 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 118 118 return l.numerator * r.denominator < l.denominator * r.numerator; 119 119 } // ?<? 120 120 121 forall ( otype RationalImpl | arithmetic( RationalImpl ) )121 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 122 122 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 123 123 return l.numerator * r.denominator <= l.denominator * r.numerator; 124 124 } // ?<=? 125 125 126 forall ( otype RationalImpl | arithmetic( RationalImpl ) )126 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 127 127 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 128 128 return ! ( l <= r ); 129 129 } // ?>? 130 130 131 forall ( otype RationalImpl | arithmetic( RationalImpl ) )131 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 132 132 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 133 133 return ! ( l < r ); … … 137 137 // arithmetic 138 138 139 forall ( otype RationalImpl | arithmetic( RationalImpl ) )139 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 140 140 Rational(RationalImpl) +?( Rational(RationalImpl) r ) { 141 141 Rational(RationalImpl) t = { r.numerator, r.denominator }; … … 143 143 } // +? 144 144 145 forall ( otype RationalImpl | arithmetic( RationalImpl ) )145 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 146 146 Rational(RationalImpl) -?( Rational(RationalImpl) r ) { 147 147 Rational(RationalImpl) t = { -r.numerator, r.denominator }; … … 149 149 } // -? 150 150 151 forall ( otype RationalImpl | arithmetic( RationalImpl ) )151 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 152 152 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 153 153 if ( l.denominator == r.denominator ) { // special case … … 160 160 } // ?+? 161 161 162 forall ( otype RationalImpl | arithmetic( RationalImpl ) )162 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 163 163 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 164 164 if ( l.denominator == r.denominator ) { // special case … … 171 171 } // ?-? 172 172 173 forall ( otype RationalImpl | arithmetic( RationalImpl ) )173 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 174 174 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 175 175 Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator }; … … 177 177 } // ?*? 178 178 179 forall ( otype RationalImpl | arithmetic( RationalImpl ) )179 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 180 180 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 181 181 if ( r.numerator < (RationalImpl){0} ) { … … 190 190 // conversion 191 191 192 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )192 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 193 193 double widen( Rational(RationalImpl) r ) { 194 194 return convert( r.numerator ) / convert( r.denominator ); … … 196 196 197 197 // http://www.ics.uci.edu/~eppstein/numth/frap.c 198 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )198 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } ) 199 199 Rational(RationalImpl) narrow( double f, RationalImpl md ) { 200 200 if ( md <= (RationalImpl){1} ) { // maximum fractional digits too small? … … 227 227 // I/O 228 228 229 forall ( otype RationalImpl | arithmetic( RationalImpl ) )229 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 230 230 forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } ) 231 231 istype * ?|?( istype * is, Rational(RationalImpl) * r ) { … … 238 238 } // ?|? 239 239 240 forall ( otype RationalImpl | arithmetic( RationalImpl ) )240 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 241 241 forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } ) 242 242 ostype * ?|?( ostype * os, Rational(RationalImpl ) r ) { -
src/libcfa/stdlib
rfea3faa rb826e6b 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jun 2 15:51:03 2017 13 // Update Count : 218 14 // 15 16 #ifndef STDLIB_H 17 #define STDLIB_H 12 // Last Modified On : Fri Jul 7 09:34:49 2017 13 // Update Count : 219 14 // 15 16 #pragma once 18 17 19 18 //--------------------------------------- … … 232 231 void swap( T * t1, T * t2 ); 233 232 234 #endif // STDLIB_H235 236 233 // Local Variables: // 237 234 // mode: c //
Note:
See TracChangeset
for help on using the changeset viewer.