Changeset b826e6b for src/libcfa


Ignore:
Timestamp:
Jul 19, 2017, 11:49:33 AM (8 years ago)
Author:
Aaron Moss <a3moss@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/libcfa
Files:
8 added
32 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/Makefile.am

    rfea3faa rb826e6b  
    1010## Author           : Peter A. Buhr
    1111## Created On       : Sun May 31 08:54:01 2015
    12 ## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Sun May 14 21:04:21 2017
    14 ## Update Count     : 214
     12## Last Modified By : Andrew Beach
     13## Last Modified On : Fri Jun 14 17:00:00 2017
     14## Update Count     : 216
    1515###############################################################################
    1616
    1717# create object files in directory with source files
    1818AUTOMAKE_OPTIONS = subdir-objects
     19ARFLAGS = cr
    1920
    2021libdir = ${CFA_LIBDIR}
     
    5051
    5152libobjs = ${headers:=.o}
    52 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c}
     53libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
     54        exception.c typeobject.c
    5355
    5456# not all platforms support concurrency, add option do disable it
     
    6466        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
    6567
     68libcfa_a-exception.o : exception.c
     69        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
     70
     71libcfa_a-typeobject.o : typeobject.c
     72        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
     73
    6674concurrency/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
     77libcfa_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
     80libcfa_d_a-typeobject.o : typeobject.c
    6781        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
    6882
  • src/libcfa/Makefile.in

    rfea3faa rb826e6b  
    1 # Makefile.in generated by automake 1.11.3 from Makefile.am.
     1# Makefile.in generated by automake 1.15 from Makefile.am.
    22# @configure_input@
    33
    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
    76# This Makefile.in is free software; the Free Software Foundation
    87# gives unlimited permission to copy and/or distribute it,
     
    2120
    2221VPATH = @srcdir@
     22am__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}
     33am__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
     75am__make_dryrun = (target_option=n; $(am__make_running_with_option))
     76am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
    2377pkgdatadir = $(datadir)/@PACKAGE@
    2478pkgincludedir = $(includedir)/@PACKAGE@
     
    48102@BUILD_CONCURRENCY_TRUE@am__append_4 = concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c concurrency/invoke.c concurrency/preemption.c
    49103subdir = src/libcfa
    50 DIST_COMMON = $(am__nobase_cfa_include_HEADERS_DIST) \
    51         $(srcdir)/Makefile.am $(srcdir)/Makefile.in
    52104ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    53105am__aclocal_m4_deps = $(top_srcdir)/configure.ac
    54106am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
    55107        $(ACLOCAL_M4)
     108DIST_COMMON = $(srcdir)/Makefile.am \
     109        $(am__nobase_cfa_include_HEADERS_DIST) $(am__DIST_COMMON)
    56110mkinstalldirs = $(install_sh) -d
    57111CONFIG_HEADER = $(top_builddir)/config.h
     
    88142LIBRARIES = $(lib_LIBRARIES)
    89143AR = ar
    90 ARFLAGS = cru
    91144AM_V_AR = $(am__v_AR_@AM_V@)
    92145am__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 = @
     146am__v_AR_0 = @echo "  AR      " $@;
     147am__v_AR_1 =
    97148libcfa_d_a_AR = $(AR) $(ARFLAGS)
    98149libcfa_d_a_LIBADD =
     
    102153        containers/pair.c containers/result.c containers/vector.c \
    103154        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
    107159am__dirstamp = $(am__leading_dot)dirstamp
    108160@BUILD_CONCURRENCY_TRUE@am__objects_1 = concurrency/libcfa_d_a-coroutine.$(OBJEXT) \
     
    126178        libcfa_d_a-interpose.$(OBJEXT) \
    127179        libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \
     180        libcfa_d_a-exception.$(OBJEXT) libcfa_d_a-typeobject.$(OBJEXT) \
    128181        $(am__objects_3)
    129182am_libcfa_d_a_OBJECTS = $(am__objects_4)
     
    136189        containers/pair.c containers/result.c containers/vector.c \
    137190        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
    141195@BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
    142196@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-thread.$(OBJEXT) \
     
    158212        libcfa_a-interpose.$(OBJEXT) \
    159213        libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \
     214        libcfa_a-exception.$(OBJEXT) libcfa_a-typeobject.$(OBJEXT) \
    160215        $(am__objects_7)
    161216am_libcfa_a_OBJECTS = $(am__objects_8)
    162217libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     218AM_V_P = $(am__v_P_@AM_V@)
     219am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     220am__v_P_0 = false
     221am__v_P_1 = :
     222AM_V_GEN = $(am__v_GEN_@AM_V@)
     223am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
     224am__v_GEN_0 = @echo "  GEN     " $@;
     225am__v_GEN_1 =
     226AM_V_at = $(am__v_at_@AM_V@)
     227am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
     228am__v_at_0 = @
     229am__v_at_1 =
    163230DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
    164231depcomp = $(SHELL) $(top_srcdir)/automake/depcomp
     
    169236AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
    170237am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
    171 am__v_CPPAS_0 = @echo "  CPPAS " $@;
     238am__v_CPPAS_0 = @echo "  CPPAS   " $@;
     239am__v_CPPAS_1 =
    172240AM_V_lt = $(am__v_lt_@AM_V@)
    173241am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
    174242am__v_lt_0 = --silent
     243am__v_lt_1 =
    175244COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
    176245        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
    177246AM_V_CC = $(am__v_CC_@AM_V@)
    178247am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
    179 am__v_CC_0 = @echo "  CC    " $@;
     248am__v_CC_0 = @echo "  CC      " $@;
     249am__v_CC_1 =
    180250CCLD = $(CC)
    181251LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    182252AM_V_CCLD = $(am__v_CCLD_@AM_V@)
    183253am__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   " $@;
     254am__v_CCLD_0 = @echo "  CCLD    " $@;
     255am__v_CCLD_1 =
    188256SOURCES = $(libcfa_d_a_SOURCES) $(libcfa_a_SOURCES)
    189257DIST_SOURCES = $(am__libcfa_d_a_SOURCES_DIST) \
    190258        $(am__libcfa_a_SOURCES_DIST)
     259am__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
    191264am__nobase_cfa_include_HEADERS_DIST = assert fstream iostream iterator \
    192265        limits math rational stdlib containers/maybe containers/pair \
     
    195268        ${shell echo stdhdr/*} gmp concurrency/invoke.h
    196269HEADERS = $(nobase_cfa_include_HEADERS)
     270am__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.
     274am__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.
     282am__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)`
    197287ETAGS = etags
    198288CTAGS = ctags
     289am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/automake/depcomp
    199290DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
    200291ACLOCAL = @ACLOCAL@
     
    309400program_transform_name = @program_transform_name@
    310401psdir = @psdir@
     402runstatedir = @runstatedir@
    311403sbindir = @sbindir@
    312404sharedstatedir = @sharedstatedir@
     
    320412# create object files in directory with source files
    321413AUTOMAKE_OPTIONS = subdir-objects
     414ARFLAGS = cr
    322415lib_LIBRARIES = $(am__append_1) $(am__append_2)
    323416EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -I${abs_top_srcdir}/src/libcfa/libhdr -imacros libcfa-prelude.c @CFA_FLAGS@
     
    328421libobjs = ${headers:=.o}
    329422libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
    330         $(am__append_4)
     423        exception.c typeobject.c $(am__append_4)
    331424libcfa_a_SOURCES = ${libsrc}
    332425libcfa_a_CFLAGS = -nodebug -O2
     
    353446        $(am__cd) $(top_srcdir) && \
    354447          $(AUTOMAKE) --foreign src/libcfa/Makefile
    355 .PRECIOUS: Makefile
    356448Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    357449        @case '$?' in \
     
    373465install-libLIBRARIES: $(lib_LIBRARIES)
    374466        @$(NORMAL_INSTALL)
    375         test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
    376467        @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
    377468        list2=; for p in $$list; do \
     
    381472        done; \
    382473        test -z "$$list2" || { \
     474          echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
     475          $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
    383476          echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \
    384477          $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; }
     
    448541        concurrency/$(am__dirstamp) \
    449542        concurrency/$(DEPDIR)/$(am__dirstamp)
     543
    450544libcfa-d.a: $(libcfa_d_a_OBJECTS) $(libcfa_d_a_DEPENDENCIES) $(EXTRA_libcfa_d_a_DEPENDENCIES)
    451545        $(AM_V_at)-rm -f libcfa-d.a
     
    477571        concurrency/$(am__dirstamp) \
    478572        concurrency/$(DEPDIR)/$(am__dirstamp)
     573
    479574libcfa.a: $(libcfa_a_OBJECTS) $(libcfa_a_DEPENDENCIES) $(EXTRA_libcfa_a_DEPENDENCIES)
    480575        $(AM_V_at)-rm -f libcfa.a
     
    484579mostlyclean-compile:
    485580        -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)
    511584
    512585distclean-compile:
     
    514587
    515588@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@
    516590@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-fstream.Po@am__quote@
    517591@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-interpose.Po@am__quote@
     
    523597@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@
    524598@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@
    525600@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@
    526602@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-fstream.Po@am__quote@
    527603@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-interpose.Po@am__quote@
     
    533609@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@
    534610@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@
    535612@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@MACHINE_TYPE@.Po@am__quote@
    536613@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-alarm.Po@am__quote@
     
    850927@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`
    851928
     929libcfa_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
     936libcfa_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
    852943concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c
    853944@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
     
    11441235@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`
    11451236
     1237libcfa_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
     1244libcfa_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
    11461251concurrency/libcfa_a-alarm.o: concurrency/alarm.c
    11471252@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
     
    11801285install-nobase_cfa_includeHEADERS: $(nobase_cfa_include_HEADERS)
    11811286        @$(NORMAL_INSTALL)
    1182         test -z "$(cfa_includedir)" || $(MKDIR_P) "$(DESTDIR)$(cfa_includedir)"
    11831287        @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; \
    11841292        $(am__nobase_list) | while read dir files; do \
    11851293          xfiles=; for file in $$files; do \
     
    11881296          test -z "$$xfiles" || { \
    11891297            test "x$$dir" = x. || { \
    1190               echo "$(MKDIR_P) '$(DESTDIR)$(cfa_includedir)/$$dir'"; \
     1298              echo " $(MKDIR_P) '$(DESTDIR)$(cfa_includedir)/$$dir'"; \
    11911299              $(MKDIR_P) "$(DESTDIR)$(cfa_includedir)/$$dir"; }; \
    11921300            echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(cfa_includedir)/$$dir'"; \
     
    12001308        dir='$(DESTDIR)$(cfa_includedir)'; $(am__uninstall_files_from_dir)
    12011309
    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)
     1310ID: $(am__tagged_files)
     1311        $(am__define_uniq_tagged_files); mkid -fID $$unique
     1312tags: tags-am
     1313TAGS: tags
     1314
     1315tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
    12141316        set x; \
    12151317        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); \
    12221319        shift; \
    12231320        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
     
    12311328          fi; \
    12321329        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; }; }'`; \
     1330ctags: ctags-am
     1331
     1332CTAGS: ctags
     1333ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
     1334        $(am__define_uniq_tagged_files); \
    12421335        test -z "$(CTAGS_ARGS)$$unique" \
    12431336          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
     
    12481341          && $(am__cd) $(top_srcdir) \
    12491342          && gtags -i $(GTAGS_ARGS) "$$here"
     1343cscopelist: cscopelist-am
     1344
     1345cscopelist-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
    12501358
    12511359distclean-tags:
     
    13991507.MAKE: install-am install-strip
    14001508
    1401 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
    1402         clean-libLIBRARIES ctags 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 \
    14081516        install-nobase_cfa_includeHEADERS install-pdf install-pdf-am \
    14091517        install-ps install-ps-am install-strip installcheck \
     
    14111519        maintainer-clean-generic maintainer-clean-local mostlyclean \
    14121520        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 \
    14141522        uninstall-nobase_cfa_includeHEADERS
     1523
     1524.PRECIOUS: Makefile
    14151525
    14161526
     
    14281538        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
    14291539
     1540libcfa_a-exception.o : exception.c
     1541        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
     1542
     1543libcfa_a-typeobject.o : typeobject.c
     1544        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
     1545
    14301546concurrency/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
     1549libcfa_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
     1552libcfa_d_a-typeobject.o : typeobject.c
    14311553        ${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
    14321554
  • src/libcfa/concurrency/CtxSwitch-i386.S

    rfea3faa rb826e6b  
    9898        ret
    9999
    100 .text
    101         .align 2
    102 .globl  CtxGet
    103 CtxGet:
    104         movl %esp,SP_OFFSET(%eax)
    105         movl %ebp,FP_OFFSET(%eax)
    106 
    107         ret
    108 
    109100// Local Variables: //
    110101// compile-command: "make install" //
  • src/libcfa/concurrency/CtxSwitch-x86_64.S

    rfea3faa rb826e6b  
    1 //                               -*- Mode: Asm -*- 
     1//                               -*- Mode: Asm -*-
    22//
    33// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1818// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
    1919// option) any later version.
    20 // 
     20//
    2121// This library is distributed in the  hope that it will be useful, but WITHOUT
    2222// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
    2323// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
    2424// for more details.
    25 // 
     25//
    2626// You should  have received a  copy of the  GNU Lesser General  Public License
    2727// along  with this library.
    28 // 
     28//
    2929
    3030// This context switch routine depends on the fact that the stack of a new
     
    9393.globl  CtxInvokeStub
    9494CtxInvokeStub:
    95         movq %rbx, %rdi 
     95        movq %rbx, %rdi
    9696        jmp *%r12
    97 
    98 .text
    99         .align 2
    100 .globl  CtxGet
    101 CtxGet:
    102         movq %rsp,SP_OFFSET(%rdi)
    103         movq %rbp,FP_OFFSET(%rdi)
    104 
    105         ret
    10697
    10798// Local Variables: //
  • src/libcfa/concurrency/alarm.c

    rfea3faa rb826e6b  
    1616
    1717extern "C" {
     18#include <errno.h>
     19#include <stdio.h>
     20#include <string.h>
    1821#include <time.h>
     22#include <unistd.h>
    1923#include <sys/time.h>
    2024}
     25
     26#include "libhdr.h"
    2127
    2228#include "alarm.h"
     
    2531
    2632//=============================================================================================
     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
     43void ?{}( __cfa_time_t * this ) { this->val = 0; }
     44void ?{}( __cfa_time_t * this, zero_t zero ) { this->val = 0; }
     45
     46void ?{}( 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
     54void ?{}( __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//=============================================================================================
    2771// Clock logic
    2872//=============================================================================================
     
    3175        timespec curr;
    3276        clock_gettime( CLOCK_REALTIME, &curr );
    33         return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
     77        return (__cfa_time_t){ &curr };
    3478}
    3579
    3680void __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 };
    4282        setitimer( ITIMER_REAL, &val, NULL );
    4383}
     
    4787//=============================================================================================
    4888
    49 void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
     89void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) {
    5090        this->thrd = thrd;
    5191        this->alarm = alarm;
     
    5696}
    5797
    58 void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0 ) {
     98void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) {
    5999        this->proc = proc;
    60100        this->alarm = alarm;
     
    71111}
    72112
     113LIB_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
    73122static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    74         assert( !n->next );
     123        verify( !n->next );
    75124        if( p == this->tail ) {
    76125                this->tail = &n->next;
     
    80129        }
    81130        *p = n;
     131
     132        verify( validate( this ) );
    82133}
    83134
     
    89140
    90141        insert_at( this, n, it );
     142
     143        verify( validate( this ) );
    91144}
    92145
     
    100153                head->next = NULL;
    101154        }
     155        verify( validate( this ) );
    102156        return head;
    103157}
     
    105159static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    106160        verify( it );
    107         verify( (*it)->next == n );
    108 
    109         (*it)->next = n->next;
     161        verify( (*it) == n );
     162
     163        (*it) = n->next;
    110164        if( !n-> next ) {
    111165                this->tail = it;
    112166        }
    113167        n->next = NULL;
     168
     169        verify( validate( this ) );
    114170}
    115171
    116172static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    117173        alarm_node_t ** it = &this->head;
    118         while( (*it) && (*it)->next != n ) {
     174        while( (*it) && (*it) != n ) {
    119175                it = &(*it)->next;
    120176        }
    121177
     178        verify( validate( this ) );
     179
    122180        if( *it ) { remove_at( this, n, it ); }
     181
     182        verify( validate( this ) );
    123183}
    124184
    125185void register_self( alarm_node_t * this ) {
     186        alarm_list_t * alarms = &event_kernel->alarms;
     187
    126188        disable_interrupts();
    127         assert( !systemProcessor->pending_alarm );
    128         lock( &systemProcessor->alarm_lock );
     189        lock( &event_kernel->lock DEBUG_CTX2 );
    129190        {
    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() );
    133197                }
    134198        }
    135         unlock( &systemProcessor->alarm_lock );
     199        unlock( &event_kernel->lock );
    136200        this->set = true;
    137         enable_interrupts();
     201        enable_interrupts( DEBUG_CTX );
    138202}
    139203
    140204void unregister_self( alarm_node_t * this ) {
    141205        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 );
    146213        this->set = false;
    147214}
  • src/libcfa/concurrency/alarm.h

    rfea3faa rb826e6b  
    1919
    2020#include <stdbool.h>
     21#include <stdint.h>
    2122
    2223#include "assert"
    23 
    24 typedef unsigned long int __cfa_time_t;
    2524
    2625struct thread_desc;
    2726struct processor;
    2827
     28struct timespec;
     29struct itimerval;
     30
     31//=============================================================================================
     32// time type
     33//=============================================================================================
     34
     35struct __cfa_time_t {
     36        uint64_t val;
     37};
     38
     39// ctors
     40void ?{}( __cfa_time_t * this );
     41void ?{}( __cfa_time_t * this, zero_t zero );
     42void ?{}( __cfa_time_t * this, timespec * curr );
     43void ?{}( itimerval * this, __cfa_time_t * alarm );
     44
     45__cfa_time_t ?=?( __cfa_time_t * this, zero_t rhs );
     46
     47// logical ops
     48static inline bool ?==?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val == rhs.val; }
     49static inline bool ?!=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val != rhs.val; }
     50static inline bool ?>? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >  rhs.val; }
     51static inline bool ?<? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <  rhs.val; }
     52static inline bool ?>=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >= rhs.val; }
     53static inline bool ?<=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <= rhs.val; }
     54
     55static inline bool ?==?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val == rhs; }
     56static inline bool ?!=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val != rhs; }
     57static inline bool ?>? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >  rhs; }
     58static inline bool ?<? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <  rhs; }
     59static inline bool ?>=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >= rhs; }
     60static inline bool ?<=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <= rhs; }
     61
     62// addition/substract
     63static 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
     69static 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
     80extern __cfa_time_t zero_time;
     81
    2982//=============================================================================================
    3083// Clock logic
    3184//=============================================================================================
    32 
    33 #define TIMEGRAN 1_000_000_000L                         // nanosecond granularity, except for timeval
    3485
    3586__cfa_time_t __kernel_get_time();
     
    56107typedef alarm_node_t ** __alarm_it_t;
    57108
    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 );
     109void ?{}( alarm_node_t * this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time );
     110void ?{}( alarm_node_t * this, processor   * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time );
    60111void ^?{}( alarm_node_t * this );
    61112
  • src/libcfa/concurrency/coroutine

    rfea3faa rb826e6b  
    6363
    6464// Get current coroutine
    65 coroutine_desc * this_coroutine(void);
     65extern volatile thread_local coroutine_desc * this_coroutine;
    6666
    6767// Private wrappers for context switch and stack creation
     
    7171// Suspend implementation inlined for performance
    7272static inline void suspend() {
    73         coroutine_desc * src = this_coroutine();                // optimization
     73        coroutine_desc * src = this_coroutine;          // optimization
    7474
    7575        assertf( src->last != 0,
     
    8888forall(dtype T | is_coroutine(T))
    8989static inline void resume(T * cor) {
    90         coroutine_desc * src = this_coroutine();                // optimization
     90        coroutine_desc * src = this_coroutine;          // optimization
    9191        coroutine_desc * dst = get_coroutine(cor);
    9292
     
    112112
    113113static inline void resume(coroutine_desc * dst) {
    114         coroutine_desc * src = this_coroutine();                // optimization
     114        coroutine_desc * src = this_coroutine;          // optimization
    115115
    116116        // not resuming self ?
  • src/libcfa/concurrency/coroutine.c

    rfea3faa rb826e6b  
    3232#include "invoke.h"
    3333
    34 extern thread_local processor * this_processor;
     34extern volatile thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
     
    4444// Coroutine ctors and dtors
    4545void ?{}(coStack_t* this) {
    46         this->size              = 10240;        // size of stack
     46        this->size              = 65000;        // size of stack
    4747        this->storage   = NULL; // pointer to stack
    4848        this->limit             = NULL; // stack grows towards stack limit
     
    5050        this->context   = NULL; // address of cfa_context_t
    5151        this->top               = NULL; // address of top of storage
    52         this->userStack = false;       
     52        this->userStack = false;
    5353}
    5454
     
    106106
    107107        // set state of current coroutine to inactive
    108         src->state = Inactive;
     108        src->state = src->state == Halted ? Halted : Inactive;
    109109
    110110        // set new coroutine that task is executing
    111         this_processor->current_coroutine = dst;
     111        this_coroutine = dst;
    112112
    113113        // context switch to specified coroutine
     114        assert( src->stack.context );
    114115        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
    116117
    117118        // set state of new coroutine to active
     
    131132                this->size = libCeiling( storageSize, 16 );
    132133                // use malloc/memalign because "new" raises an exception for out-of-memory
    133                
     134
    134135                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    135136                LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
  • src/libcfa/concurrency/invoke.c

    rfea3faa rb826e6b  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_monitor_desc( struct monitor_desc * this );
     31extern void __leave_thread_monitor( struct thread_desc * this );
     32extern void disable_interrupts();
     33extern void enable_interrupts( DEBUG_CTX_PARAM );
    3234
    3335void CtxInvokeCoroutine(
    34       void (*main)(void *), 
    35       struct coroutine_desc *(*get_coroutine)(void *), 
     36      void (*main)(void *),
     37      struct coroutine_desc *(*get_coroutine)(void *),
    3638      void *this
    3739) {
     
    5658
    5759void 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 *),
    6163      void *this
    6264) {
     65      // First suspend, once the thread arrives here,
     66      // the function pointer to main can be invalidated without risk
    6367      __suspend_internal();
    6468
     69      // Fetch the thread handle from the user defined thread structure
    6570      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;
    6971
    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
    7176      main( this );
    7277
    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
    7584      //Final suspend, should never return
    76       __suspend_internal();
     85      __leave_thread_monitor( thrd );
    7786      abortf("Resumed dead thread");
    7887}
     
    8089
    8190void 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,
    8594      void (*invoke)(void *)
    8695) {
     
    108117        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    109118      ((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
    111120
    112121#elif defined( __x86_64__ )
     
    128137      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
    129138      ((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
    131140#else
    132141      #error Only __i386__ and __x86_64__ is supported for threads in cfa
  • src/libcfa/concurrency/invoke.h

    rfea3faa rb826e6b  
    3131      struct spinlock {
    3232            volatile int lock;
     33            #ifdef __CFA_DEBUG__
     34                  const char * prev_name;
     35                  void* prev_thrd;
     36            #endif
    3337      };
    3438
     
    8387            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    8488            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 monitor
    8689            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    8790      };
     
    99102#ifndef _INVOKE_PRIVATE_H_
    100103#define _INVOKE_PRIVATE_H_
    101      
     104
    102105      struct machine_context_t {
    103106            void *SP;
     
    109112      extern void CtxInvokeStub( void );
    110113      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
    112126
    113127#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    rfea3faa rb826e6b  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 bool try_lock( spinlock * );
    31 void lock( spinlock * );
    32 void unlock( spinlock * );
     30void lock      ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, spin if already acquired
     31void lock_yield( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, yield repeatedly if already acquired
     32bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, return false if already acquired
     33void unlock    ( spinlock * );                        // Unlock the spinlock
    3334
    34 struct signal_once {
    35         volatile bool cond;
    36         struct spinlock lock;
    37         struct __thread_queue_t blocked;
     35struct semaphore {
     36        spinlock lock;
     37        int count;
     38        __thread_queue_t waiting;
    3839};
    3940
    40 void ?{}(signal_once * this);
    41 void ^?{}(signal_once * this);
     41void  ?{}(semaphore * this, int count = 1);
     42void ^?{}(semaphore * this);
     43void P(semaphore * this);
     44void V(semaphore * this);
    4245
    43 void wait( signal_once * );
    44 void signal( signal_once * );
    4546
    4647//-----------------------------------------------------------------------------
    4748// Cluster
    4849struct 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
    5153};
    5254
     
    6870        unsigned short thrd_count;
    6971};
    70 static inline void ?{}(FinishAction * this) { 
     72static inline void ?{}(FinishAction * this) {
    7173        this->action_code = No_Action;
    7274        this->thrd = NULL;
     
    7577static inline void ^?{}(FinishAction * this) {}
    7678
     79// Processor
     80// Wrapper around kernel threads
    7781struct 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
    8686
    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
    8890
    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
    9193
    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
    9397
    94         bool pending_preemption;
     98#ifdef __CFA_DEBUG__
     99        char * last_enable;                             // Last function to enable preemption on this processor
     100#endif
    95101};
    96102
  • src/libcfa/concurrency/kernel.c

    rfea3faa rb826e6b  
    1515//
    1616
    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"
    2518
    2619//C Includes
     
    3528
    3629//CFA Includes
    37 #include "libhdr.h"
     30#include "kernel_private.h"
    3831#include "preemption.h"
     32#include "startup.h"
    3933
    4034//Private includes
     
    4236#include "invoke.h"
    4337
     38//Start and stop routine for the kernel, declared first to make sure they run first
     39void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     40void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     41
    4442//-----------------------------------------------------------------------------
    4543// 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;
     44KERNEL_STORAGE(cluster,           mainCluster);
     45KERNEL_STORAGE(processor,         mainProcessor);
     46KERNEL_STORAGE(processorCtx_t,    mainProcessorCtx);
     47KERNEL_STORAGE(thread_desc,       mainThread);
     48KERNEL_STORAGE(machine_context_t, mainThreadCtx);
     49
     50cluster *     mainCluster;
     51processor *   mainProcessor;
    5652thread_desc * mainThread;
    5753
     
    5955// Global state
    6056
    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 }
     57volatile thread_local coroutine_desc * this_coroutine;
     58volatile thread_local thread_desc * this_thread;
     59volatile thread_local processor * this_processor;
     60
     61volatile thread_local bool preemption_in_progress = 0;
     62volatile thread_local unsigned short disable_preempt_count = 1;
    7063
    7164//-----------------------------------------------------------------------------
    7265// Main thread construction
    7366struct current_stack_info_t {
    74         machine_context_t ctx; 
     67        machine_context_t ctx;
    7568        unsigned int size;              // size of stack
    7669        void *base;                             // base of stack
     
    8275
    8376void ?{}( current_stack_info_t * this ) {
    84         CtxGet( &this->ctx );
     77        CtxGet( this->ctx );
    8578        this->base = this->ctx.FP;
    8679        this->storage = this->ctx.SP;
     
    9184
    9285        this->limit = (void *)(((intptr_t)this->base) - this->size);
    93         this->context = &mainThread_context_storage;
     86        this->context = &storage_mainThreadCtx;
    9487        this->top = this->base;
    9588}
     
    10699
    107100void ?{}( coroutine_desc * this, current_stack_info_t * info) {
    108         (&this->stack){ info }; 
     101        (&this->stack){ info };
    109102        this->name = "Main Thread";
    110103        this->errno_ = 0;
     
    131124
    132125void ?{}(processor * this) {
    133         this{ systemCluster };
     126        this{ mainCluster };
    134127}
    135128
    136129void ?{}(processor * this, cluster * cltr) {
    137130        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;
    142133        this->preemption_alarm = NULL;
    143         this->preemption = default_preemption();
    144         this->disable_preempt_count = 1;                //Start with interrupts disabled
    145134        this->pending_preemption = false;
    146135
     
    150139void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    151140        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;
    157144        this->pending_preemption = false;
     145        this->kernel_thread = pthread_self();
    158146
    159147        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);
    161149        runner{ this };
    162150}
    163151
    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 
    172152void ^?{}(processor * this) {
    173         if( ! this->is_terminated ) {
     153        if( ! this->do_terminate ) {
    174154                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 );
    177158        }
    178159}
     
    180161void ?{}(cluster * this) {
    181162        ( &this->ready_queue ){};
    182         ( &this->lock ){};
     163        ( &this->ready_queue_lock ){};
     164
     165        this->preemption = default_preemption();
    183166}
    184167
    185168void ^?{}(cluster * this) {
    186        
     169
    187170}
    188171
     
    203186
    204187                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++ )
    206189                {
    207190                        readyThread = nextThread( this->cltr );
     
    209192                        if(readyThread)
    210193                        {
     194                                verify( disable_preempt_count > 0 );
     195
    211196                                runThread(this, readyThread);
     197
     198                                verify( disable_preempt_count > 0 );
    212199
    213200                                //Some actions need to be taken from the kernel
     
    225212        }
    226213
    227         signal( &this->terminated );
     214        V( &this->terminated );
     215
    228216        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
    229217}
    230218
    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
    233221void runThread(processor * this, thread_desc * dst) {
    234222        coroutine_desc * proc_cor = get_coroutine(this->runner);
    235223        coroutine_desc * thrd_cor = get_coroutine(dst);
    236        
     224
    237225        //Reset the terminating actions here
    238226        this->finish.action_code = No_Action;
    239227
    240228        //Update global state
    241         this->current_thread = dst;
     229        this_thread = dst;
    242230
    243231        // Context Switch to the thread
     
    246234}
    247235
    248 // Once a thread has finished running, some of 
     236// Once a thread has finished running, some of
    249237// its final actions must be executed from the kernel
    250238void finishRunning(processor * this) {
     
    256244        }
    257245        else if( this->finish.action_code == Release_Schedule ) {
    258                 unlock( this->finish.lock );           
     246                unlock( this->finish.lock );
    259247                ScheduleThread( this->finish.thrd );
    260248        }
     
    289277        processor * proc = (processor *) arg;
    290278        this_processor = proc;
     279        this_coroutine = NULL;
     280        this_thread = NULL;
     281        disable_preempt_count = 1;
    291282        // SKULLDUGGERY: We want to create a context for the processor coroutine
    292283        // 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.
    294285        current_stack_info_t info;
    295286        machine_context_t ctx;
     
    300291
    301292        //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;
    304295
    305296        //We now have a proper context from which to schedule threads
    306297        LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
    307298
    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
    311302        // appropriate stack.
    312303        proc_cor_storage.__cor.state = Active;
     
    315306
    316307        // 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);
    318309
    319310        return NULL;
     
    322313void start(processor * this) {
    323314        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    324        
     315
    325316        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    326317
    327         LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
     318        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
    328319}
    329320
     
    331322// Scheduler routines
    332323void 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 );
    334329
    335330        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 );
    340337}
    341338
    342339thread_desc * nextThread(cluster * this) {
    343         lock( &this->lock );
     340        verify( disable_preempt_count > 0 );
     341        lock( &this->ready_queue_lock DEBUG_CTX2 );
    344342        thread_desc * head = pop_head( &this->ready_queue );
    345         unlock( &this->lock );
     343        unlock( &this->ready_queue_lock );
     344        verify( disable_preempt_count > 0 );
    346345        return head;
    347346}
    348347
    349 void ScheduleInternal() {
    350         suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     348void 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
     356void BlockInternal( spinlock * lock ) {
     357        disable_interrupts();
    354358        this_processor->finish.action_code = Release;
    355359        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
     368void BlockInternal( thread_desc * thrd ) {
     369        disable_interrupts();
     370        assert( thrd->cor.state != Halted );
    360371        this_processor->finish.action_code = Schedule;
    361372        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
     381void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     382        disable_interrupts();
    366383        this_processor->finish.action_code = Release_Schedule;
    367384        this_processor->finish.lock = lock;
    368385        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
     394void BlockInternal(spinlock ** locks, unsigned short count) {
     395        disable_interrupts();
    373396        this_processor->finish.action_code = Release_Multi;
    374397        this_processor->finish.locks = locks;
    375398        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
     407void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     408        disable_interrupts();
    380409        this_processor->finish.action_code = Release_Multi_Schedule;
    381410        this_processor->finish.locks = locks;
     
    383412        this_processor->finish.thrds = thrds;
    384413        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
     422void 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
    385428        suspend();
    386429}
     
    392435// Kernel boot procedures
    393436void kernel_startup(void) {
    394         LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");   
     437        LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");
    395438
    396439        // Start by initializing the main thread
    397         // SKULLDUGGERY: the mainThread steals the process main thread 
    398         // which will then be scheduled by the systemProcessor normally
    399         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;
    400443        current_stack_info_t info;
    401444        mainThread{ &info };
     
    403446        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404447
     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
    405464        // Enable preemption
    406465        kernel_start_preemption();
    407466
    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
    421469        ScheduleThread(mainThread);
    422470
    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
    429472        // 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 );
    432475
    433476
     
    435478        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436479        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     480
     481        enable_interrupts( DEBUG_CTX );
    437482}
    438483
     
    440485        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
    441486
    442         // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     487        disable_interrupts();
     488
     489        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
    443490        // When its coroutine terminates, it return control to the mainThread
    444491        // which is currently here
    445         systemProcessor->proc.is_terminated = true;
     492        mainProcessor->do_terminate = true;
    446493        suspend();
    447494
    448495        // THE SYSTEM IS NOW COMPLETELY STOPPED
    449496
    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
    451501        // These were manually constructed so we need manually destroy them
    452         ^(systemProcessor->proc.runner){};
    453         ^(systemProcessor){};
     502        ^(mainProcessor->runner){};
     503        ^(mainProcessor){};
    454504
    455505        // Final step, destroy the main thread since it is no longer needed
     
    457507        ^(mainThread){};
    458508
    459         LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");   
     509        LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");
    460510}
    461511
     
    467517        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    468518        // the globalAbort flag is true.
    469         lock( &kernel_abort_lock );
     519        lock( &kernel_abort_lock DEBUG_CTX2 );
    470520
    471521        // first task to abort ?
     
    473523                kernel_abort_called = true;
    474524                unlock( &kernel_abort_lock );
    475         } 
     525        }
    476526        else {
    477527                unlock( &kernel_abort_lock );
    478                
     528
    479529                sigset_t mask;
    480530                sigemptyset( &mask );
     
    482532                sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    483533                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;
    488538}
    489539
     
    494544        __lib_debug_write( STDERR_FILENO, abort_text, len );
    495545
    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 );
    498548                __lib_debug_write( STDERR_FILENO, abort_text, len );
    499         } 
     549        }
    500550        else {
    501551                __lib_debug_write( STDERR_FILENO, ".\n", 2 );
     
    505555extern "C" {
    506556        void __lib_debug_acquire() {
    507                 lock(&kernel_debug_lock);
     557                lock( &kernel_debug_lock DEBUG_CTX2 );
    508558        }
    509559
    510560        void __lib_debug_release() {
    511                 unlock(&kernel_debug_lock);
     561                unlock( &kernel_debug_lock );
    512562        }
    513563}
     
    525575}
    526576
    527 bool try_lock( spinlock * this ) {
     577bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    528578        return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;
    529579}
    530580
    531 void lock( spinlock * this ) {
     581void lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    532582        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
     591void 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
    536602
    537603void unlock( spinlock * this ) {
     
    539605}
    540606
    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         }
     607void  ?{}( semaphore * this, int count = 1 ) {
     608        (&this->lock){};
     609        this->count = count;
     610        (&this->waiting){};
     611}
     612void ^?{}(semaphore * this) {}
     613
     614void 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
     629void 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
    555638        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 );
    569642}
    570643
     
    590663                }
    591664                head->next = NULL;
    592         }       
     665        }
    593666        return head;
    594667}
     
    609682                this->top = top->next;
    610683                top->next = NULL;
    611         }       
     684        }
    612685        return top;
    613686}
  • src/libcfa/concurrency/kernel_private.h

    rfea3faa rb826e6b  
    1818#define KERNEL_PRIVATE_H
    1919
     20#include "libhdr.h"
     21
    2022#include "kernel"
    2123#include "thread"
     
    2325#include "alarm.h"
    2426
    25 #include "libhdr.h"
    2627
    2728//-----------------------------------------------------------------------------
    2829// Scheduler
     30
     31extern "C" {
     32        void disable_interrupts();
     33        void enable_interrupts_noPoll();
     34        void enable_interrupts( DEBUG_CTX_PARAM );
     35}
     36
    2937void ScheduleThread( thread_desc * );
     38static inline void WakeThread( thread_desc * thrd ) {
     39        if( !thrd ) return;
     40
     41        disable_interrupts();
     42        ScheduleThread( thrd );
     43        enable_interrupts( DEBUG_CTX );
     44}
    3045thread_desc * nextThread(cluster * this);
    3146
    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
     48void BlockInternal(void);
     49void BlockInternal(spinlock * lock);
     50void BlockInternal(thread_desc * thrd);
     51void BlockInternal(spinlock * lock, thread_desc * thrd);
     52void BlockInternal(spinlock ** locks, unsigned short count);
     53void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     54void LeaveThread(spinlock * lock, thread_desc * thrd);
    3855
    3956//-----------------------------------------------------------------------------
     
    4966void spin(processor * this, unsigned int * spin_count);
    5067
    51 struct system_proc_t {
    52         processor proc;
    53 
     68struct event_kernel_t {
    5469        alarm_list_t alarms;
    55         spinlock alarm_lock;
    56 
    57         bool pending_alarm;
     70        spinlock lock;
    5871};
    5972
    60 extern cluster * systemCluster;
    61 extern system_proc_t * systemProcessor;
    62 extern thread_local processor * this_processor;
     73extern event_kernel_t * event_kernel;
    6374
    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 }
     75extern volatile thread_local processor * this_processor;
     76extern volatile thread_local coroutine_desc * this_coroutine;
     77extern volatile thread_local thread_desc * this_thread;
     78extern volatile thread_local bool preemption_in_progress;
     79extern volatile thread_local unsigned short disable_preempt_count;
    8280
    8381//-----------------------------------------------------------------------------
     
    9088extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
    9189
     90//-----------------------------------------------------------------------------
     91// Utils
     92#define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)]
     93
    9294#endif //KERNEL_PRIVATE_H
    9395
  • src/libcfa/concurrency/monitor

    rfea3faa rb826e6b  
    2626static inline void ?{}(monitor_desc * this) {
    2727        this->owner = NULL;
    28         this->stack_owner = NULL;
    2928        this->recursion = 0;
    3029}
  • src/libcfa/concurrency/monitor.c

    rfea3faa rb826e6b  
    1919#include <stdlib>
    2020
     21#include "libhdr.h"
    2122#include "kernel_private.h"
    22 #include "libhdr.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "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);
    5151
    5252                if( !this->owner ) {
     
    6262                        //Some one else has the monitor, wait in line for it
    6363                        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 ourselves
    68                         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;
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      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 );
    8282
    8383                //Leaving a recursion level, decrement the counter
     
    9696                unlock( &this->lock );
    9797
    98                 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
     98                // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    9999
    100100                //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 );
    102127        }
    103128}
     
    121146        enter( this->m, this->count );
    122147
    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;
    128153}
    129154
     
    131156        leave( this->m, this->count );
    132157
    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;
    135160}
    136161
     
    159184// Internal scheduling
    160185void wait( condition * this, uintptr_t user_info = 0 ) {
    161         LIB_DEBUG_PRINT_SAFE("Waiting\n");
     186        // LIB_DEBUG_PRINT_SAFE("Waiting\n");
    162187
    163188        brand_condition( this );
     
    170195        unsigned short count = this->monitor_count;
    171196        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 ScheduleInternal
    173 
    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 };
    177202
    178203        __condition_criterion_t criteria[count];
    179204        for(int i = 0; i < count; i++) {
    180205                (&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] );
    182207        }
    183208
     
    201226        }
    202227
    203         LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     228        // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    204229        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");
    208233
    209234        // Everything is ready to go to sleep
    210         ScheduleInternal( locks, count, threads, thread_count );
     235        BlockInternal( locks, count, threads, thread_count );
    211236
    212237
     
    222247bool signal( condition * this ) {
    223248        if( is_empty( this ) ) {
    224                 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     249                // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    225250                return false;
    226251        }
     
    231256
    232257        unsigned short count = this->monitor_count;
    233        
     258
    234259        //Some more checking in debug
    235260        LIB_DEBUG_DO(
    236                 thread_desc * this_thrd = this_thread();
     261                thread_desc * this_thrd = this_thread;
    237262                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    238263                        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 );
     
    248273        //Lock all the monitors
    249274        lock_all( this->monitors, NULL, count );
    250         LIB_DEBUG_PRINT_SAFE("Signalling");
     275        // LIB_DEBUG_PRINT_SAFE("Signalling");
    251276
    252277        //Pop the head of the waiting queue
     
    256281        for(int i = 0; i < count; i++) {
    257282                __condition_criterion_t * crit = &node->criteria[i];
    258                 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     283                // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    259284                assert( !crit->ready );
    260285                push( &crit->target->signal_stack, crit );
    261286        }
    262287
    263         LIB_DEBUG_PRINT_SAFE("\n");
     288        // LIB_DEBUG_PRINT_SAFE("\n");
    264289
    265290        //Release
     
    281306        unsigned short count = this->monitor_count;
    282307        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 ScheduleInternal
     308        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    284309
    285310        lock_all( this->monitors, locks, count );
    286311
    287312        //create creteria
    288         __condition_node_t waiter = { this_thread(), count, 0 };
     313        __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
    289314
    290315        __condition_criterion_t criteria[count];
    291316        for(int i = 0; i < count; i++) {
    292317                (&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] );
    294319                push( &criteria[i].target->signal_stack, &criteria[i] );
    295320        }
     
    309334
    310335        //Everything is ready to go to sleep
    311         ScheduleInternal( locks, count, &signallee, 1 );
     336        BlockInternal( locks, count, &signallee, 1 );
    312337
    313338
     
    325350
    326351uintptr_t front( condition * this ) {
    327         verifyf( !is_empty(this), 
     352        verifyf( !is_empty(this),
    328353                "Attempt to access user data on an empty condition.\n"
    329354                "Possible cause is not checking if the condition is empty before reading stored data."
     
    335360// Internal scheduling
    336361void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    337         // thread_desc * this = this_thread();
     362        // thread_desc * this = this_thread;
    338363
    339364        // unsigned short count = this->current_monitor_count;
    340365        // 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 ScheduleInternal
     366        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
    342367
    343368        // lock_all( this->current_monitors, locks, count );
     
    348373
    349374        // // // Everything is ready to go to sleep
    350         // // ScheduleInternal( locks, count, threads, thread_count );
     375        // // BlockInternal( locks, count, threads, thread_count );
    351376
    352377
     
    393418static inline void lock_all( spinlock ** locks, unsigned short count ) {
    394419        for( int i = 0; i < count; i++ ) {
    395                 lock( locks[i] );
     420                lock_yield( locks[i] DEBUG_CTX2 );
    396421        }
    397422}
     
    400425        for( int i = 0; i < count; i++ ) {
    401426                spinlock * l = &source[i]->lock;
    402                 lock( l );
     427                lock_yield( l DEBUG_CTX2 );
    403428                if(locks) locks[i] = l;
    404429        }
     
    443468        for(    int i = 0; i < count; i++ ) {
    444469
    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 );
    446471                if( &criteria[i] == target ) {
    447472                        criteria[i].ready = true;
    448                         LIB_DEBUG_PRINT_SAFE( "True\n" );
     473                        // LIB_DEBUG_PRINT_SAFE( "True\n" );
    449474                }
    450475
     
    452477        }
    453478
    454         LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     479        // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    455480        return ready2run ? node->waiting_thread : NULL;
    456481}
    457482
    458483static inline void brand_condition( condition * this ) {
    459         thread_desc * thrd = this_thread();
     484        thread_desc * thrd = this_thread;
    460485        if( !this->monitors ) {
    461                 LIB_DEBUG_PRINT_SAFE("Branding\n");
     486                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    462487                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    463488                this->monitor_count = thrd->current_monitor_count;
  • src/libcfa/concurrency/preemption.c

    rfea3faa rb826e6b  
    1515//
    1616
     17#include "libhdr.h"
    1718#include "preemption.h"
    1819
    1920extern "C" {
     21#include <errno.h>
     22#include <execinfo.h>
     23#define __USE_GNU
    2024#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
    2540__attribute__((weak)) unsigned int default_preemption() {
    2641        return __CFA_DEFAULT_PREEMPTION__;
    2742}
    2843
     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
    2949static void preempt( processor   * this );
    3050static void timeout( thread_desc * this );
    3151
     52// FwdDeclarations : Signal handlers
     53void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
     54void sigHandler_segv     ( __CFA_SIGPARMS__ );
     55void sigHandler_abort    ( __CFA_SIGPARMS__ );
     56
     57// FwdDeclarations : sigaction wrapper
     58static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
     59
     60// FwdDeclarations : alarm thread main
     61void * 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
     70KERNEL_STORAGE(event_kernel_t, event_kernel);         // private storage for event kernel
     71event_kernel_t * event_kernel;                        // kernel public handle to even kernel
     72static pthread_t alarm_thread;                        // pthread handle to alarm thread
     73
     74void ?{}(event_kernel_t * this) {
     75        (&this->alarms){};
     76        (&this->lock){};
     77}
     78
    3279//=============================================================================================
    3380// Kernel Preemption logic
    3481//=============================================================================================
    3582
    36 void kernel_start_preemption() {
    37 
    38 }
    39 
     83// Get next expired node
     84static 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
    4091void 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
    45100                if( node->kernel_alarm ) {
    46101                        preempt( node->proc );
     
    50105                }
    51106
    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
    55112                }
    56113                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
    66123void update_preemption( processor * this, __cfa_time_t duration ) {
    67         //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
    68124        alarm_node_t * alarm = this->preemption_alarm;
    69125
     
    89145}
    90146
     147//=============================================================================================
     148// Kernel Signal Tools
     149//=============================================================================================
     150
     151LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
     152
     153extern "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
     188static 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
     199static 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
     210static void preempt( processor * this ) {
     211        pthread_kill( this->kernel_thread, SIGUSR1 );
     212}
     213
     214// reserved for future use
     215static 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
     223static 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
     235void 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
     257void 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
    91279void ?{}( preemption_scope * this, processor * proc ) {
    92         (&this->alarm){ proc };
     280        (&this->alarm){ proc, zero_time, zero_time };
    93281        this->proc = proc;
    94282        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) );
    96285}
    97286
    98287void ^?{}( 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
     299void 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
     316void * 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
     356EXIT:
     357        LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n");
     358        return NULL;
     359}
     360
     361// Sigaction wrapper : register an signal handler
     362static 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
     378static 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
     398LIB_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  
    5454}
    5555
    56 thread_desc * this_thread(void);
     56extern volatile thread_local thread_desc * this_thread;
    5757
    5858forall( dtype T | is_thread(T) )
  • src/libcfa/concurrency/thread.c

    rfea3faa rb826e6b  
    2828}
    2929
    30 extern thread_local processor * this_processor;
     30extern volatile thread_local processor * this_processor;
    3131
    3232//-----------------------------------------------------------------------------
     
    7171        coroutine_desc* thrd_c = get_coroutine(this);
    7272        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;
    7574
    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);
    7776
     77        disable_interrupts();
    7878        create_stack(&thrd_c->stack, thrd_c->stack.size);
     79        this_coroutine = thrd_c;
    7980        CtxStart(this, CtxInvokeThread);
     81        assert( thrd_c->last->stack.context );
    8082        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8183
    8284        ScheduleThread(thrd_h);
     85        enable_interrupts( DEBUG_CTX );
    8386}
    8487
    8588void yield( void ) {
    86         ScheduleInternal( this_processor->current_thread );
     89        BlockInternal( (thread_desc *)this_thread );
    8790}
    8891
     
    9598void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9699        // set state of current coroutine to inactive
    97         src->state = Inactive;
     100        src->state = src->state == Halted ? Halted : Inactive;
    98101        dst->state = Active;
    99102
     
    103106        // set new coroutine that the processor is executing
    104107        // and context switch to it
    105         this_processor->current_coroutine = dst;
     108        this_coroutine = dst;
     109        assert( src->stack.context );
    106110        CtxSwitch( src->stack.context, dst->stack.context );
    107         this_processor->current_coroutine = src;
     111        this_coroutine = src;
    108112
    109113        // set state of new coroutine to active
    110         dst->state = Inactive;
     114        dst->state = dst->state == Halted ? Halted : Inactive;
    111115        src->state = Active;
    112116}
  • src/libcfa/fstream

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:11:09 2017
    13 // Update Count     : 104
     12// Last Modified On : Fri Jul  7 08:32:38 2017
     13// Update Count     : 117
    1414//
    1515
    16 #ifndef __FSTREAM_H__
    17 #define __FSTREAM_H__
     16#pragma once
    1817
    1918#include "iostream"
    2019
    21 enum { separateSize = 16 };
     20enum { sepSize = 16 };
    2221struct ofstream {
    2322        void * file;
    2423        _Bool sepDefault;
    2524        _Bool sepOnOff;
     25        _Bool sawNL;
    2626        const char * sepCur;
    27         char separator[separateSize];
    28         char tupleSeparator[separateSize];
     27        char separator[sepSize];
     28        char tupleSeparator[sepSize];
    2929}; // ofstream
    3030
     
    3535const char * sepGetCur( ofstream * );
    3636void sepSetCur( ofstream *, const char * );
     37_Bool getNL( ofstream * );
     38void setNL( ofstream *, _Bool );
    3739
    3840// public
     
    7375extern ifstream * sin;
    7476
    75 #endif // __FSTREAM_H__
    76 
    7777// Local Variables: //
    7878// mode: c //
  • src/libcfa/fstream.c

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:11:11 2017
    13 // Update Count     : 234
     12// Last Modified On : Thu Jul  6 18:38:25 2017
     13// Update Count     : 251
    1414//
    1515
     
    3939
    4040// private
    41 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
     41_Bool sepPrt( ofstream * os ) { setNL( os, false ); return os->sepOnOff; }
    4242void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    4343void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
    4444const char * sepGetCur( ofstream * os ) { return os->sepCur; }
    4545void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; }
     46_Bool getNL( ofstream * os ) { return os->sawNL; }
     47void setNL( ofstream * os, _Bool state ) { os->sawNL = state; }
    4648
    4749// public
    48 void sepOn( ofstream * os ) { os->sepOnOff = 1; }
    49 void sepOff( ofstream * os ) { os->sepOnOff = 0; }
     50void sepOn( ofstream * os ) { os->sepOnOff = ! getNL( os ); }
     51void sepOff( ofstream * os ) { os->sepOnOff = false; }
    5052
    5153_Bool sepDisable( ofstream *os ) {
     
    6668void sepSet( ofstream * os, const char * s ) {
    6769        assert( s );
    68         strncpy( os->separator, s, separateSize - 1 );
    69         os->separator[separateSize - 1] = '\0';
     70        strncpy( os->separator, s, sepSize - 1 );
     71        os->separator[sepSize - 1] = '\0';
    7072} // sepSet
    7173
     
    7375void sepSetTuple( ofstream * os, const char * s ) {
    7476        assert( s );
    75         strncpy( os->tupleSeparator, s, separateSize - 1 );
    76         os->tupleSeparator[separateSize - 1] = '\0';
     77        strncpy( os->tupleSeparator, s, sepSize - 1 );
     78        os->tupleSeparator[sepSize - 1] = '\0';
    7779} // sepSet
    7880
     
    9294                exit( EXIT_FAILURE );
    9395        } // if
    94         ?{}( os, file, 1, 0, " ", ", " );
     96        ?{}( os, file, true, false, " ", ", " );
    9597} // open
    9698
     
    132134} // fmt
    133135
    134 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, " ", ", " };
     136static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " };
    135137ofstream *sout = &soutFile;
    136 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, " ", ", " };
     138static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " };
    137139ofstream *serr = &serrFile;
    138140
     
    150152
    151153void open( ifstream * is, const char * name, const char * mode ) {
    152         FILE *t = fopen( name, mode );
    153         if ( t == 0 ) {                                                                         // do not change unless successful
     154        FILE *file = fopen( name, mode );
     155        if ( file == 0 ) {                                                                      // do not change unless successful
    154156                fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
    155157                perror( 0 );
    156158                exit( EXIT_FAILURE );
    157159        } // if
    158         is->file = t;
     160        is->file = file;
    159161} // open
    160162
  • src/libcfa/gmp

    rfea3faa rb826e6b  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 27 09:55:51 2017
    13 // Update Count     : 14
     12// Last Modified On : Fri Jul  7 09:33:20 2017
     13// Update Count     : 15
    1414//
    1515
    1616// https://gmplib.org/gmp-man-6.1.1.pdf
     17
     18#pragma once
    1719
    1820#include <gmp.h>                                                                                // GNU multi-precise integers
  • src/libcfa/iostream

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 18:08:44 2017
    13 // Update Count     : 105
     12// Last Modified On : Fri Jul  7 08:35:59 2017
     13// Update Count     : 118
    1414//
    1515
    16 #ifndef __IOSTREAM_H__
    17 #define __IOSTREAM_H__
     16#pragma once
    1817
    1918#include "iterator"
     
    2625        const char * sepGetCur( ostype * );                                     // get current separator string
    2726        void sepSetCur( ostype *, const char * );                       // set current separator string
     27        _Bool getNL( ostype * );                                                        // check newline
     28        void setNL( ostype *, _Bool );                                          // saw newline
    2829        // public
    2930        void sepOn( ostype * );                                                         // turn separator state on
     
    4344        ostype * write( ostype *, const char *, unsigned long int );
    4445        int fmt( ostype *, const char fmt[], ... );
    45 };
     46}; // ostream
    4647
    4748trait writeable( otype T ) {
    4849        forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T );
    49 };
     50}; // writeable
    5051
    5152// implement writable for intrinsic types
     
    8182forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, ostype * (*)( ostype * ) );
    8283forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * );
     84forall( dtype ostype | ostream( ostype ) ) ostype * sep( ostype * );
     85forall( dtype ostype | ostream( ostype ) ) ostype * sepTuple( ostype * );
    8386forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * );
    8487forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * );
     
    103106        istype * ungetc( istype *, char );
    104107        int fmt( istype *, const char fmt[], ... );
    105 };
     108}; // istream
    106109
    107110trait readable( otype T ) {
    108111        forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T );
    109 };
     112}; // readable
    110113
    111114forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, char * );
     
    136139forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC );
    137140
    138 #endif // __IOSTREAM_H
    139 
    140141// Local Variables: //
    141142// mode: c //
  • src/libcfa/iostream.c

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May  8 18:24:23 2017
    13 // Update Count     : 369
     12// Last Modified On : Sun Jul 16 21:12:03 2017
     13// Update Count     : 398
    1414//
    1515
     
    1818extern "C" {
    1919#include <stdio.h>
     20#include <stdbool.h>                                                                    // true/false
    2021#include <string.h>                                                                             // strlen
    2122#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
     
    2425
    2526forall( dtype ostype | ostream( ostype ) )
    26 ostype * ?|?( ostype * os, char c ) {
    27         fmt( os, "%c", c );
     27ostype * ?|?( ostype * os, char ch ) {
     28        fmt( os, "%c", ch );
     29        if ( ch == '\n' ) setNL( os, true );
    2830        sepOff( os );
    2931        return os;
     
    123125forall( dtype ostype | ostream( ostype ) )
    124126ostype * ?|?( 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 ) );
    130129        return os;
    131130} // ?|?
     
    133132forall( dtype ostype | ostream( ostype ) )
    134133ostype * ?|?( 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 ) );
    140136        return os;
    141137} // ?|?
     
    143139forall( dtype ostype | ostream( ostype ) )
    144140ostype * ?|?( 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 ) );
    150143        return os;
    151144} // ?|?
     
    180173
    181174        // 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 unsigned
     175        size_t len = strlen( cp );
     176        ch = cp[len - 1];                                                                       // must make unsigned
    184177        if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    185178                sepOn( os );
     
    187180                sepOff( os );
    188181        } // if
     182        if ( ch == '\n' ) setNL( os, true );                            // check *AFTER* sepPrt call above as it resets NL flag
    189183        return write( os, cp, len );
    190184} // ?|?
     
    201195forall( dtype ostype, otype T, ttype Params | ostream( ostype ) | writeable( T ) | { ostype * ?|?( ostype *, Params ); } )
    202196ostype * ?|?( ostype * os, T arg, Params rest ) {
     197        os | arg;                                                                                       // print first argument
    203198        sepSetCur( os, sepGetTuple( os ) );                                     // switch to tuple separator
    204         os | arg;                                                                                       // print first argument
    205199        os | rest;                                                                                      // print remaining arguments
    206200        sepSetCur( os, sepGet( os ) );                                          // switch to regular separator
     
    216210
    217211forall( dtype ostype | ostream( ostype ) )
     212ostype * sep( ostype * os ) {
     213        os | sepGet( os );
     214        return os;
     215} // sep
     216
     217forall( dtype ostype | ostream( ostype ) )
     218ostype * sepTuple( ostype * os ) {
     219        os | sepGetTuple( os );
     220        return os;
     221} // sepTuple
     222
     223forall( dtype ostype | ostream( ostype ) )
    218224ostype * endl( ostype * os ) {
    219225        os | '\n';
     226        setNL( os, true );
    220227        flush( os );
    221228        sepOff( os );                                                                           // prepare for next line
  • src/libcfa/iterator

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 18:06:05 2016
    13 // Update Count     : 9
     12// Last Modified On : Fri Jul  7 08:37:25 2017
     13// Update Count     : 10
    1414//
    1515
    16 #ifndef ITERATOR_H
    17 #define ITERATOR_H
     16#pragma once
    1817
    1918// An iterator can be used to traverse a data structure.
     
    3938
    4039forall( 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 ) );
     40void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) );
    4241
    4342forall( 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
     43void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) );
    4744
    4845// Local Variables: //
  • src/libcfa/iterator.c

    rfea3faa rb826e6b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 18:08:11 2016
    13 // Update Count     : 27
     12// Last Modified On : Fri Jul  7 08:38:23 2017
     13// Update Count     : 28
    1414//
    1515
     
    1717
    1818forall( 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 ) ) {
     19void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {
    2020        for ( iterator_type i = begin; i != end; ++i ) {
    2121                func( *i );
    22         }
    23 }
     22        } // for
     23} // for_each
    2424
    2525forall( 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 ) ) {
     26void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {
    2727        for ( iterator_type i = end; i != begin; ) {
    2828                --i;
    2929                func( *i );
    30         }
    31 }
     30        } // for
     31} // for_each_reverse
    3232
    3333// Local Variables: //
  • src/libcfa/libhdr/libalign.h

    rfea3faa rb826e6b  
    1 //                              -*- Mode: C++ -*- 
     1//                              -*- Mode: C++ -*-
    22//
    33// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1818// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
    1919// option) any later version.
    20 // 
     20//
    2121// This library is distributed in the  hope that it will be useful, but WITHOUT
    2222// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
    2323// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
    2424// for more details.
    25 // 
     25//
    2626// You should  have received a  copy of the  GNU Lesser General  Public License
    2727// along  with this library.
    28 // 
     28//
    2929
    3030
     
    3333
    3434#include "assert"
     35#include <stdbool.h>
    3536
    36 // Minimum size used to align memory boundaries for memory allocations. 
     37// Minimum size used to align memory boundaries for memory allocations.
    3738#define libAlign() (sizeof(double))
    3839
  • src/libcfa/libhdr/libdebug.h

    rfea3faa rb826e6b  
    1818
    1919#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
    2226#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
    2533#endif
    2634
     
    5159
    5260#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 );
    5969#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)
    6678#endif
    6779
  • src/libcfa/limits

    rfea3faa rb826e6b  
    1010// Created On       : Wed Apr  6 18:06:52 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 21:08:16 2016
    13 // Update Count     : 6
     12// Last Modified On : Fri Jul  7 09:33:57 2017
     13// Update Count     : 7
    1414//
    1515
    16 #ifndef LIMITS_H
    17 #define LIMITS_H
     16#pragma once
    1817
    1918// Integral Constants
     
    110109extern const long _Complex _1_SQRT_2;                                   // 1 / sqrt(2)
    111110
    112 #endif // LIMITS_H
    113 
    114111// Local Variables: //
    115112// mode: c //
  • src/libcfa/math

    rfea3faa rb826e6b  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// 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
    1817
    1918extern "C" {
     
    345344long double scalbln( long double, long int );
    346345
    347 #endif // MATH_H
    348 
    349346// Local Variables: //
    350347// mode: c //
  • src/libcfa/rational

    rfea3faa rb826e6b  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Mon May 15 21:30:12 2017
    15 // Update Count     : 90
     14// Last Modified On : Fri Jul  7 09:34:33 2017
     15// Update Count     : 93
    1616//
    1717
    18 #ifndef RATIONAL_H
    19 #define RATIONAL_H
     18#pragma once
    2019
    2120#include "iostream"
     
    4746// implementation
    4847
    49 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     48forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5049struct Rational {
    5150        RationalImpl numerator, denominator;                            // invariant: denominator > 0
     
    5453// constructors
    5554
    56 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     55forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5756void ?{}( Rational(RationalImpl) * r );
    5857
    59 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     58forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6059void ?{}( Rational(RationalImpl) * r, RationalImpl n );
    6160
    62 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     61forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6362void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d );
    6463
    65 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     64forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6665void ?{}( Rational(RationalImpl) * r, zero_t );
    6766
    68 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     67forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6968void ?{}( Rational(RationalImpl) * r, one_t );
    7069
    71 // getter for numerator/denominator
     70// numerator/denominator getter
    7271
    73 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     72forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7473RationalImpl numerator( Rational(RationalImpl) r );
    7574
    76 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     75forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7776RationalImpl denominator( Rational(RationalImpl) r );
    78 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     77
     78forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7979[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
    8080
    81 // setter for numerator/denominator
     81// numerator/denominator setter
    8282
    83 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     83forall( otype RationalImpl | arithmetic( RationalImpl ) )
    8484RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n );
    8585
    86 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     86forall( otype RationalImpl | arithmetic( RationalImpl ) )
    8787RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d );
    8888
    8989// comparison
    9090
    91 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     91forall( otype RationalImpl | arithmetic( RationalImpl ) )
    9292int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9393
    94 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     94forall( otype RationalImpl | arithmetic( RationalImpl ) )
    9595int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9696
    97 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     97forall( otype RationalImpl | arithmetic( RationalImpl ) )
    9898int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9999
    100 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     100forall( otype RationalImpl | arithmetic( RationalImpl ) )
    101101int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    102102
    103 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     103forall( otype RationalImpl | arithmetic( RationalImpl ) )
    104104int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    105105
    106 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     106forall( otype RationalImpl | arithmetic( RationalImpl ) )
    107107int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    108108
    109109// arithmetic
    110110
    111 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     111forall( otype RationalImpl | arithmetic( RationalImpl ) )
    112112Rational(RationalImpl) +?( Rational(RationalImpl) r );
    113113
    114 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     114forall( otype RationalImpl | arithmetic( RationalImpl ) )
    115115Rational(RationalImpl) -?( Rational(RationalImpl) r );
    116116
    117 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     117forall( otype RationalImpl | arithmetic( RationalImpl ) )
    118118Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    119119
    120 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     120forall( otype RationalImpl | arithmetic( RationalImpl ) )
    121121Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    122122
    123 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     123forall( otype RationalImpl | arithmetic( RationalImpl ) )
    124124Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    125125
    126 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     126forall( otype RationalImpl | arithmetic( RationalImpl ) )
    127127Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    128128
    129129// conversion
    130 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     130forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
    131131double widen( Rational(RationalImpl) r );
    132 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
     132forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
    133133Rational(RationalImpl) narrow( double f, RationalImpl md );
    134134
    135135// I/O
    136 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     136forall( otype RationalImpl | arithmetic( RationalImpl ) )
    137137forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } )
    138138istype * ?|?( istype *, Rational(RationalImpl) * );
    139139
    140 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     140forall( otype RationalImpl | arithmetic( RationalImpl ) )
    141141forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } )
    142142ostype * ?|?( ostype *, Rational(RationalImpl ) );
    143 
    144 #endif // RATIONAL_H
    145143
    146144// Local Variables: //
  • src/libcfa/rational.c

    rfea3faa rb826e6b  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 21:29:23 2017
    13 // Update Count     : 149
     12// Last Modified On : Tue May 16 18:35:36 2017
     13// Update Count     : 150
    1414//
    1515
     
    2222// Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
    2323// alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    24 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     24forall( otype RationalImpl | arithmetic( RationalImpl ) )
    2525static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
    2626        for ( ;; ) {                                                                            // Euclid's algorithm
     
    3333} // gcd
    3434
    35 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     35forall( otype RationalImpl | arithmetic( RationalImpl ) )
    3636static RationalImpl simplify( RationalImpl * n, RationalImpl * d ) {
    3737        if ( *d == (RationalImpl){0} ) {
     
    4646// constructors
    4747
    48 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     48forall( otype RationalImpl | arithmetic( RationalImpl ) )
    4949void ?{}( Rational(RationalImpl) * r ) {
    5050        r{ (RationalImpl){0}, (RationalImpl){1} };
    5151} // rational
    5252
    53 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     53forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5454void ?{}( Rational(RationalImpl) * r, RationalImpl n ) {
    5555        r{ n, (RationalImpl){1} };
    5656} // rational
    5757
    58 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     58forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5959void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ) {
    6060        RationalImpl t = simplify( &n, &d );                            // simplify
     
    6666// getter for numerator/denominator
    6767
    68 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     68forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6969RationalImpl numerator( Rational(RationalImpl) r ) {
    7070        return r.numerator;
    7171} // numerator
    7272
    73 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     73forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7474RationalImpl denominator( Rational(RationalImpl) r ) {
    7575        return r.denominator;
    7676} // denominator
    7777
    78 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     78forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7979[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
    8080        return *dest = src.[ numerator, denominator ];
     
    8383// setter for numerator/denominator
    8484
    85 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     85forall( otype RationalImpl | arithmetic( RationalImpl ) )
    8686RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
    8787        RationalImpl prev = r.numerator;
     
    9292} // numerator
    9393
    94 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     94forall( otype RationalImpl | arithmetic( RationalImpl ) )
    9595RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
    9696        RationalImpl prev = r.denominator;
     
    104104// comparison
    105105
    106 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     106forall( otype RationalImpl | arithmetic( RationalImpl ) )
    107107int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    108108        return l.numerator * r.denominator == l.denominator * r.numerator;
    109109} // ?==?
    110110
    111 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     111forall( otype RationalImpl | arithmetic( RationalImpl ) )
    112112int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    113113        return ! ( l == r );
    114114} // ?!=?
    115115
    116 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     116forall( otype RationalImpl | arithmetic( RationalImpl ) )
    117117int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    118118        return l.numerator * r.denominator < l.denominator * r.numerator;
    119119} // ?<?
    120120
    121 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     121forall( otype RationalImpl | arithmetic( RationalImpl ) )
    122122int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    123123        return l.numerator * r.denominator <= l.denominator * r.numerator;
    124124} // ?<=?
    125125
    126 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     126forall( otype RationalImpl | arithmetic( RationalImpl ) )
    127127int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    128128        return ! ( l <= r );
    129129} // ?>?
    130130
    131 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     131forall( otype RationalImpl | arithmetic( RationalImpl ) )
    132132int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    133133        return ! ( l < r );
     
    137137// arithmetic
    138138
    139 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     139forall( otype RationalImpl | arithmetic( RationalImpl ) )
    140140Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    141141        Rational(RationalImpl) t = { r.numerator, r.denominator };
     
    143143} // +?
    144144
    145 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     145forall( otype RationalImpl | arithmetic( RationalImpl ) )
    146146Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    147147        Rational(RationalImpl) t = { -r.numerator, r.denominator };
     
    149149} // -?
    150150
    151 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     151forall( otype RationalImpl | arithmetic( RationalImpl ) )
    152152Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    153153        if ( l.denominator == r.denominator ) {                         // special case
     
    160160} // ?+?
    161161
    162 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     162forall( otype RationalImpl | arithmetic( RationalImpl ) )
    163163Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    164164        if ( l.denominator == r.denominator ) {                         // special case
     
    171171} // ?-?
    172172
    173 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     173forall( otype RationalImpl | arithmetic( RationalImpl ) )
    174174Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    175175        Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
     
    177177} // ?*?
    178178
    179 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     179forall( otype RationalImpl | arithmetic( RationalImpl ) )
    180180Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    181181        if ( r.numerator < (RationalImpl){0} ) {
     
    190190// conversion
    191191
    192 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     192forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
    193193double widen( Rational(RationalImpl) r ) {
    194194        return convert( r.numerator ) / convert( r.denominator );
     
    196196
    197197// http://www.ics.uci.edu/~eppstein/numth/frap.c
    198 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
     198forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
    199199Rational(RationalImpl) narrow( double f, RationalImpl md ) {
    200200        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
     
    227227// I/O
    228228
    229 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     229forall( otype RationalImpl | arithmetic( RationalImpl ) )
    230230forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } )
    231231istype * ?|?( istype * is, Rational(RationalImpl) * r ) {
     
    238238} // ?|?
    239239
    240 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     240forall( otype RationalImpl | arithmetic( RationalImpl ) )
    241241forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } )
    242242ostype * ?|?( ostype * os, Rational(RationalImpl ) r ) {
  • src/libcfa/stdlib

    rfea3faa rb826e6b  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// 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
    1817
    1918//---------------------------------------
     
    232231void swap( T * t1, T * t2 );
    233232
    234 #endif // STDLIB_H
    235 
    236233// Local Variables: //
    237234// mode: c //
Note: See TracChangeset for help on using the changeset viewer.