Re: [PATCH] user: Document patch review process
On 1/10/19 3:50 pm, Sebastian Huber wrote: > On 01/10/2019 01:40, Chris Johns wrote: >> On 30/9/19 10:45 pm, Sebastian Huber wrote: >>> --- >>> images/user/patch-review.png | Bin 0 -> 57130 bytes >>> images/user/patch-review.puml | 44 +++ >>> user/support/contrib.rst | 67 >>> +- >>> 3 files changed, 97 insertions(+), 14 deletions(-) >>> create mode 100644 images/user/patch-review.png >>> create mode 100644 images/user/patch-review.puml >>> >> >> If you want to review the figure it is ... >> >> http://www.plantuml.com/plantuml/png/dP0_ZzDC4CRx_HGZwoqIlSf9K8Q28451ST7f3WgaD7lsutZ1EsjcnuxoxLcFWt9790gAbNR-_6QUUNPPlUWOU-VivzpsWuZd8-YSHg6wc_-P0X_OCy7dCsaYmHHm8i_DWUlKGS1AWzUwemm9oE_AeCyyfH_OKbKTWrAR97hTM5DLpVKdS4FQuHKuJsymeT-98kQx9CSPlMnSCANztFQsHASkzA3LerKXkR2ng7gX-sR3-pM5JAjlo6j7jFsOh4FmSmo2AsbJ15v1dXYdFyyhwDUXcSjrYZ4eHUJiZQph94tWOt-slhyOGPk9_jkR7IQb7YDOJT1l7QsaI1CaXyJBtNlwdzuS-DLfxMo3RnLYoMgpsLJK1uPDDi-khEN-pVx2N2pVfxLpeQNLmqlyvEr-38g6diyN3b9SdtVnrVU7CNStwm-iQKbA-evQIJ2a73J9OYKd1KauTbe2elinAps3ciIOjtcszEENJ_TF57rWBGzoLxBWncY7FY_gpV6GQo-tDjYXeNKkQngSsvLeZFql >> > > Nice, you can use it for new images here: > > http://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa7 > :) > [...] >>> +* The patch builds. All RTEMS tests link with this patch. >>> + >>> +* The patch does not introduce new compiler warnings. >> >> This step is not in the figure. > > You mean there should be a step mentioning this checklist? Sorry, I missed by a line, I meant the patch builds. I am wondering if building should be in the figure, that is the figure and this text match. I think it is important to point out in a bold manner patches need to build and need to work. I know this is common sense but >> >> Built against which BSPs? > > This is for the user manual. I think at least one arbitrary BSP which is > affected by the patch should be sufficient. > Joel and I now have the BSP builder building on a regular basis because we found things broke in weird ways across archs and bsps. If we had a patch smoke test tool available it would help but we do not. >> >>> +* The patch does not introduce new test failures in existing tests. >> >> This step is not in the figure. >> >> Again which BSPs? This assumes expected fails are valid for the bsps being >> tested. > > I think we should not add to many details to the figure. The list of steps here does not matching the figure is a potential source of user problems if the user inspects the figure and skims the written text. >> >> What about tickets and the "Closes ...", "Updates ..." etc tags? > > Yes, this is missing. What should be checked as well? What does "checked" mean? Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH] dosfs: Fix format with media block sizes > 512
--- cpukit/libfs/src/dosfs/msdos_format.c | 93 +-- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/cpukit/libfs/src/dosfs/msdos_format.c b/cpukit/libfs/src/dosfs/msdos_format.c index 42f1d74575..326040f004 100644 --- a/cpukit/libfs/src/dosfs/msdos_format.c +++ b/cpukit/libfs/src/dosfs/msdos_format.c @@ -65,6 +65,7 @@ typedef struct { bool VolLabel_present; uint32_t vol_id; bool skip_alignment; + char*sec; } msdos_format_param_t; /* @@ -180,11 +181,11 @@ static int msdos_format_fill_sectors +---+ | Input Parameters: | \*-*/ + msdos_format_param_t *fmt_params, const msdos_format_request_param_t *rqdata, int fd, /* file descriptor index*/ uint32_tstart_sector, /* sector number to fill to */ uint32_tsector_cnt, /* number of sectors to fill to */ - uint32_tsector_size, /* size of sector */ const char fill_byte /* byte to fill into sectors*/ ) /*-*\ @@ -193,22 +194,14 @@ static int msdos_format_fill_sectors \*=*/ { int ret_val = 0; - char *fill_buffer = NULL; uint32_t total_sectors = sector_cnt; int last_percent = -1; /* - * allocate and fill buffer + * fill buffer */ if (ret_val == 0) { -fill_buffer = malloc(sector_size); -if (fill_buffer == NULL) { - errno = ENOMEM; - ret_val = -1; -} -else { - memset(fill_buffer,fill_byte,sector_size); -} +memset(fmt_params->sec,fill_byte,fmt_params->bytes_per_sector); } msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, @@ -224,7 +217,9 @@ static int msdos_format_fill_sectors msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "."); last_percent = percent; } -ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer); +ret_val = msdos_format_write_sec(fd,start_sector, + fmt_params->bytes_per_sector, + fmt_params->sec); start_sector++; sector_cnt--; } @@ -235,13 +230,6 @@ static int msdos_format_fill_sectors msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO, "filling error on sector: %d\n", start_sector); - /* - * cleanup - */ - if (fill_buffer != NULL) { -free(fill_buffer); -fill_buffer = NULL; - } return ret_val; } @@ -1016,13 +1004,14 @@ int msdos_format |0, if success, -1 and errno if failed | \*=*/ { - char tmp_sec[FAT_TOTAL_MBR_SIZE]; struct stat stat_buf; int ret_val = 0; int fd= -1; int i; msdos_format_param_t fmt_params; + memset(&fmt_params, 0, sizeof(fmt_params)); + /* * open device for writing */ @@ -1055,6 +1044,14 @@ int msdos_format if (ret_val == 0) { ret_val = msdos_format_determine_fmt_params(fd,rqdata,&fmt_params); } + + if (ret_val == 0) { +fmt_params.sec = malloc(fmt_params.bytes_per_sector); +if (fmt_params.sec == NULL) { + ret_val = -1; +} + } + /* * if requested, write whole disk/partition with 0xe5 */ @@ -1062,11 +1059,11 @@ int msdos_format (rqdata != NULL) && !(rqdata->quick_format)) { ret_val = msdos_format_fill_sectors - (rqdata, + (&fmt_params, + rqdata, fd, 0,/* start sector */ fmt_params.totl_sector_cnt, /* sector count */ - fmt_params.bytes_per_sector, 0xe5); } @@ -1082,11 +1079,11 @@ int msdos_format ret_val = msdos_format_read_sec(fd, 0, fmt_params.bytes_per_sector, -tmp_sec); +fmt_params.sec); if (ret_val == 0) { msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "generate MRB sector\n"); - ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params); + ret_val = msdos_format_gen_mbr(fmt_params.sec,&fmt_params); } /* @@ -1099,7 +1096,7 @@ int msdos_format ret_val = msdos_format_write_sec(fd, 0, fmt_params.bytes_per_sector, - tmp_sec); + fmt_params.sec);
Re: [PATCH] user: Document patch review process
On 01/10/2019 09:22, Chris Johns wrote: On 1/10/19 3:50 pm, Sebastian Huber wrote: On 01/10/2019 01:40, Chris Johns wrote: On 30/9/19 10:45 pm, Sebastian Huber wrote: [...] +* The patch builds. All RTEMS tests link with this patch. + +* The patch does not introduce new compiler warnings. This step is not in the figure. You mean there should be a step mentioning this checklist? Sorry, I missed by a line, I meant the patch builds. I am wondering if building should be in the figure, that is the figure and this text match. I think it is important to point out in a bold manner patches need to build and need to work. I know this is common sense but What about this figure: http://www.plantuml.com/plantuml/png/dLDXQnf14Fr-ls8u2bNAIHBwfVP3JKrf0ur8RA41lwntSzuqjxFNsJd5Vz-zNK5ReOK8WZlptfktRzoPLoFQspPx3QlbtO_YAvN87elx2bcf9fGfpEV5nwTYTLkydLnb0JXttK5esoYCvcEukRf-1sWtM5LOmKOCiOVFTlCb2vyedsNJMn73MuI3wmNAPlZjWNZDXW6DFu0w4DmHxi5mjURIDIZ82ftHiW6FGkZV3q9TrmPqWq45o-UMl4Bj9E4Iv9vtxXcdaETRYarhj8ZzF1_wA-GgAfnh3mOgt64x4qNh9qwsKJUPIZI5nG2x2QTzGot2w35sKNpWsc3yx6eN4pwCWJoCdj2FCu3fdOi8mLyz2PwOKKNGA881nltV2GJgzwuAxHI2ivOKB7fl8hiidLJ4s_QGiF_F2-0VYK6nWrUBc5lqNFOMMOzwoN0jpi8EnPFZ5D02ti3rcl_8e1xoChMYn69U54KEBJ56vLEuaHjhBzjJu1ntit3ZBACQHijp-jx4aB3JuSzwEF9GXlM4MNnQqBBtpSNuDQjBHN4_iTJ0xvmdTPBoPgS8yMs40y13xnKs29LZ7AOPZkN7RvyULc0DiOOloYHKW_78ph3roNrCd7nfv3A6U56gXmVckcmM3k4D_mO0 @startuml start :Arrange your changes in\nan easy to review and\ncoherent patch series; :Apply the checklist for patches; :Invoke: ""git format-patch""; :Send the patch series to devel@rtems.org for review; :Set N to 2; while (Reviewers demand changes in the patch series?) is (Yes) :Do the required changes and create a new patch series; :Update the commit messages accordingly; :Apply the checklist for patches; :Invoke: ""git format-patch -v $N""; :Document the changes from version N to N + 1\nin the patch file after the "---" line; :Set N to N + 1; :Send the patch series to devel@rtems.org for review; endwhile (No) if (Patch series was accepted by reviewers?) then (Yes) :Push the patch series\nto the project repository; note right Must be done by an RTEMS maintainer. end note else (No) :Discard the patch series; endif stop @enduml Built against which BSPs? This is for the user manual. I think at least one arbitrary BSP which is affected by the patch should be sufficient. Joel and I now have the BSP builder building on a regular basis because we found things broke in weird ways across archs and bsps. If we had a patch smoke test tool available it would help but we do not. Yes, this is the long term goal. +* The patch does not introduce new test failures in existing tests. This step is not in the figure. Again which BSPs? This assumes expected fails are valid for the bsps being tested. I think we should not add to many details to the figure. The list of steps here does not matching the figure is a potential source of user problems if the user inspects the figure and skims the written text. What about tickets and the "Closes ...", "Updates ..." etc tags? Yes, this is missing. What should be checked as well? What does "checked" mean? I mean items (individual checks) for the Checklist for Patches. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 2/3] score: Remove strange timecounter init step
The double call of the timecounter get method was added to FreeBSD in 2002 without a comment. It is not clear why this is needed. --- cpukit/score/src/kern_tc.c| 2 +- testsuites/sptests/sptimecounter01/init.c | 12 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 082cb9f7d7..e550b22580 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1399,9 +1399,9 @@ tc_init(struct timecounter *tc) if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) return; -#endif /* __rtems__ */ (void)tc->tc_get_timecount(tc); (void)tc->tc_get_timecount(tc); +#endif /* __rtems__ */ timecounter = tc; #ifdef __rtems__ tc_windup(NULL); diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c index 9fc36583c4..8928c5e051 100644 --- a/testsuites/sptests/sptimecounter01/init.c +++ b/testsuites/sptests/sptimecounter01/init.c @@ -126,25 +126,25 @@ void boot_card(const char *cmdline) tc_soft->tc_frequency = soft_freq; tc_soft->tc_quality = 1234; _Timecounter_Install(tc_soft); - assert(ctx->tc_soft_counter == 3); + assert(ctx->tc_soft_counter == 1); rtems_bsd_binuptime(&bt); - assert(ctx->tc_soft_counter == 4); + assert(ctx->tc_soft_counter == 2); assert(bt.sec == 1); assert(bt.frac == 18446744073708); - ctx->tc_soft_counter = 0xf000 | 3; + ctx->tc_soft_counter = 0xf000 | 1; rtems_bsd_binuptime(&bt); - assert(ctx->tc_soft_counter == (0xf000 | 4)); + assert(ctx->tc_soft_counter == (0xf000 | 2)); assert(bt.sec == 1); assert(bt.frac == 18446744073708); /* Ensure that the fraction overflows and the second remains constant */ - ctx->tc_soft_counter = (0xf000 | 3) + soft_freq; + ctx->tc_soft_counter = (0xf000 | 1) + soft_freq; rtems_bsd_binuptime(&bt); - assert(ctx->tc_soft_counter == (0xf000 | 4) + soft_freq); + assert(ctx->tc_soft_counter == (0xf000 | 2) + soft_freq); assert(bt.sec == 1); assert(bt.frac == 18446742522092); -- 2.16.4 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 1/3] score: Remove superfluous timecounter members
--- cpukit/include/sys/timetc.h | 4 +++- cpukit/score/src/kern_tc.c| 10 +++--- testsuites/sptests/sptimecounter01/init.c | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cpukit/include/sys/timetc.h b/cpukit/include/sys/timetc.h index 347a140ed9..5cdfdfe9b3 100644 --- a/cpukit/include/sys/timetc.h +++ b/cpukit/include/sys/timetc.h @@ -45,12 +45,14 @@ typedef uint32_t timecounter_fill_vdso_timehands32_t(struct vdso_timehands32 *, struct timecounter { timecounter_get_t *tc_get_timecount; +#ifndef __rtems__ /* * This function reads the counter. It is not required to * mask any unimplemented bits out, as long as they are * constant. */ timecounter_pps_t *tc_poll_pps; +#endif /* __rtems__ */ /* * This function is optional. It will be called whenever the * timecounter is rewound, and is intended to check for PPS @@ -64,6 +66,7 @@ struct timecounter { const char *tc_name; /* Name of the timecounter. */ int tc_quality; +#ifndef __rtems__ /* * Used to determine if this timecounter is better than * another timecounter higher means better. Negative @@ -80,7 +83,6 @@ struct timecounter { /* Pointer to the timecounter's private parts. */ struct timecounter *tc_next; /* Pointer to the next timecounter. */ -#ifndef __rtems__ timecounter_fill_vdso_timehands_t *tc_fill_vdso_timehands; timecounter_fill_vdso_timehands32_t *tc_fill_vdso_timehands32; #endif /* __rtems__ */ diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index d705b59a4c..082cb9f7d7 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -146,7 +146,11 @@ dummy_get_timecount(struct timecounter *tc) } static struct timecounter dummy_timecounter = { +#ifndef __rtems__ dummy_get_timecount, 0, ~0u, 100, "dummy", -100 +#else /* __rtems__ */ + dummy_get_timecount, ~(uint32_t)0, 100, "dummy", -100 +#endif /* __rtems__ */ }; struct timehands { @@ -195,9 +199,9 @@ static struct timehands th0 = { static struct timehands *volatile timehands = &th0; struct timecounter *timecounter = &dummy_timecounter; +#ifndef __rtems__ static struct timecounter *timecounters = &dummy_timecounter; -#ifndef __rtems__ int tc_min_ticktock_freq = 1; #endif /* __rtems__ */ @@ -1359,11 +1363,9 @@ tc_init(struct timecounter *tc) tc->tc_name, (uintmax_t)tc->tc_frequency, tc->tc_quality); } -#endif /* __rtems__ */ tc->tc_next = timecounters; timecounters = tc; -#ifndef __rtems__ /* * Set up sysctl tree for this counter. */ @@ -1566,6 +1568,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, } bintime_addx(&th->th_offset, th->th_scale * delta); +#ifndef __rtems__ /* * Hardware latching timecounters may not generate interrupts on * PPS events, so instead we poll them. There is a finite risk that @@ -1576,6 +1579,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, */ if (tho->th_counter->tc_poll_pps) tho->th_counter->tc_poll_pps(tho->th_counter); +#endif /* __rtems__ */ /* * Deal with NTP second processing. The for loop normally diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c index 6976f7bc80..9fc36583c4 100644 --- a/testsuites/sptests/sptimecounter01/init.c +++ b/testsuites/sptests/sptimecounter01/init.c @@ -38,8 +38,9 @@ static test_context test_instance; static uint32_t test_get_timecount_soft(struct timecounter *tc) { - test_context *ctx = tc->tc_priv; + test_context *ctx; + ctx = RTEMS_CONTAINER_OF(tc, test_context, tc_soft); ++ctx->tc_soft_counter; return ctx->tc_soft_counter; @@ -124,7 +125,6 @@ void boot_card(const char *cmdline) tc_soft->tc_counter_mask = 0x0fff; tc_soft->tc_frequency = soft_freq; tc_soft->tc_quality = 1234; - tc_soft->tc_priv = ctx; _Timecounter_Install(tc_soft); assert(ctx->tc_soft_counter == 3); -- 2.16.4 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 3/3] score: Install timecounter according to quality
This makes it possible to install higher quality timecounter in plug-and-play systems and helps to override the clock driver provided timecounter in some test scenarios. --- cpukit/score/src/kern_tc.c| 2 + testsuites/sptests/sptimecounter01/init.c | 101 +++--- 2 files changed, 81 insertions(+), 22 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index e550b22580..1b65cf41ee 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1394,11 +1394,13 @@ tc_init(struct timecounter *tc) return; if (tc->tc_quality < 0) return; +#endif /* __rtems__ */ if (tc->tc_quality < timecounter->tc_quality) return; if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) return; +#ifndef __rtems__ (void)tc->tc_get_timecount(tc); (void)tc->tc_get_timecount(tc); #endif /* __rtems__ */ diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c index 8928c5e051..c949244dc4 100644 --- a/testsuites/sptests/sptimecounter01/init.c +++ b/testsuites/sptests/sptimecounter01/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2019 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -29,32 +29,87 @@ const char rtems_test_name[] = "SPTIMECOUNTER 1"; +#define TEST_QUAL 1234 + +#define TEST_FREQ 100 + typedef struct { - struct timecounter tc_soft; - u_int tc_soft_counter; + struct timecounter tc; + uint32_t counter; + struct timecounter tc_2; + uint32_t counter_2; } test_context; static test_context test_instance; -static uint32_t test_get_timecount_soft(struct timecounter *tc) +static uint32_t test_get_timecount(struct timecounter *tc) +{ + test_context *ctx; + + ctx = RTEMS_CONTAINER_OF(tc, test_context, tc); + ++ctx->counter; + + return ctx->counter; +} + +static uint32_t test_get_timecount_2(struct timecounter *tc) { test_context *ctx; - ctx = RTEMS_CONTAINER_OF(tc, test_context, tc_soft); - ++ctx->tc_soft_counter; + ctx = RTEMS_CONTAINER_OF(tc, test_context, tc_2); + ++ctx->counter_2; + + return ctx->counter_2; +} - return ctx->tc_soft_counter; +static void test_install(test_context *ctx) +{ + struct timecounter *tc; + struct timecounter *tc_2; + uint32_t c; + uint32_t c_2; + + tc = &ctx->tc; + tc_2 = &ctx->tc_2; + c = ctx->counter; + c_2 = ctx->counter_2; + + tc_2->tc_get_timecount = test_get_timecount_2; + tc_2->tc_counter_mask = 0x0fff; + tc_2->tc_frequency = TEST_FREQ - 1; + tc_2->tc_quality = TEST_QUAL; + _Timecounter_Install(tc_2); + assert(ctx->counter == c); + assert(ctx->counter_2 == c_2); + + tc_2->tc_get_timecount = test_get_timecount_2; + tc_2->tc_counter_mask = 0x0fff; + tc_2->tc_frequency = TEST_FREQ - 1; + tc_2->tc_quality = TEST_QUAL + 1; + _Timecounter_Install(tc_2); + assert(ctx->counter == c + 1); + assert(ctx->counter_2 == c_2 + 1); + + tc->tc_get_timecount = test_get_timecount; + tc->tc_counter_mask = 0x0fff; + tc->tc_frequency = TEST_FREQ; + tc->tc_quality = TEST_QUAL + 1; + _Timecounter_Install(tc); + assert(ctx->counter == c + 2); + assert(ctx->counter_2 == c_2 + 2); } void boot_card(const char *cmdline) { - test_context *ctx = &test_instance; - struct timecounter *tc_soft = &ctx->tc_soft; - uint64_t soft_freq = 100; + test_context *ctx; + struct timecounter *tc; struct bintime bt; struct timeval tv; struct timespec ts; + ctx = &test_instance; + tc = &ctx->tc; + TEST_BEGIN(); assert(time(NULL) == TOD_SECONDS_1970_THROUGH_1988); @@ -120,34 +175,36 @@ void boot_card(const char *cmdline) assert(bt.sec == 1); assert(bt.frac == 0); - ctx->tc_soft_counter = 0; - tc_soft->tc_get_timecount = test_get_timecount_soft; - tc_soft->tc_counter_mask = 0x0fff; - tc_soft->tc_frequency = soft_freq; - tc_soft->tc_quality = 1234; - _Timecounter_Install(tc_soft); - assert(ctx->tc_soft_counter == 1); + ctx->counter = 0; + tc->tc_get_timecount = test_get_timecount; + tc->tc_counter_mask = 0x0fff; + tc->tc_frequency = TEST_FREQ; + tc->tc_quality = TEST_QUAL; + _Timecounter_Install(tc); + assert(ctx->counter == 1); rtems_bsd_binuptime(&bt); - assert(ctx->tc_soft_counter == 2); + assert(ctx->counter == 2); assert(bt.sec == 1); assert(bt.frac == 18446744073708); - ctx->tc_soft_counter = 0xf000 | 1; + ctx->counter = 0xf000 | 1; rtems_bsd_binuptime(&bt); - assert(ctx->tc_soft_counter == (0xf000 | 2)); + assert(ctx->counter == (0xf000 | 2)); assert(bt.sec == 1); assert(bt.frac == 18446744073708); /* Ensure that the fraction overflows and the second remains constant */ - ctx->tc_soft_counter = (0xf000 | 1) + soft_freq; + ctx->counter = (0xf
[PATCH 1/3] libtest: Do all output in test runner
This ensures that lines are output atomically if they are produced by different other contexts, e.g. interrupts, other processors, other threads. Update #3199. --- cpukit/include/t.h | 2 + cpukit/libtest/t-test.c| 138 ++--- testsuites/libtests/ttest01/init.c | 4 ++ 3 files changed, 121 insertions(+), 23 deletions(-) diff --git a/cpukit/include/t.h b/cpukit/include/t.h index c5e3792ec1..5dbf1e00b5 100644 --- a/cpukit/include/t.h +++ b/cpukit/include/t.h @@ -2199,6 +2199,8 @@ typedef void (*T_putchar)(int, void *); typedef struct { const char *name; + char *buf; + size_t buf_size; T_putchar putchar; void *putchar_arg; T_verbosity verbosity; diff --git a/cpukit/libtest/t-test.c b/cpukit/libtest/t-test.c index cf3bcd6a99..881a92efb0 100644 --- a/cpukit/libtest/t-test.c +++ b/cpukit/libtest/t-test.c @@ -47,12 +47,16 @@ #include "t-test-printf.h" #endif /* __rtems__ */ -#define T_LINE_SIZE 120 +#define T_LINE_SIZE 128 #define T_SCOPE_SIZE 5 typedef struct { pthread_spinlock_t lock; + char *buf; + unsigned int buf_mask; + atomic_uint buf_head; + atomic_uint buf_tail; void (*putchar)(int, void *); void *putchar_arg; T_verbosity verbosity; @@ -81,18 +85,6 @@ typedef struct { static T_context T_instance; -static int -T_do_vprintf(T_context *ctx, char const *fmt, va_list ap) -{ - return _IO_Vprintf(ctx->putchar, ctx->putchar_arg, fmt, ap); -} - -int -T_vprintf(char const *fmt, va_list ap) -{ - return T_do_vprintf(&T_instance, fmt, ap); -} - typedef struct { char *s; size_t n; @@ -101,13 +93,13 @@ typedef struct { static void T_putchar_string(int c, void *arg) { - T_putchar_string_context *ctx; + T_putchar_string_context *sctx; char *s; size_t n; - ctx = arg; - s = ctx->s; - n = ctx->n; + sctx = arg; + s = sctx->s; + n = sctx->n; if (n == 1) { c = '\0'; @@ -119,8 +111,8 @@ T_putchar_string(int c, void *arg) --n; } - ctx->s = s; - ctx->n = n; + sctx->s = s; + sctx->n = n; } int @@ -128,17 +120,106 @@ T_snprintf(char *s, size_t n, char const *fmt, ...) { va_list ap; int len; - T_putchar_string_context ctx = { + T_putchar_string_context sctx = { .s = s, .n = n }; va_start(ap, fmt); - len = _IO_Vprintf(T_putchar_string, &ctx, fmt, ap); + len = _IO_Vprintf(T_putchar_string, &sctx, fmt, ap); va_end(ap); - if (ctx.n > 0) { - *ctx.s = '\0'; + if (sctx.n > 0) { + *sctx.s = '\0'; + } + + return len; +} + +static int +T_vprintf_direct(char const *fmt, va_list ap) +{ + T_context *ctx; + unsigned int head; + unsigned int tail; + + ctx = &T_instance; + + head = atomic_load_explicit(&ctx->buf_head, memory_order_acquire); + tail = atomic_load_explicit(&ctx->buf_tail, memory_order_relaxed); + + while (head != tail) { + (*ctx->putchar)(ctx->buf[tail], ctx->putchar_arg); + tail = (tail + 1) & ctx->buf_mask; + } + + atomic_store_explicit(&ctx->buf_tail, tail, memory_order_relaxed); + + return _IO_Vprintf(ctx->putchar, ctx->putchar_arg, fmt, ap); +} + +static int +T_vprintf_buffered(char const *fmt, va_list ap) +{ + unsigned int len; + T_context *ctx; + char buf[T_LINE_SIZE]; + T_putchar_string_context sctx = { + .s = buf, + .n = sizeof(buf) + }; + unsigned int head; + unsigned int tail; + unsigned int mask; + unsigned int capacity; + + len = (unsigned int)_IO_Vprintf(T_putchar_string, &sctx, fmt, ap); + + if (len >= sizeof(buf)) { + len = sizeof(buf) - 1; + } + + ctx = &T_instance; + pthread_spin_lock(&ctx->lock); + head = atomic_load_explicit(&ctx->buf_head, memory_order_relaxed); + tail = atomic_load_explicit(&ctx->buf_tail, memory_order_relaxed); + mask = ctx->buf_mask; + capacity = (tail - head - 1) & mask; + + if (len <= capacity) { + unsigned int todo; + char *c; + + todo = len; + c = buf; + + while (todo > 0) { + ctx->buf[head] = *c; + head = (head + 1) & mask; + --todo; + ++c; + } + + atomic_store_explicit(&ctx->buf_head, head, + memory_order_release); + } else { + /* If it does not fit into the buffer, discard everything */ + len = 0; + } + + pthread_spin_unlock(&ctx->lock); + return (int)len; +} + +int +T_vprintf(char const *fmt
[PATCH 3/3] ttest01: Add test outputs all test cases
From: Mikail Yayla --- testsuites/libtests/ttest01/test-assert.c | 21 + testsuites/libtests/ttest01/test-checks.c | 2503 + testsuites/libtests/ttest01/test-destructor.c |7 + testsuites/libtests/ttest01/test-eno.c| 20 + testsuites/libtests/ttest01/test-fixture.c| 20 + testsuites/libtests/ttest01/test-leak.c | 75 + testsuites/libtests/ttest01/test-log.c|7 + testsuites/libtests/ttest01/test-malloc.c | 30 + testsuites/libtests/ttest01/test-plan.c | 31 + testsuites/libtests/ttest01/test-psx.c| 27 + testsuites/libtests/ttest01/test-rtems.c | 32 + testsuites/libtests/ttest01/test-simple.c |8 + testsuites/libtests/ttest01/test-step.c |8 + testsuites/libtests/ttest01/test-time.c | 82 + testsuites/libtests/ttest01/test-verbosity.c |9 + 15 files changed, 2880 insertions(+) diff --git a/testsuites/libtests/ttest01/test-assert.c b/testsuites/libtests/ttest01/test-assert.c index 9055d37194..7bf240279f 100644 --- a/testsuites/libtests/ttest01/test-assert.c +++ b/testsuites/libtests/ttest01/test-assert.c @@ -56,6 +56,27 @@ T_TEST_CASE_FIXTURE(assert2, &fixture) T_log(T_QUIET, "not reached"); } +#include "t-self-test.h" + +T_TEST_OUTPUT(assert, +"B:assert\n" +"P:0:0:UI1:test-assert.c:5\n" +"F:1:0:UI1:test-assert.c:6:test fails and we stop the test case\n" +"E:assert:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(assert2, +"B:assert2\n" +"L:setup\n" +"P:0:0:UI1:test-assert.c:18\n" +"P:1:0:UI1:test-assert.c:54\n" +"F:2:0:UI1:test-assert.c:55:test fails and we stop the test case\n" +"L:stop\n" +"P:3:0:UI1:test-assert.c:29\n" +"L:teardown\n" +"P:4:0:UI1:test-assert.c:40\n" +"P:5:0:UI1:test-assert.c:42\n" +"E:assert2:N:6:F:1:D:0.001000\n"); + /* * SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/testsuites/libtests/ttest01/test-checks.c b/testsuites/libtests/ttest01/test-checks.c index 9d5b4da548..3e2a88bb5e 100644 --- a/testsuites/libtests/ttest01/test-checks.c +++ b/testsuites/libtests/ttest01/test-checks.c @@ -2880,6 +2880,2509 @@ T_TEST_CASE(check_lt_sz) T_assert_lt_sz((size_t)12, (size_t)12); } +#include "t-self-test.h" + +T_TEST_OUTPUT(step_assert_true, +"B:step_assert_true\n" +"P:0:0:UI1:test-checks.c:8\n" +"F:1:0:UI1:test-checks.c:9:a\n" +"E:step_assert_true:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(check_true, +"B:check_true\n" +"P:0:0:UI1:test-checks.c:14\n" +"F:1:0:UI1:test-checks.c:15:a\n" +"F:*:0:UI1:test-checks.c:17:ab 0\n" +"P:2:0:UI1:test-checks.c:18\n" +"F:3:0:UI1:test-checks.c:19:abc 0\n" +"P:4:0:UI1:test-checks.c:20\n" +"F:5:0:UI1:test-checks.c:21:abcd 0 1 2\n" +"E:check_true:N:6:F:4:D:0.001000\n"); + +T_TEST_OUTPUT(step_assert_false, +"B:step_assert_false\n" +"P:0:0:UI1:test-checks.c:27\n" +"F:1:0:UI1:test-checks.c:28:a\n" +"E:step_assert_false:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(check_false, +"B:check_false\n" +"P:0:0:UI1:test-checks.c:33\n" +"F:1:0:UI1:test-checks.c:34:a\n" +"F:*:0:UI1:test-checks.c:36:ab 0\n" +"P:2:0:UI1:test-checks.c:37\n" +"F:3:0:UI1:test-checks.c:38:abc 0\n" +"P:4:0:UI1:test-checks.c:39\n" +"F:5:0:UI1:test-checks.c:40:abcd 0 1 2\n" +"E:check_false:N:6:F:4:D:0.001000\n"); + +T_TEST_OUTPUT(step_assert_eq, +"B:step_assert_eq\n" +"P:0:0:UI1:test-checks.c:46\n" +"F:1:0:UI1:test-checks.c:47:1 == 2\n" +"E:step_assert_eq:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(check_eq, +"B:check_eq\n" +"P:0:0:UI1:test-checks.c:52\n" +"F:1:0:UI1:test-checks.c:53:1 == 2\n" +"F:*:0:UI1:test-checks.c:55:4 == 5\n" +"P:2:0:UI1:test-checks.c:56\n" +"F:3:0:UI1:test-checks.c:57:7 == 8\n" +"P:4:0:UI1:test-checks.c:58\n" +"F:5:0:UI1:test-checks.c:59:10 == 11\n" +"E:check_eq:N:6:F:4:D:0.001000\n"); + +T_TEST_OUTPUT(step_assert_ne, +"B:step_assert_ne\n" +"P:0:0:UI1:test-checks.c:65\n" +"F:1:0:UI1:test-checks.c:66:2 != 2\n" +"E:step_assert_ne:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(check_ne, +"B:check_ne\n" +"P:0:0:UI1:test-checks.c:71\n" +"F:1:0:UI1:test-checks.c:72:2 != 2\n" +"F:*:0:UI1:test-checks.c:74:5 != 5\n" +"P:2:0:UI1:test-checks.c:75\n" +"F:3:0:UI1:test-checks.c:76:5 != 5\n" +"P:4:0:UI1:test-checks.c:77\n" +"F:5:0:UI1:test-checks.c:78:11 != 11\n" +"E:check_ne:N:6:F:4:D:0.001000\n"); + +T_TEST_OUTPUT(step_assert_eq_ptr, +"B:step_assert_eq_ptr\n" +"P:0:0:UI1:test-checks.c:87\n" +"F:1:0:UI1:test-checks.c:88:&a == &b\n" +"E:step_assert_eq_ptr:N:2:F:1:D:0.001000\n"); + +T_TEST_OUTPUT(check_eq_ptr, +"B:check_eq_ptr\n" +"P:0:0:UI1:test-checks.c:96\n" +"F:1:0:UI1:test-checks.c:97:&a == &b\n" +"F:*:0:UI1:test-checks.c:99:&a == &b\n" +"P:2:0:UI1:test-checks.c:100\n" +"F:3:0:UI1:test-checks.c:101:&a == &b\n" +"P:4:0:UI1:test-checks.c:102\n" +"F:5:0:UI1:test-checks.c:103:&a == &b\n" +"E:check_eq_ptr:N:6:F:4:D:0.001000\n"); + +T_TEST_OUTPUT(step_assert_ne_ptr, +"B:step_assert_ne_ptr\n" +"P:0:0:UI1:test-checks.c:112\n" +"F:1:0:UI1:test-checks.c:113:&a != &a\n" +"E:step_assert_ne_ptr:N:2:F:1:D:0.001000\n")
[PATCH 2/3] ttest01: Add more test cases
Update #3199. --- testsuites/libtests/Makefile.am | 15 + testsuites/libtests/ttest01/init.c| 54 +- testsuites/libtests/ttest01/test-assert.c | 90 + testsuites/libtests/ttest01/test-checks.c | 2914 + testsuites/libtests/ttest01/test-destructor.c | 49 + testsuites/libtests/ttest01/test-eno.c| 55 + testsuites/libtests/ttest01/test-fixture.c| 91 + testsuites/libtests/ttest01/test-leak.c | 165 ++ testsuites/libtests/ttest01/test-log.c| 41 + testsuites/libtests/ttest01/test-malloc.c | 88 + testsuites/libtests/ttest01/test-plan.c | 68 + testsuites/libtests/ttest01/test-psx.c| 70 + testsuites/libtests/ttest01/test-rtems.c | 104 + testsuites/libtests/ttest01/test-simple.c | 48 + testsuites/libtests/ttest01/test-step.c | 40 + testsuites/libtests/ttest01/test-time.c | 223 ++ testsuites/libtests/ttest01/test-verbosity.c | 50 + 17 files changed, 4162 insertions(+), 3 deletions(-) create mode 100644 testsuites/libtests/ttest01/test-assert.c create mode 100644 testsuites/libtests/ttest01/test-checks.c create mode 100644 testsuites/libtests/ttest01/test-destructor.c create mode 100644 testsuites/libtests/ttest01/test-eno.c create mode 100644 testsuites/libtests/ttest01/test-fixture.c create mode 100644 testsuites/libtests/ttest01/test-leak.c create mode 100644 testsuites/libtests/ttest01/test-log.c create mode 100644 testsuites/libtests/ttest01/test-malloc.c create mode 100644 testsuites/libtests/ttest01/test-plan.c create mode 100644 testsuites/libtests/ttest01/test-psx.c create mode 100644 testsuites/libtests/ttest01/test-rtems.c create mode 100644 testsuites/libtests/ttest01/test-simple.c create mode 100644 testsuites/libtests/ttest01/test-step.c create mode 100644 testsuites/libtests/ttest01/test-time.c create mode 100644 testsuites/libtests/ttest01/test-verbosity.c diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am index 406961ca73..a668dda103 100644 --- a/testsuites/libtests/Makefile.am +++ b/testsuites/libtests/Makefile.am @@ -1513,7 +1513,22 @@ lib_tests += ttest01 lib_screens += ttest01/ttest01.scn lib_docs += ttest01/ttest01.doc ttest01_SOURCES = ttest01/init.c +ttest01_SOURCES += ttest01/test-assert.c +ttest01_SOURCES += ttest01/test-checks.c +ttest01_SOURCES += ttest01/test-destructor.c +ttest01_SOURCES += ttest01/test-eno.c ttest01_SOURCES += ttest01/test-example.c +ttest01_SOURCES += ttest01/test-fixture.c +ttest01_SOURCES += ttest01/test-leak.c +ttest01_SOURCES += ttest01/test-log.c +ttest01_SOURCES += ttest01/test-malloc.c +ttest01_SOURCES += ttest01/test-plan.c +ttest01_SOURCES += ttest01/test-psx.c +ttest01_SOURCES += ttest01/test-rtems.c +ttest01_SOURCES += ttest01/test-simple.c +ttest01_SOURCES += ttest01/test-step.c +ttest01_SOURCES += ttest01/test-time.c +ttest01_SOURCES += ttest01/test-verbosity.c ttest01_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_ttest01) \ $(support_includes) endif diff --git a/testsuites/libtests/ttest01/init.c b/testsuites/libtests/ttest01/init.c index 135dc2b25e..cb4ad95829 100644 --- a/testsuites/libtests/ttest01/init.c +++ b/testsuites/libtests/ttest01/init.c @@ -32,6 +32,8 @@ #include #include +#include +#include #include "t-self-test.h" @@ -47,6 +49,7 @@ typedef struct { const char *c; size_t case_begin_count; size_t case_end_count; + struct timecounter tc; } test_context; static test_context test_instance; @@ -138,11 +141,44 @@ now(void) return t * SBT_1MS; } +static uint32_t +get_timecount(struct timecounter *tc) +{ + return 0; +} + +static void +install_timecounter(void) +{ + test_context *ctx; + + ctx = &test_instance; + ctx->tc.tc_get_timecount = get_timecount; + ctx->tc.tc_counter_mask = 0x; + ctx->tc.tc_frequency = 10; + ctx->tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1; + rtems_timecounter_install(&ctx->tc); +} + +RTEMS_SYSINIT_ITEM(install_timecounter, RTEMS_SYSINIT_DEVICE_DRIVERS, +RTEMS_SYSINIT_ORDER_FIRST); + static char buffer[512]; static const T_action actions[] = { T_report_hash_sha256, - test_action + test_action, + T_check_file_descriptors, + T_check_rtems_barriers, + T_check_rtems_extensions, + T_check_rtems_message_queues, + T_check_rtems_partitions, + T_check_rtems_periods, + T_check_rtems_regions, + T_check_rtems_semaphores, + T_check_rtems_tasks, + T_check_rtems_timers, + T_check_posix_keys }; static const T_config config = { @@ -180,9 +216,21 @@ Init(rtems_task_argument arg) rtems_test_exit(0); } -#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4 + +#define CONFIGURE_MAXIMUM_BARR
[PATCH 1/2] barrier: Remove leftover semaphore remnants
Remove various incorrect references to "lock" and "obtain" and to an option set which is not part of the barrier interface. It looks like the barrier documentation was started based on a copy of the semaphore documentation and these things are surviving remnants. Also remove an unfinished sentence in the barrier wait description, since the intended information is already provided in the under the NOTE label. --- c-user/barrier_manager.rst | 38 +++--- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst index b0bf3bf..e5d69b0 100644 --- a/c-user/barrier_manager.rst +++ b/c-user/barrier_manager.rst @@ -324,8 +324,7 @@ NOTES: .. _rtems_barrier_wait: -.. index:: obtain a barrier -.. index:: lock a barrier +.. index:: wait at a barrier .. index:: rtems_barrier_wait BARRIER_WAIT - Wait at a barrier @@ -356,14 +355,11 @@ DIRECTIVE STATUS CODES: DESCRIPTION: -This directive acquires the barrier specified by ``id``. The -``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options parameter -indicate whether the calling task wants to wait for the barrier to become -available or return immediately if the barrier is not currently available. -With either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current barrier -count is positive, then it is decremented by one and the barrier is -successfully acquired by returning immediately with a successful return -code. +This directive waits at the barrier specified by ``id``. The timeout +parameter specifies the maximum interval the calling task is willing to be +blocked waiting for the barrier. If it is set to ``RTEMS_NO_TIMEOUT``, +then the calling task will wait forever. If the barrier is available or +the ``RTEMS_NO_WAIT`` option component is set, then timeout is ignored. Conceptually, the calling task should always be thought of as blocking when it makes this call and being unblocked when the barrier is released. If @@ -372,24 +368,7 @@ DESCRIPTION: callers will block except for the one which is the Nth task which trips the automatic release condition. -The timeout parameter specifies the maximum interval the calling task is -willing to be blocked waiting for the barrier. If it is set to -``RTEMS_NO_TIMEOUT``, then the calling task will wait forever. If the -barrier is available or the ``RTEMS_NO_WAIT`` option component is set, then -timeout is ignored. - NOTES: - -The following barrier acquisition option constants are defined by RTEMS: - -.. list-table:: - :class: rtems-table - - * - ``RTEMS_WAIT`` - - task will wait for barrier (default) - * - ``RTEMS_NO_WAIT`` - - task should not wait - A clock tick is required to support the timeout functionality of this directive. @@ -399,7 +378,6 @@ NOTES: .. _rtems_barrier_release: -.. index:: wait at a barrier .. index:: release a barrier .. index:: rtems_barrier_release @@ -425,9 +403,7 @@ DIRECTIVE STATUS CODES: DESCRIPTION: This directive releases the barrier specified by id. All tasks waiting at -the barrier will be unblocked. If the running task's preemption mode is -enabled and one of the unblocked tasks has a higher priority than the -running task. +the barrier will be unblocked. NOTES: The calling task may be preempted if it causes a higher priority task to be -- 2.11.0 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 2/2] barrier: Remove unfinished sentence
Remove the unfinished sentence "Since a barrier is, by definition, never immediately [...]" and jump directly to "The task may wait [forever or for a timeout]" instead. I cannot figure out what the unfinished sentence is supposed to be - "released"? "passed"? --- c-user/barrier_manager.rst | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst index e5d69b0..9a57645 100644 --- a/c-user/barrier_manager.rst +++ b/c-user/barrier_manager.rst @@ -119,10 +119,9 @@ Waiting at a Barrier The ``rtems_barrier_wait`` directive is used to wait at -the specified barrier. Since a barrier is, by definition, never immediately, -the task may wait forever for the barrier to be released or it may -specify a timeout. Specifying a timeout limits the interval the task will -wait before returning with an error status code. +the specified barrier. The task may wait forever for the barrier to be +released or it may specify a timeout. Specifying a timeout limits the interval +the task will wait before returning with an error status code. If the barrier is configured as automatic and there are already one less then the maximum number of waiters, then the call will unblock all tasks waiting at -- 2.11.0 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[Resend] [PATCH 0/2] rtems-doc barrier fixes
Hi, I'm re-sending this patch set since I received no reply previously (2019-09-04). Martin Erik Werner (2): barrier: Remove leftover semaphore remnants barrier: Remove unfinished sentence c-user/barrier_manager.rst | 45 ++--- 1 file changed, 10 insertions(+), 35 deletions(-) -- 2.11.0 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH v2 3/3] ttest01: New test
On Fri, Mar 22, 2019 at 3:20 AM Sebastian Huber wrote: > > This is an example test using the RTEMS Test Framework. It tests also > the framework itself. > > Add T_FILE_NAME command line define to get rid of the full file path. > This is important to reduce the read-only data of test files and make > them build system independent. > > Update #3199. > --- > testsuites/automake/compile.am | 1 + > testsuites/libtests/Makefile.am| 10 ++ > testsuites/libtests/configure.ac | 1 + > testsuites/libtests/ttest01/init.c | 183 > + > testsuites/libtests/ttest01/t-self-test.h | 46 > testsuites/libtests/ttest01/test-example.c | 57 + > testsuites/libtests/ttest01/ttest01.doc| 19 +++ > testsuites/libtests/ttest01/ttest01.scn| 26 > 8 files changed, 343 insertions(+) > create mode 100644 testsuites/libtests/ttest01/init.c > create mode 100644 testsuites/libtests/ttest01/t-self-test.h > create mode 100644 testsuites/libtests/ttest01/test-example.c > create mode 100644 testsuites/libtests/ttest01/ttest01.doc > create mode 100644 testsuites/libtests/ttest01/ttest01.scn > > diff --git a/testsuites/automake/compile.am b/testsuites/automake/compile.am > index 83d4ab111c..66ea9a8421 100644 > --- a/testsuites/automake/compile.am > +++ b/testsuites/automake/compile.am > @@ -11,6 +11,7 @@ STRIP = @STRIP@ > TEST_LD_FLAGS = -Wl,--wrap=printf -Wl,--wrap=puts -Wl,--wrap=putchar > > AM_CPPFLAGS = $(TEST_FLAGS) @RTEMS_CPPFLAGS@ @RTEMS_BSP_CPPFLAGS@ > +AM_CPPFLAGS += -DT_FILE_NAME='"$(notdir $<)"' > AM_CFLAGS = $(TEST_C_FLAGS) > AM_CXXFLAGS = $(TEST_CXX_FLAGS) > > diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am > index fe6f7d8ee8..1b80283123 100644 > --- a/testsuites/libtests/Makefile.am > +++ b/testsuites/libtests/Makefile.am > @@ -1500,6 +1500,16 @@ top_SOURCES = top/init.c top/task1.c top/task2.c > top/task3.c \ > top_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_top) $(support_includes) > endif > > +if TEST_ttest01 > +lib_tests += ttest01 > +lib_screens += ttest01/ttest01.scn > +lib_docs += ttest01/ttest01.doc > +ttest01_SOURCES = ttest01/init.c > +ttest01_SOURCES += ttest01/test-example.c > +ttest01_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_ttest01) \ > + $(support_includes) > +endif > + > if TEST_tztest > lib_tests += tztest > lib_screens += tztest/tztest.scn > diff --git a/testsuites/libtests/configure.ac > b/testsuites/libtests/configure.ac > index a6879a7430..c02b42a5f9 100644 > --- a/testsuites/libtests/configure.ac > +++ b/testsuites/libtests/configure.ac > @@ -226,6 +226,7 @@ RTEMS_TEST_CHECK([termios07]) > RTEMS_TEST_CHECK([termios08]) > RTEMS_TEST_CHECK([termios09]) > RTEMS_TEST_CHECK([top]) > +RTEMS_TEST_CHECK([ttest01]) > RTEMS_TEST_CHECK([tztest]) > RTEMS_TEST_CHECK([uid01]) > RTEMS_TEST_CHECK([unlink]) > diff --git a/testsuites/libtests/ttest01/init.c > b/testsuites/libtests/ttest01/init.c > new file mode 100644 > index 00..6a76eec123 > --- /dev/null > +++ b/testsuites/libtests/ttest01/init.c > @@ -0,0 +1,183 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (C) 2018, 2019 embedded brains GmbH > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + *notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + *notice, this list of conditions and the following disclaimer in the > + *documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > + > +#include > +#include > + > +#include > +#include > + > +#include "t-self-test.h" > + > +#include > + > +const char rtems_test_name[] = "TTEST 1"; > + > +#define test_assert(e) (e) ? (void)0 : test_failed(__LINE__, #e) > + > +RTEMS_LINKER_ROSET(t_self_test, const char *); > + > +typedef struct { > + const char *c; > + BSP_output_char_function_
Re: [PATCH 1/2] barrier: Remove leftover semaphore remnants
On Wed, Sep 4, 2019 at 3:36 PM Martin Erik Werner wrote: > > Remove various incorrect references to "lock" and "obtain" and to an > option set which is not part of the barrier interface. > > It looks like the barrier documentation was started based on a copy of > the semaphore documentation and these things are surviving remnants. > > Also remove an unfinished sentence in the barrier wait description, > since the intended information is already provided in the under the NOTE > label. Thanks for your contribution! I have a few minor comments: > --- > c-user/barrier_manager.rst | 38 +++--- > 1 file changed, 7 insertions(+), 31 deletions(-) > > diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst > index b0bf3bf..e5d69b0 100644 > --- a/c-user/barrier_manager.rst > +++ b/c-user/barrier_manager.rst > @@ -324,8 +324,7 @@ NOTES: > > .. _rtems_barrier_wait: > > -.. index:: obtain a barrier > -.. index:: lock a barrier > +.. index:: wait at a barrier > .. index:: rtems_barrier_wait > > BARRIER_WAIT - Wait at a barrier > @@ -356,14 +355,11 @@ DIRECTIVE STATUS CODES: > > DESCRIPTION: > > -This directive acquires the barrier specified by ``id``. The > -``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options parameter > -indicate whether the calling task wants to wait for the barrier to become > -available or return immediately if the barrier is not currently > available. > -With either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current barrier > -count is positive, then it is decremented by one and the barrier is > -successfully acquired by returning immediately with a successful return > -code. > +This directive waits at the barrier specified by ``id``. The timeout > +parameter specifies the maximum interval the calling task is willing to > be > +blocked waiting for the barrier. If it is set to ``RTEMS_NO_TIMEOUT``, > +then the calling task will wait forever. If the barrier is available or 1. "will wait forever" -> "will wait forever if it doesn't get released" or something more precise, even just "may wait forever" 2. I'm not quite sure what "available" means in this context. Maybe "open" is a better word? > +the ``RTEMS_NO_WAIT`` option component is set, then timeout is ignored. > > Conceptually, the calling task should always be thought of as blocking > when > it makes this call and being unblocked when the barrier is released. If > @@ -372,24 +368,7 @@ DESCRIPTION: > callers will block except for the one which is the Nth task which trips > the > automatic release condition. > > -The timeout parameter specifies the maximum interval the calling task is > -willing to be blocked waiting for the barrier. If it is set to > -``RTEMS_NO_TIMEOUT``, then the calling task will wait forever. If the > -barrier is available or the ``RTEMS_NO_WAIT`` option component is set, > then > -timeout is ignored. > - > NOTES: > - > -The following barrier acquisition option constants are defined by RTEMS: > - > -.. list-table:: > - :class: rtems-table > - > - * - ``RTEMS_WAIT`` > - - task will wait for barrier (default) > - * - ``RTEMS_NO_WAIT`` > - - task should not wait > - > A clock tick is required to support the timeout functionality of this > directive. > > @@ -399,7 +378,6 @@ NOTES: > > .. _rtems_barrier_release: > > -.. index:: wait at a barrier > .. index:: release a barrier > .. index:: rtems_barrier_release > > @@ -425,9 +403,7 @@ DIRECTIVE STATUS CODES: > > DESCRIPTION: > This directive releases the barrier specified by id. All tasks waiting > at > -the barrier will be unblocked. If the running task's preemption mode is > -enabled and one of the unblocked tasks has a higher priority than the > -running task. > +the barrier will be unblocked. > > NOTES: > The calling task may be preempted if it causes a higher priority task to > be > -- > 2.11.0 > > ___ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 2/2] barrier: Remove unfinished sentence
On Tue, Oct 1, 2019 at 11:09 AM Martin Erik Werner wrote: > > Remove the unfinished sentence > "Since a barrier is, by definition, never immediately [...]" > and jump directly to > "The task may wait [forever or for a timeout]" > instead. > > I cannot figure out what the unfinished sentence is supposed to be - > "released"? "passed"? This unfinished sentence seems to exist since the barrier documentation was introduced. Maybe Joel remembers. My guess is that it was starting to say "never immediately available", although I don't think that is true for an automatic release barrier. Your rewrite looks good to me. > --- > c-user/barrier_manager.rst | 7 +++ > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst > index e5d69b0..9a57645 100644 > --- a/c-user/barrier_manager.rst > +++ b/c-user/barrier_manager.rst > @@ -119,10 +119,9 @@ Waiting at a Barrier > > > The ``rtems_barrier_wait`` directive is used to wait at > -the specified barrier. Since a barrier is, by definition, never immediately, > -the task may wait forever for the barrier to be released or it may > -specify a timeout. Specifying a timeout limits the interval the task will > -wait before returning with an error status code. > +the specified barrier. The task may wait forever for the barrier to be > +released or it may specify a timeout. Specifying a timeout limits the > interval > +the task will wait before returning with an error status code. > > If the barrier is configured as automatic and there are already one less then > the maximum number of waiters, then the call will unblock all tasks waiting > at > -- > 2.11.0 > > ___ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 1/2] barrier: Remove leftover semaphore remnants
On Tue, Oct 1, 2019 at 3:53 PM Gedare Bloom wrote: > > On Wed, Sep 4, 2019 at 3:36 PM Martin Erik Werner > wrote: > > > > Remove various incorrect references to "lock" and "obtain" and to an > > option set which is not part of the barrier interface. > > > > It looks like the barrier documentation was started based on a copy of > > the semaphore documentation and these things are surviving remnants. > > > > Also remove an unfinished sentence in the barrier wait description, > > since the intended information is already provided in the under the NOTE > > label. > Thanks for your contribution! I have a few minor comments: > > > --- > > c-user/barrier_manager.rst | 38 +++--- > > 1 file changed, 7 insertions(+), 31 deletions(-) > > > > diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst > > index b0bf3bf..e5d69b0 100644 > > --- a/c-user/barrier_manager.rst > > +++ b/c-user/barrier_manager.rst > > @@ -324,8 +324,7 @@ NOTES: > > > > .. _rtems_barrier_wait: > > > > -.. index:: obtain a barrier > > -.. index:: lock a barrier > > +.. index:: wait at a barrier > > .. index:: rtems_barrier_wait > > > > BARRIER_WAIT - Wait at a barrier > > @@ -356,14 +355,11 @@ DIRECTIVE STATUS CODES: > > > > DESCRIPTION: > > > > -This directive acquires the barrier specified by ``id``. The > > -``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options > > parameter > > -indicate whether the calling task wants to wait for the barrier to > > become > > -available or return immediately if the barrier is not currently > > available. > > -With either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current barrier > > -count is positive, then it is decremented by one and the barrier is > > -successfully acquired by returning immediately with a successful return > > -code. > > +This directive waits at the barrier specified by ``id``. The timeout > > +parameter specifies the maximum interval the calling task is willing > > to be > > +blocked waiting for the barrier. If it is set to ``RTEMS_NO_TIMEOUT``, > > +then the calling task will wait forever. If the barrier is available > > or > 1. "will wait forever" -> "will wait forever if it doesn't get > released" or something more precise, even just "may wait forever" > 2. I'm not quite sure what "available" means in this context. Maybe > "open" is a better word? > I guess "available" is the wording that has been used throughout. Again, probably due to inheriting from the semaphore documentation. I think "open/closed" is more precise when describing a barrier, but available is OK if it is consistently applied. I would still like the fix on #1, even though that was not introduced by you just copied from elsewhere, it is good to improve it at the same time. > > +the ``RTEMS_NO_WAIT`` option component is set, then timeout is ignored. > > > > Conceptually, the calling task should always be thought of as blocking > > when > > it makes this call and being unblocked when the barrier is released. > > If > > @@ -372,24 +368,7 @@ DESCRIPTION: > > callers will block except for the one which is the Nth task which > > trips the > > automatic release condition. > > > > -The timeout parameter specifies the maximum interval the calling task > > is > > -willing to be blocked waiting for the barrier. If it is set to > > -``RTEMS_NO_TIMEOUT``, then the calling task will wait forever. If the > > -barrier is available or the ``RTEMS_NO_WAIT`` option component is set, > > then > > -timeout is ignored. > > - > > NOTES: > > - > > -The following barrier acquisition option constants are defined by > > RTEMS: > > - > > -.. list-table:: > > - :class: rtems-table > > - > > - * - ``RTEMS_WAIT`` > > - - task will wait for barrier (default) > > - * - ``RTEMS_NO_WAIT`` > > - - task should not wait > > - > > A clock tick is required to support the timeout functionality of this > > directive. > > > > @@ -399,7 +378,6 @@ NOTES: > > > > .. _rtems_barrier_release: > > > > -.. index:: wait at a barrier > > .. index:: release a barrier > > .. index:: rtems_barrier_release > > > > @@ -425,9 +403,7 @@ DIRECTIVE STATUS CODES: > > > > DESCRIPTION: > > This directive releases the barrier specified by id. All tasks > > waiting at > > -the barrier will be unblocked. If the running task's preemption mode > > is > > -enabled and one of the unblocked tasks has a higher priority than the > > -running task. > > +the barrier will be unblocked. > > > > NOTES: > > The calling task may be preempted if it causes a higher priority task > > to be > > -- > > 2.11.0 > > > > ___ > > devel mailing list > > devel@rtems.org > > http://lists.rtems.org/mailman/listinfo/devel ___ devel mailing list devel@rtems.org http://lists.rtems
Re: [PATCH 1/2] barrier: Remove leftover semaphore remnants
On Tue, Oct 1, 2019, 5:07 PM Gedare Bloom wrote: > On Tue, Oct 1, 2019 at 3:53 PM Gedare Bloom wrote: > > > > On Wed, Sep 4, 2019 at 3:36 PM Martin Erik Werner > > wrote: > > > > > > Remove various incorrect references to "lock" and "obtain" and to an > > > option set which is not part of the barrier interface. > > > > > > It looks like the barrier documentation was started based on a copy of > > > the semaphore documentation and these things are surviving remnants. > > > > > > Also remove an unfinished sentence in the barrier wait description, > > > since the intended information is already provided in the under the > NOTE > > > label. > > Thanks for your contribution! I have a few minor comments: > > > > > --- > > > c-user/barrier_manager.rst | 38 +++--- > > > 1 file changed, 7 insertions(+), 31 deletions(-) > > > > > > diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst > > > index b0bf3bf..e5d69b0 100644 > > > --- a/c-user/barrier_manager.rst > > > +++ b/c-user/barrier_manager.rst > > > @@ -324,8 +324,7 @@ NOTES: > > > > > > .. _rtems_barrier_wait: > > > > > > -.. index:: obtain a barrier > > > -.. index:: lock a barrier > > > +.. index:: wait at a barrier > > > .. index:: rtems_barrier_wait > > > > > > BARRIER_WAIT - Wait at a barrier > > > @@ -356,14 +355,11 @@ DIRECTIVE STATUS CODES: > > > > > > DESCRIPTION: > > > > > > -This directive acquires the barrier specified by ``id``. The > > > -``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options > parameter > > > -indicate whether the calling task wants to wait for the barrier > to become > > > -available or return immediately if the barrier is not currently > available. > > > -With either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current > barrier > > > -count is positive, then it is decremented by one and the barrier > is > > > -successfully acquired by returning immediately with a successful > return > > > -code. > > > +This directive waits at the barrier specified by ``id``. The > timeout > > > +parameter specifies the maximum interval the calling task is > willing to be > > > +blocked waiting for the barrier. If it is set to > ``RTEMS_NO_TIMEOUT``, > > > +then the calling task will wait forever. If the barrier is > available or > > 1. "will wait forever" -> "will wait forever if it doesn't get > > released" or something more precise, even just "may wait forever" > Will wait until the barrier is released/opened. Then add there is no option for no wait as found in other APIs. > 2. I'm not quite sure what "available" means in this context. Maybe > > "open" is a better word? > > > I guess "available" is the wording that has been used throughout. > Again, probably due to inheriting from the semaphore documentation. I > think "open/closed" is more precise when describing a barrier, but > available is OK if it is consistently applied. > Open/closed is better. I think of a barrier as the starting gates at a horse race. Horses arrive and wait while the gates are closed. When the race starts, all gates are opened and the horses are released. > > I would still like the fix on #1, even though that was not introduced > by you just copied from elsewhere, it is good to improve it at the > same time. > > > > +the ``RTEMS_NO_WAIT`` option component is set, then timeout is > ignored. > > > > > > Conceptually, the calling task should always be thought of as > blocking when > > > it makes this call and being unblocked when the barrier is > released. If > > > @@ -372,24 +368,7 @@ DESCRIPTION: > > > callers will block except for the one which is the Nth task which > trips the > > > automatic release condition. > > > > > > -The timeout parameter specifies the maximum interval the calling > task is > > > -willing to be blocked waiting for the barrier. If it is set to > > > -``RTEMS_NO_TIMEOUT``, then the calling task will wait forever. > If the > > > -barrier is available or the ``RTEMS_NO_WAIT`` option component is > set, then > > > -timeout is ignored. > > > - > > > NOTES: > > > - > > > -The following barrier acquisition option constants are defined by > RTEMS: > > > - > > > -.. list-table:: > > > - :class: rtems-table > > > - > > > - * - ``RTEMS_WAIT`` > > > - - task will wait for barrier (default) > > > - * - ``RTEMS_NO_WAIT`` > > > - - task should not wait > > > - > > > A clock tick is required to support the timeout functionality of > this > > > directive. > > > > > > @@ -399,7 +378,6 @@ NOTES: > > > > > > .. _rtems_barrier_release: > > > > > > -.. index:: wait at a barrier > > > .. index:: release a barrier > > > .. index:: rtems_barrier_release > > > > > > @@ -425,9 +403,7 @@ DIRECTIVE STATUS CODES: > > > > > > DESCRIPTION: > > > This directive releases the barrier specified by id. All tasks > waiting at > > > -the barrier will be unblocke
Re: [PATCH 2/2] barrier: Remove unfinished sentence
On Tue, Oct 1, 2019, 5:04 PM Gedare Bloom wrote: > On Tue, Oct 1, 2019 at 11:09 AM Martin Erik Werner > wrote: > > > > Remove the unfinished sentence > > "Since a barrier is, by definition, never immediately [...]" > > and jump directly to > > "The task may wait [forever or for a timeout]" > > instead. > > > > I cannot figure out what the unfinished sentence is supposed to be - > > "released"? "passed"? > This unfinished sentence seems to exist since the barrier > documentation was introduced. Maybe Joel remembers. My guess is that > it was starting to say "never immediately available", although I don't > think that is true for an automatic release barrier. Your rewrite > looks good to me. > Logically I think the thread still "waited" until all the threads were unblocked. It wasn't available when the call was made. It was not made available from an external view. The threads were just released. Maybe this is just my odd view. You always stop at a barrier. Sometimes blocking, sometimes long enough to do the releasing work. > > --- > > c-user/barrier_manager.rst | 7 +++ > > 1 file changed, 3 insertions(+), 4 deletions(-) > > > > diff --git a/c-user/barrier_manager.rst b/c-user/barrier_manager.rst > > index e5d69b0..9a57645 100644 > > --- a/c-user/barrier_manager.rst > > +++ b/c-user/barrier_manager.rst > > @@ -119,10 +119,9 @@ Waiting at a Barrier > > > > > > The ``rtems_barrier_wait`` directive is used to wait at > > -the specified barrier. Since a barrier is, by definition, never > immediately, > > -the task may wait forever for the barrier to be released or it may > > -specify a timeout. Specifying a timeout limits the interval the task > will > > -wait before returning with an error status code. > > +the specified barrier. The task may wait forever for the barrier to be > > +released or it may specify a timeout. Specifying a timeout limits the > interval > > +the task will wait before returning with an error status code. > > > > If the barrier is configured as automatic and there are already one > less then > > the maximum number of waiters, then the call will unblock all tasks > waiting at > > -- > > 2.11.0 > > > > ___ > > devel mailing list > > devel@rtems.org > > http://lists.rtems.org/mailman/listinfo/devel > ___ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel > ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH v2 3/3] ttest01: New test
On 01/10/2019 23:40, Gedare Bloom wrote: +/* + * SPDX-License-Identifier: BSD-2-Clause + * SPDX-License-Identifier: CC-BY-SA-4.0 + * + * Copyright (C) 2018, 2019 embedded brains GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International Public License as + * published by Creative Commons, PO Box 1866, Mountain View, CA 94042 + * (https://creativecommons.org/licenses/by-sa/4.0/legalcode). + */ Is there any standing for dual-licensing 2BSD with CC-BY-SA? diff --git a/testsuites/libtests/ttest01/ttest01.doc b/testsuites/libtests/ttest01/ttest01.doc new file mode 100644 index 00..37d9ff8535 --- /dev/null +++ b/testsuites/libtests/ttest01/ttest01.doc @@ -0,0 +1,19 @@ +This file describes the directives and concepts tested by this test set. + +test set name: ttest01 + +The test-*.c files must place the license header at the bottom of the file. +This allows a copy and past of the test code into documentation sources and paste +enables a constent line numbering between the documentation code fragements and constant ... fragments +the actual test output. For the same reason the T_TEST_OUTPUT() macros must be +placed after the actual test cases. The test source files are dual licensesd licensed +BSD-2-Clause and CC-BY-SA-4.0. + Thanks for the above explanation, it was helpful for this example. For future tests, do you anticipate any text here such as a short narrative description? Or this text should be deleted if it gets copy-paste into new tests? Everything which may end up in the documentation (such as code examples) should be dual licensed BSD-2-Clause and CC-BY-SA-4.0 from my point of view. Otherwise we would have to deal with BSD-2-Clause also in the documentation set. Not every test needs this, just the one that may be used in the documentation, e.g. https://docs.rtems.org/branches/master/eng/test-framework.html#test-fixture I would like to add also code examples to the RTEMS Classic API Guide for the managers (not in the next weeks). Another candidate for dual licensing are the interface specification items. I would like to generate the API header files with Doxygen markup and the API documentation from a single source - the interface specification items. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 2/2] ttest01: Check init/final run output
Update #3199. --- testsuites/libtests/ttest01/init.c | 85 ++ 1 file changed, 85 insertions(+) diff --git a/testsuites/libtests/ttest01/init.c b/testsuites/libtests/ttest01/init.c index cb4ad95829..44ffadf112 100644 --- a/testsuites/libtests/ttest01/init.c +++ b/testsuites/libtests/ttest01/init.c @@ -45,11 +45,20 @@ const char rtems_test_name[] = "TTEST 1"; RTEMS_LINKER_ROSET(t_self_test, const char *); +typedef enum { + CENSOR_PASS_THROUGH, + CENSOR_DISCARD +} censor_state; + typedef struct { const char *c; size_t case_begin_count; size_t case_end_count; struct timecounter tc; + T_putchar putchar; + void *putchar_arg; + const char *censor_c; + censor_state censor_state; } test_context; static test_context test_instance; @@ -113,6 +122,76 @@ case_late(const char *name) ctx->c = NULL; } +static const char censored_init[] = "A:ttest01\n" +"S:Platform:RTEMS\n" +"S:Compiler:*" +"S:Version:*" +"S:BSP:*" +"S:RTEMS_DEBUG:*" +"S:RTEMS_MULTIPROCESSING:*" +"S:RTEMS_POSIX_API:*" +"S:RTEMS_PROFILING:*" +"S:RTEMS_SMP:*"; + +static void +censor_putchar(int c, void *arg) +{ + test_context *ctx; + + ctx = arg; + + if (*ctx->censor_c == '\0') { + T_putchar discard_putchar; + void *discard_putchar_arg; + + (*ctx->putchar)(c, ctx->putchar_arg); + T_set_putchar(ctx->putchar, ctx->putchar_arg, &discard_putchar, + &discard_putchar_arg); + return; + } + + switch (ctx->censor_state) { + case CENSOR_PASS_THROUGH: + if (*ctx->censor_c == '*') { + (*ctx->putchar)('*', ctx->putchar_arg); + ctx->censor_state = CENSOR_DISCARD; + } else if (c == *ctx->censor_c) { + (*ctx->putchar)(c, ctx->putchar_arg); + ++ctx->censor_c; + } + break; + case CENSOR_DISCARD: + if (c == '\n') { + (*ctx->putchar)(c, ctx->putchar_arg); + ctx->censor_state = CENSOR_PASS_THROUGH; + ++ctx->censor_c; + } + break; + } +} + +static void +run_initialize(void) +{ + test_context *ctx; + + ctx = &test_instance; + ctx->censor_c = censored_init; + T_set_putchar(censor_putchar, ctx, &ctx->putchar, &ctx->putchar_arg); +} + +static const char expected_final[] = "Z:ttest01:C:341:N:1316:F:790:D:0.682999\n" +"Y:ReportHash:SHA256:62d6f3b37299137932ea2c2f0505c8b8f12b95749c81d5af19570e9470203475\n"; + +static void +run_finalize(void) +{ + test_context *ctx; + + ctx = &test_instance; + ctx->c = expected_final; +} + static void test_action(T_event event, const char *name) { @@ -125,6 +204,12 @@ test_action(T_event event, const char *name) case T_EVENT_CASE_LATE: case_late(name); break; + case T_EVENT_RUN_INITIALIZE_EARLY: + run_initialize(); + break; + case T_EVENT_RUN_FINALIZE_EARLY: + run_finalize(); + break; default: break; }; -- 2.16.4 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 1/2] libtest: Add more action events
This allows more control over the initialization and finalization run. Update #3199. --- cpukit/include/t.h | 6 -- cpukit/libtest/t-test-hash-sha256.c | 4 ++-- cpukit/libtest/t-test-rtems-fds.c | 2 +- cpukit/libtest/t-test-rtems-heap.c | 2 +- cpukit/libtest/t-test-rtems-objs.c | 20 ++-- cpukit/libtest/t-test.c | 18 ++ 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/cpukit/include/t.h b/cpukit/include/t.h index 5dbf1e00b5..ec806a1f68 100644 --- a/cpukit/include/t.h +++ b/cpukit/include/t.h @@ -2185,12 +2185,14 @@ void T_free(void *); void T_register(void); typedef enum { - T_EVENT_RUN_INITIALIZE, + T_EVENT_RUN_INITIALIZE_EARLY, + T_EVENT_RUN_INITIALIZE_LATE, T_EVENT_CASE_EARLY, T_EVENT_CASE_BEGIN, T_EVENT_CASE_END, T_EVENT_CASE_LATE, - T_EVENT_RUN_FINALIZE + T_EVENT_RUN_FINALIZE_EARLY, + T_EVENT_RUN_FINALIZE_LATE } T_event; typedef void (*T_action)(T_event, const char *); diff --git a/cpukit/libtest/t-test-hash-sha256.c b/cpukit/libtest/t-test-hash-sha256.c index c272da27ac..4793a508e5 100644 --- a/cpukit/libtest/t-test-hash-sha256.c +++ b/cpukit/libtest/t-test-hash-sha256.c @@ -88,10 +88,10 @@ T_report_hash_sha256(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_report_hash_sha256_initialize(); break; - case T_EVENT_RUN_FINALIZE: + case T_EVENT_RUN_FINALIZE_LATE: T_report_hash_sha256_finalize(); break; default: diff --git a/cpukit/libtest/t-test-rtems-fds.c b/cpukit/libtest/t-test-rtems-fds.c index 79720a01c4..19abbd3673 100644 --- a/cpukit/libtest/t-test-rtems-fds.c +++ b/cpukit/libtest/t-test-rtems-fds.c @@ -71,7 +71,7 @@ T_check_file_descriptors(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_open_fds = T_count_open_fds(); break; case T_EVENT_CASE_END: diff --git a/cpukit/libtest/t-test-rtems-heap.c b/cpukit/libtest/t-test-rtems-heap.c index 8858f5b952..6755e886b2 100644 --- a/cpukit/libtest/t-test-rtems-heap.c +++ b/cpukit/libtest/t-test-rtems-heap.c @@ -100,7 +100,7 @@ T_check_heap(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_heap_run_initialize(); break; case T_EVENT_CASE_END: diff --git a/cpukit/libtest/t-test-rtems-objs.c b/cpukit/libtest/t-test-rtems-objs.c index dd4f2d59d2..55da1ab850 100644 --- a/cpukit/libtest/t-test-rtems-objs.c +++ b/cpukit/libtest/t-test-rtems-objs.c @@ -94,7 +94,7 @@ T_check_rtems_barriers(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_barriers_run_initialize(); break; case T_EVENT_CASE_END: @@ -127,7 +127,7 @@ T_check_rtems_extensions(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_extensions_run_initialize(); break; case T_EVENT_CASE_END: @@ -160,7 +160,7 @@ T_check_rtems_message_queues(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_message_queues_run_initialize(); break; case T_EVENT_CASE_END: @@ -193,7 +193,7 @@ T_check_rtems_partitions(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_partitions_run_initialize(); break; case T_EVENT_CASE_END: @@ -226,7 +226,7 @@ T_check_rtems_periods(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_periods_run_initialize(); break; case T_EVENT_CASE_END: @@ -259,7 +259,7 @@ T_check_rtems_regions(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_regions_run_initialize(); break; case T_EVENT_CASE_END: @@ -292,7 +292,7 @@ T_check_rtems_semaphores(T_event event, const char *name) (void)name; switch (event) { - case T_EVENT_RUN_INITIALIZE: + case T_EVENT_RUN_INITIALIZE_EARLY: T_rtems_
[PATCH v2] user: Document patch review process
--- v2: * Added ticket comments to checklist for patches. * Added checklist for patches step to figure: http://www.plantuml.com/plantuml/uml/dL71Yjim4BthAnwcXuJYXRscXwRG7dhOiEosXq8kMdiSgskDtD4u8NzVUrH8sa0BFGYacVVUwBtPPlMYKnoSivjpcmyYdW-4Sve4JR_SCmBlsJF8vpCqGUWOw0JFxPwRr9CGAqQlJOzC4YY_MuJ6SPZHFSqgrBmE8Ikw90LN89_vc5vfWwew16j6hxNrgshfFnEtfd2j3KrewKZ3LfHYlajoCDtogK9Jx1RO_VmwzM4Wh9wiIvBHKlJSNbcxcV1-ZP2n-aPvxO3DnsG8eHzJ4BemJKN8Ay63wVH70WlrwzWkRGiXnHWKaNBsncwQ96tWmt0ks7_d1LoixV3Mx05_IH7r4MzsbgNvQAP8h2WpYebEKiIH98V4sA76lQdl-RTSkYL3toc95QkwhYiCWScK_szFC-VNRdPfxLpei7gyff-yXKIZKekNCmgFP5cFziIN1JrEkRyPlsTDfIZfEpKAeJ7be4bAtfoK8E7GgmE0XoahNWXjObgcURRoqvTF3y-8Fh3EX-JE0SIjiHqDkVpUqWsvyN8RWnaDdNDPq-ZSTdvDSVW9 images/user/patch-review.png | Bin 0 -> 63668 bytes images/user/patch-review.puml | 48 user/support/contrib.rst | 71 +- 3 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 images/user/patch-review.png create mode 100644 images/user/patch-review.puml diff --git a/images/user/patch-review.png b/images/user/patch-review.png new file mode 100644 index ..40ee0a99894c03537c2f01f1296018b0f089c662 GIT binary patch literal 63668 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
[PATCH v3] user: Document patch review process
--- v2: * Added ticket comments to checklist for patches. * Added checklist for patches step to figure: http://www.plantuml.com/plantuml/uml/dL71Yjim4BthAnwcXuJYXRscXwRG7dhOiEosXq8kMdiSgskDtD4u8NzVUrH8sa0BFGYacVVUwBtPPlMYKnoSivjpcmyYdW-4Sve4JR_SCmBlsJF8vpCqGUWOw0JFxPwRr9CGAqQlJOzC4YY_MuJ6SPZHFSqgrBmE8Ikw90LN89_vc5vfWwew16j6hxNrgshfFnEtfd2j3KrewKZ3LfHYlajoCDtogK9Jx1RO_VmwzM4Wh9wiIvBHKlJSNbcxcV1-ZP2n-aPvxO3DnsG8eHzJ4BemJKN8Ay63wVH70WlrwzWkRGiXnHWKaNBsncwQ96tWmt0ks7_d1LoixV3Mx05_IH7r4MzsbgNvQAP8h2WpYebEKiIH98V4sA76lQdl-RTSkYL3toc95QkwhYiCWScK_szFC-VNRdPfxLpei7gyff-yXKIZKekNCmgFP5cFziIN1JrEkRyPlsTDfIZfEpKAeJ7be4bAtfoK8E7GgmE0XoahNWXjObgcURRoqvTF3y-8Fh3EX-JE0SIjiHqDkVpUqWsvyN8RWnaDdNDPq-ZSTdvDSVW9 v3: * Add missing content from stray rebase commit. images/user/patch-review.png | Bin 0 -> 63668 bytes images/user/patch-review.puml | 48 ++ user/support/contrib.rst | 111 -- 3 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 images/user/patch-review.png create mode 100644 images/user/patch-review.puml diff --git a/images/user/patch-review.png b/images/user/patch-review.png new file mode 100644 index ..40ee0a99894c03537c2f01f1296018b0f089c662 GIT binary patch literal 63668 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