Proper streamer implementation

Proper streamer implementation

Have dedicated writer thread - it is going to be working pretty much
non-stop, we don't want that particular bottleneck spread across worker
threads.

Re-writing visibility data seems to be a larger performance problem than
I had expected. Seems HDF5 really doesn't do too well with random access
to chunks. Some of this will likely go away with larger chunks, we'll
have to do some larger scale tests to figure that out.

--- examples/grid/streamer.c
+++ examples/grid/streamer.c
@@ -10,29 +10,174 @@
 #include <omp.h>
 #include <mpi.h>

-void streamer_ireceive(struct work_config *wcfg,
-                       double complex *NMBF_NMBF_queue, MPI_Request *requests_queue,
-                       int subgrid_worker, int subgrid_work,
-                       int *producer_ranks)
-{
+
+struct streamer
+{
+    struct work_config *work_cfg;
+    int subgrid_worker;
+    int *producer_ranks;
+
+    struct sep_kernel_data kern;
+    bool have_kern;
+
+    // Incoming data queue (to be assembled)
+    int queue_length;
+    double complex *nmbf_queue;
+    MPI_Request *request_queue;
+
+    // Subgrid queue (to be degridded)
+    double complex *subgrid_queue;
+    int *subgrid_locks;
+    fftw_plan subgrid_plan;
+
+    // Visibility chunk queue (to be written)
+    int vis_queue_length;
+    double complex *vis_queue;
+    int *vis_a1, *vis_a2, *vis_tchunk, *vis_fchunk;
+    int vis_in_ptr, vis_out_ptr;
+    omp_lock_t *vis_in_lock, *vis_out_lock; // Ready to fill / write to disk
+
+    // Visibility file
+    hid_t vis_file;
+    hid_t vis_group;
+
+    // Statistics
+    double wait_time;
+    double critical_wait_time;
+    double wait_in_time, wait_out_time;
+    double read_time, write_time;
+    double recombine_time, degrid_time;
+    uint64_t received_data, received_subgrids, baselines_covered;
+    uint64_t written_vis_data, rewritten_vis_data;
+};
+
+static double complex *nmbf_slot(struct streamer *streamer, int slot, int facet)
+{
+    const int facets = streamer->work_cfg->facet_workers * streamer->work_cfg->facet_max_work;
+    const int xM_yN_size = streamer->work_cfg->recombine.xM_yN_size;
+    assert(facet >= 0 && facet < facets);
+    return streamer->nmbf_queue + xM_yN_size * xM_yN_size * ((slot * facets) + facet);
+}
+
+static MPI_Request *request_slot(struct streamer *streamer, int slot, int facet)
+{
+    const int facets = streamer->work_cfg->facet_workers * streamer->work_cfg->facet_max_work;
+    assert(facet >= 0 && facet < facets);
+    return streamer->request_queue + (slot * facets) + facet;
+}
+
+static double complex *subgrid_slot(struct streamer *streamer, int slot)
+{
+    const int xM_size = streamer->work_cfg->recombine.xM_size;
+    return streamer->nmbf_queue + xM_size * xM_size * slot;
+}
+
+void streamer_ireceive(struct streamer *streamer,
+                       int subgrid_work)
+{
+
+    const int xM_yN_size = streamer->work_cfg->recombine.xM_yN_size;
+
+    // Identify slot
+    const int slot = subgrid_work % streamer->queue_length;

     // Walk through all facets we expect contributions from
+    const int facets = streamer->work_cfg->facet_workers * streamer->work_cfg->facet_max_work;
     int facet;
-    for (facet = 0; facet < wcfg->facet_workers * wcfg->facet_max_work; facet++) {
-        struct facet_work *fwork = wcfg->facet_work + facet;
+    for (facet = 0; facet < facets; facet++) {
+        struct facet_work *fwork = streamer->work_cfg->facet_work + facet;
         if (!fwork->set) {
-            requests_queue[facet] = MPI_REQUEST_NULL;
+            *request_slot(streamer, slot, facet) = MPI_REQUEST_NULL;
             continue;
         }

         // Set up a receive slot with appropriate tag
-        const int tag = make_subgrid_tag(wcfg, subgrid_worker, subgrid_work,
-                                         facet / wcfg->facet_max_work, facet % wcfg->facet_max_work);
-        const int elems = wcfg->recombine.xM_yN_size * wcfg->recombine.xM_yN_size;
-        int facet_worker = facet / wcfg->facet_max_work;
-        MPI_Irecv(NMBF_NMBF_queue + facet * elems, elems, MPI_DOUBLE_COMPLEX,
-                  producer_ranks[facet_worker], tag, MPI_COMM_WORLD,
-                  requests_queue + facet);
+        const int tag = make_subgrid_tag(streamer->work_cfg, streamer->subgrid_worker, subgrid_work,
+                                         facet / streamer->work_cfg->facet_max_work,
+                                         facet % streamer->work_cfg->facet_max_work);
+        int facet_worker = facet / streamer->work_cfg->facet_max_work;
+        MPI_Irecv(nmbf_slot(streamer, slot, facet),
+                  xM_yN_size * xM_yN_size, MPI_DOUBLE_COMPLEX,
+                  streamer->producer_ranks[facet_worker], tag, MPI_COMM_WORLD,
+                  request_slot(streamer, slot, facet));
+    }
+
+}
+
+void streamer_writer(struct streamer *streamer)
+{
+    struct vis_spec *const spec = &streamer->work_cfg->spec;
+    const int vis_data_size = sizeof(double complex) * spec->time_chunk * spec->freq_chunk;
+    double complex *vis_data_h5 = (double complex *) alloca(vis_data_size);
+
+    int time_chunk_count = spec->time_count / spec->time_chunk;
+    int freq_chunk_count = spec->freq_count / spec->freq_chunk;
+    int bl_count = spec->cfg->ant_count * spec->cfg->ant_count
+        * time_chunk_count * freq_chunk_count;
+    bool *bls_written = calloc(sizeof(bool), bl_count);
+
+    for(;;) {
+
+        // Obtain "out" lock for writing out visibilities
+        double start = get_time_ns();
+        omp_set_lock(streamer->vis_out_lock + streamer->vis_out_ptr);
+        streamer->wait_out_time += get_time_ns() - start;
+        //printf("Obtained out lock on slot %d\n", streamer->vis_out_ptr);
+
+        start = get_time_ns();
+
+        // Obtain baseline data
+        struct bl_data bl_data;
+        int tchunk = streamer->vis_tchunk[streamer->vis_out_ptr];
+        int fchunk = streamer->vis_fchunk[streamer->vis_out_ptr];
+        if (tchunk == -1 && fchunk == -1)
+            break; // Signal to end thread
+        vis_spec_to_bl_data(&bl_data, spec,
+                            streamer->vis_a1[streamer->vis_out_ptr],
+                            streamer->vis_a2[streamer->vis_out_ptr]);
+        double complex *vis_data = streamer->vis_queue +
+            streamer->vis_out_ptr * spec->time_chunk * spec->freq_chunk;
+
+        // Read visibility chunk. If it
+        // was not yet set, this will just fill the buffer with zeroes.
+        int chunk_index = ((bl_data.antenna2 * spec->cfg->ant_count + bl_data.antenna1)
+                           * time_chunk_count + tchunk) * freq_chunk_count + fchunk;
+        if (bls_written[chunk_index]) {
+            read_vis_chunk(streamer->vis_group, &bl_data,
+                           spec->time_chunk, spec->freq_chunk, tchunk, fchunk,
+                           vis_data_h5);
+        } else {
+            memset(vis_data_h5, 0, vis_data_size);
+        }
+        streamer->read_time += get_time_ns() - start;
+
+        // Copy over data
+        start = get_time_ns();
+        int i;
+        for (i = 0; i < spec->time_chunk * spec->freq_chunk; i++) {
+            if (vis_data[i] != 0) {
+                // Make sure we never over-write data!
+                assert(vis_data_h5[i] == 0);
+                vis_data_h5[i] = vis_data[i];
+            }
+        }
+
+        // Write chunk back
+        write_vis_chunk(streamer->vis_group, &bl_data,
+                        spec->time_chunk, spec->freq_chunk, tchunk, fchunk,
+                        vis_data_h5);
+        streamer->written_vis_data += vis_data_size;
+        if (bls_written[chunk_index])
+            streamer->rewritten_vis_data += vis_data_size;
+        bls_written[chunk_index] = true;
+
+        free(bl_data.time); free(bl_data.uvw_m); free(bl_data.freq);
+
+        // Release "in" lock to mark the slot free for writing
+        omp_unset_lock(streamer->vis_in_lock + streamer->vis_out_ptr);
+        streamer->vis_out_ptr = (streamer->vis_out_ptr + 1) % streamer->vis_queue_length;
+        streamer->write_time += get_time_ns() - start;
+
     }

 }
@@ -40,27 +185,27 @@
 static double min(double a, double b) { return a > b ? b : a; }
 static double max(double a, double b) { return a < b ? b : a; }

-void streamer_degrid_chunk(struct work_config *wcfg,
-                           struct sep_kernel_data *kern,
-                           hid_t vis_group,
+void streamer_degrid_chunk(struct streamer *streamer,
                            struct subgrid_work *work,
                            struct subgrid_work_bl *bl,
                            struct bl_data *bl_data,
                            int tchunk, int fchunk,
+                           int slot,
                            double complex *subgrid)
 {
-    struct vis_spec *spec = &wcfg->spec;
-    struct recombine2d_config *cfg = &wcfg->recombine;
-
-    double sg_mid_u = work->subgrid_off_u / wcfg->theta;
-    double sg_mid_v = work->subgrid_off_v / wcfg->theta;
-    double sg_min_u = (work->subgrid_off_u - cfg->xA_size / 2) / wcfg->theta;
-    double sg_min_v = (work->subgrid_off_v - cfg->xA_size / 2) / wcfg->theta;
-    double sg_max_u = (work->subgrid_off_u + cfg->xA_size / 2) / wcfg->theta;
-    double sg_max_v = (work->subgrid_off_v + cfg->xA_size / 2) / wcfg->theta;
-    if (sg_min_v > cfg->image_size / wcfg->theta / 2) {
-        sg_min_v -= cfg->image_size / wcfg->theta / 2;
-        sg_max_v -= cfg->image_size / wcfg->theta / 2;
+    struct vis_spec *const spec = &streamer->work_cfg->spec;
+    struct recombine2d_config *const cfg = &streamer->work_cfg->recombine;
+    const double theta = streamer->work_cfg->theta;
+
+    double sg_mid_u = work->subgrid_off_u / theta;
+    double sg_mid_v = work->subgrid_off_v / theta;
+    double sg_min_u = (work->subgrid_off_u - cfg->xA_size / 2) / theta;
+    double sg_min_v = (work->subgrid_off_v - cfg->xA_size / 2) / theta;
+    double sg_max_u = (work->subgrid_off_u + cfg->xA_size / 2) / theta;
+    double sg_max_v = (work->subgrid_off_v + cfg->xA_size / 2) / theta;
+    if (sg_min_v > cfg->image_size / theta / 2) {
+        sg_min_v -= cfg->image_size / theta / 2;
+        sg_max_v -= cfg->image_size / theta / 2;
     }

     // Determine chunk size
@@ -91,38 +236,25 @@
     if (!overlap && !inv_overlap)
         return;

-    printf("baseline %d/%d chunk %d/%d\n", bl->a1, bl->a2, tchunk, fchunk);
-    printf("u: %g-%g (%g-%g)\n", min_u, max_u, sg_min_u, sg_max_u);
-    printf("v: %g-%g (%g-%g)\n", min_v, max_v, sg_min_v, sg_max_v);
-
-    // Only now we commit to doing I/O - read visibility chunk. If it
-    // was not yet set, this will just fill the buffer with zeroes.
-    double complex *vis_data = (double complex *)
-        alloca(sizeof(double complex) * spec->time_chunk * spec->freq_chunk);
-
-    read_vis_chunk(vis_group, bl_data,
-                   spec->time_chunk, spec->freq_chunk, tchunk, fchunk,
-                   vis_data);
-
-    //printf("read visibilities:\n");
-    //int i_t, i_f;
-    //for(i_t = 0; i_t < spec->time_chunk; i_t++) {
-    //    for(i_f = 0; i_f < spec->freq_chunk; i_f++) {
-    //        printf("%g%+gi ",
-    //               creal(vis_data[i_t*spec->freq_chunk+i_f]),
-    //               cimag(vis_data[i_t*spec->freq_chunk+i_f]));
-    //    }
-    //    puts("");
-    //}
+    //printf("baseline %d/%d chunk %d/%d\n", bl->a1, bl->a2, tchunk, fchunk);
+    //printf("u: %g-%g (%g-%g)\n", min_u, max_u, sg_min_u, sg_max_u);
+    //printf("v: %g-%g (%g-%g)\n", min_v, max_v, sg_min_v, sg_max_v);
+
+    // Allocate visibility chunk (on stack)
+    const int vis_data_size = sizeof(double complex) * spec->time_chunk * spec->freq_chunk;
+    double complex *vis_data = (double complex *) alloca(vis_data_size);
+    memset(vis_data, 0, vis_data_size);

     // Do degridding. Twice if necessary.
+    double start = get_time_ns();
     uint64_t flops = 0;
+
     if (overlap) {
         bl_data->vis = vis_data; // HACK
-        flops += degrid_conv_bl(subgrid, cfg->xM_size, wcfg->theta,
+        flops += degrid_conv_bl(subgrid, cfg->xM_size, theta,
                                 sg_mid_u, sg_mid_v,
                                 max(0, sg_min_u), sg_max_u, sg_min_v, sg_max_v,
-                                bl_data, it0, it1, if0, if1, kern);
+                                bl_data, it0, it1, if0, if1, &streamer->kern);
     }
     if (inv_overlap) {
         int i;
@@ -131,61 +263,82 @@
             bl_data->uvw_m[i] *= -1;
         }
         bl_data->vis = vis_data; // HACK
-        flops += degrid_conv_bl(subgrid, cfg->xM_size, wcfg->theta,
+        flops += degrid_conv_bl(subgrid, cfg->xM_size, theta,
                                 sg_mid_u, sg_mid_v,
                                 max(0, sg_min_u), sg_max_u, sg_min_v, sg_max_v,
-                                bl_data, it0, it1, if0, if1, kern);
+                                bl_data, it0, it1, if0, if1, &streamer->kern);
         for(i = 0; i < 3 * spec->time_count; i++) {
             bl_data->uvw_m[i] *= -1;
         }
     }

-    //printf("writing visibilities:\n");
-    //for(i_t = 0; i_t < spec->time_chunk; i_t++) {
-    //    for(i_f = 0; i_f < spec->freq_chunk; i_f++) {
-    //        printf("%g%+gi ",
-    //               creal(vis_data[i_t*spec->freq_chunk+i_f]),
-    //               cimag(vis_data[i_t*spec->freq_chunk+i_f]));
-    //    }
-    //    puts("");
-    //}
-    //printf(" %d flops\n", flops);
-
-    // Write chunk back
-    write_vis_chunk(vis_group, bl_data,
-                   spec->time_chunk, spec->freq_chunk, tchunk, fchunk,
-                   vis_data);
-
-    // Read visibility chunk (in case previous data exists)
-
-
-    //printf("bl %d/%d du=%g dv=%g\n", bl->a1, bl->a2,
-
-
-    /* int i; */
-    /* for (i = 0; i < 1 /\* wcfg->spec.time_count *\/; i++) { */
-    /*     printf("t=%.4f: %g %g %g / %g %g %g\n", bl_data.time[i], */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+0],bl_data.freq[0]), */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+1],bl_data.freq[0]), */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+2],bl_data.freq[0]), */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+0],bl_data.freq[bl_data.freq_count-1]), */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+1],bl_data.freq[bl_data.freq_count-1]), */
-    /*            uvw_m_to_l(bl_data.uvw_m[i*3+2],bl_data.freq[bl_data.freq_count-1])); */
-    /* } */
-
-}
-
-void streamer_work(struct work_config *wcfg,
-                   struct sep_kernel_data *kern, hid_t vis_group,
-                   int subgrid_worker, int subgrid_work,
-                   double complex *data,
-                   double complex *subgrid, fftw_plan subgrid_plan)
-{
-
-    struct recombine2d_config *cfg = &wcfg->recombine;
-    struct subgrid_work *work = wcfg->subgrid_work + subgrid_worker * wcfg->subgrid_max_work + subgrid_work;
-    const int facets = wcfg->facet_workers * wcfg->facet_max_work;
-    const int data_length = wcfg->recombine.NMBF_NMBF_size / sizeof(double complex);
+    #pragma omp atomic
+    streamer->degrid_time += get_time_ns() - start;
+
+    // No flops executed? Skip doing I/O
+    if (flops == 0) {
+        return;
+    }
+
+    // Determine our slot (competing with other tasks, so need to have
+    // critical section here)
+    int vis_slot;
+    start = get_time_ns();
+    #pragma omp critical
+    {
+        streamer->critical_wait_time += get_time_ns() - start;
+        vis_slot = streamer->vis_in_ptr;
+        streamer->vis_in_ptr = (streamer->vis_in_ptr + 1) % streamer->vis_queue_length;
+    }
+
+    // Obtain lock for writing data (writer thread might not have
+    // written this data to disk yet)
+    start = get_time_ns();
+    if(streamer->vis_group >= 0)
+        omp_set_lock(streamer->vis_in_lock + vis_slot);
+    #pragma omp atomic
+    streamer->wait_in_time += get_time_ns() - start;
+
+    // Set slot data
+    double complex *vis_data_out = streamer->vis_queue +
+        vis_slot * spec->time_chunk * spec->freq_chunk;
+    memcpy(vis_data_out, vis_data, vis_data_size);
+    streamer->vis_a1[vis_slot] = bl->a1;
+    streamer->vis_a2[vis_slot] = bl->a2;
+    streamer->vis_tchunk[vis_slot] = tchunk;
+    streamer->vis_fchunk[vis_slot] = fchunk;
+
+    // Signal slot for output
+    if(streamer->vis_group >= 0)
+        omp_unset_lock(streamer->vis_out_lock + vis_slot);
+
+}
+
+void streamer_work(struct streamer *streamer,
+                   int subgrid_work,
+                   double complex *nmbf)
+{
+
+    struct recombine2d_config *const cfg = &streamer->work_cfg->recombine;
+    struct subgrid_work *const work = streamer->work_cfg->subgrid_work +
+        streamer->subgrid_worker * streamer->work_cfg->subgrid_max_work + subgrid_work;
+    struct facet_work *const facet_work = streamer->work_cfg->facet_work;
+
+    const int facets = streamer->work_cfg->facet_workers * streamer->work_cfg->facet_max_work;
+    const int nmbf_length = cfg->NMBF_NMBF_size / sizeof(double complex);
+
+    // Identify slot to write to
+    int slot = subgrid_work % streamer->queue_length;
+    double start_wait = get_time_ns();
+    while(streamer->subgrid_locks[slot] != 0) {
+        #pragma omp taskyield
+        if (get_time_ns() > start_wait + 1) {
+            printf("Waiting on slot %d (%d)...\n", slot, streamer->subgrid_locks[slot]);
+            start_wait = get_time_ns();
+        }
+    }
+
+    double recombine_start = get_time_ns();

     // Compare with reference
     if (work->check_fct_path) {
@@ -193,16 +346,16 @@
         int i0 = work->iv, i1 = work->iu;
         int ifacet;
         for (ifacet = 0; ifacet < facets; ifacet++) {
-            if (!wcfg->facet_work[ifacet].set) continue;
-            int j0 = wcfg->facet_work[ifacet].im, j1 = wcfg->facet_work[ifacet].il;
-            double complex *ref = read_hdf5(wcfg->recombine.NMBF_NMBF_size, work->check_hdf5,
+            if (!facet_work[ifacet].set) continue;
+            int j0 = facet_work[ifacet].im, j1 = facet_work[ifacet].il;
+            double complex *ref = read_hdf5(cfg->NMBF_NMBF_size, work->check_hdf5,
                                             work->check_fct_path, j0, j1);
             int x; double err_sum = 0;
-            for (x = 0; x < data_length; x++) {
-                double err = cabs(ref[x] - data[data_length*ifacet+x]); err_sum += err*err;
+            for (x = 0; x < nmbf_length; x++) {
+                double err = cabs(ref[x] - nmbf[nmbf_length*ifacet+x]); err_sum += err*err;
             }
             free(ref);
-            double rmse = sqrt(err_sum / data_length);
+            double rmse = sqrt(err_sum / nmbf_length);
             if (!work->check_fct_threshold || rmse > work->check_fct_threshold) {
                 printf("Subgrid %d/%d facet %d/%d checked: %g RMSE\n",
                        i0, i1, j0, j1, rmse);
@@ -211,16 +364,17 @@
     }

     // Accumulate contributions to this subgrid
+    double complex *subgrid = subgrid_slot(streamer, slot);
     memset(subgrid, 0, cfg->SG_size);
     int ifacet;
     for (ifacet = 0; ifacet < facets; ifacet++)
         recombine2d_af0_af1(cfg, subgrid,
-                            wcfg->facet_work[ifacet].facet_off_m,
-                            wcfg->facet_work[ifacet].facet_off_l,
-                            data + data_length*ifacet);
+                            facet_work[ifacet].facet_off_m,
+                            facet_work[ifacet].facet_off_l,
+                            nmbf + nmbf_length*ifacet);

     // Perform Fourier transform
-    fftw_execute(subgrid_plan);
+    fftw_execute_dft(streamer->subgrid_plan, subgrid, subgrid);

     // Check accumulated result
     if (work->check_path) {
@@ -237,7 +391,7 @@
     }

     // Check some degridded example visibilities
-    if (work->check_degrid_path && kern) {
+    if (work->check_degrid_path && streamer->have_kern) {
         int nvis = get_npoints_hdf5(work->check_hdf5, "%s/vis", work->check_degrid_path);
         double *uvw_sg = read_hdf5(3 * sizeof(double) * nvis, work->check_hdf5,
                                    "%s/uvw_subgrid", work->check_degrid_path);
@@ -258,7 +412,7 @@
         bl.uvw_m = uvw_sg;
         degrid_conv_bl(subgrid, cfg->xM_size, cfg->image_size, 0, 0,
                        -cfg->xM_size, cfg->xM_size, -cfg->xM_size, cfg->xM_size,
-                       &bl, 0, nvis, 0, 1, kern);
+                       &bl, 0, nvis, 0, 1, &streamer->kern);
         double err_sum = 0; int y;
         for (y = 0; y < nvis; y++) {
             double err = cabs(vis[y] - bl.vis[y]); err_sum += err*err;
@@ -270,37 +424,93 @@

     }

-    if (wcfg->spec.time_count > 0 && kern) {
+    streamer->recombine_time += get_time_ns() - recombine_start;
+
+    struct vis_spec *const spec = &streamer->work_cfg->spec;
+    if (spec->time_count > 0 && streamer->have_kern) {
+
+        const int bls_per_task = 256;

         // Loop through baselines
         struct subgrid_work_bl *bl;
-        for (bl = work->bls; bl; bl = bl->next) {
-
-            // Get baseline data
-            struct bl_data bl_data;
-            vis_spec_to_bl_data(&bl_data, &wcfg->spec, bl->a1, bl->a2);
-
-            // Go through time/frequency chunks
-            int ntchunk = (bl_data.time_count + wcfg->spec.time_chunk - 1) / wcfg->spec.time_chunk;
-            int nfchunk = (bl_data.freq_count + wcfg->spec.freq_chunk - 1) / wcfg->spec.freq_chunk;
-            int tchunk, fchunk;
-            for (tchunk = 0; tchunk < ntchunk; tchunk++)
-                for (fchunk = 0; fchunk < nfchunk; fchunk++)
-                    streamer_degrid_chunk(wcfg, kern, vis_group, work,
-                                          bl, &bl_data, tchunk, fchunk,
-                                          subgrid);
-        }
-
-    }
-}
-
-void streamer(struct work_config *wcfg, int subgrid_worker, int *producer_ranks) {
+        int i_bl = 0;
+        for (bl = work->bls; bl; bl = bl->next, i_bl++) {
+            if (i_bl % bls_per_task != 0)
+                continue;
+
+            // We are spawning a task: Add lock to subgrid data to
+            // make sure it doesn't get overwritten
+            #pragma omp atomic
+            streamer->subgrid_locks[slot]++;
+
+            #pragma omp task
+            {
+                char bls_str[2048];
+                bls_str[0] = 0;
+
+                struct subgrid_work_bl *bl2;
+                int i_bl2;
+                for (bl2 = bl, i_bl2 = 0; bl2 && i_bl2 < bls_per_task; bl2 = bl2->next, i_bl2++) {
+                    // Get baseline data
+                    struct bl_data bl_data;
+                    vis_spec_to_bl_data(&bl_data, spec, bl2->a1, bl2->a2);
+
+                    // Go through time/frequency chunks
+                    int ntchunk = (bl_data.time_count + spec->time_chunk - 1) / spec->time_chunk;
+                    int nfchunk = (bl_data.freq_count + spec->freq_chunk - 1) / spec->freq_chunk;
+                    int tchunk, fchunk;
+                    for (tchunk = 0; tchunk < ntchunk; tchunk++)
+                        for (fchunk = 0; fchunk < nfchunk; fchunk++)
+                            streamer_degrid_chunk(streamer, work,
+                                                  bl2, &bl_data, tchunk, fchunk,
+                                                  slot, subgrid);
+
+                    free(bl_data.time); free(bl_data.uvw_m); free(bl_data.freq);
+
+                    sprintf(bls_str + strlen(bls_str), "%d/%d ", bl2->a1, bl2->a2);
+                }
+
+                // Done with this chunk
+#pragma omp atomic
+                streamer->subgrid_locks[slot]--;
+                //printf("sg %d/%d bl %s done (slot %d: %d)\n", work->iu, work->iv, bls_str,
+                //       slot, streamer->subgrid_locks[slot]);
+            }
+        }
+
+        printf("Subgrid %d/%d (%d baselines)\n", work->iu, work->iv, i_bl);
+        streamer->baselines_covered += i_bl;
+
+    }
+}
+
+bool streamer_init(struct streamer *streamer,
+                   struct work_config *wcfg, int subgrid_worker, int *producer_ranks)
+{

     struct recombine2d_config *cfg = &wcfg->recombine;
-    struct subgrid_work *work = wcfg->subgrid_work + subgrid_worker * wcfg->subgrid_max_work;
     const int facets = wcfg->facet_workers * wcfg->facet_max_work;
-    hid_t vis_file = -1, vis_group = -1;
-    struct sep_kernel_data kern; bool have_kern = false;
+
+    streamer->work_cfg = wcfg;
+    streamer->subgrid_worker = subgrid_worker;
+    streamer->producer_ranks = producer_ranks;
+
+    streamer->have_kern = false;
+    streamer->vis_file = streamer->vis_group = -1;
+    streamer->write_time = 0;
+    streamer->wait_time = streamer->wait_in_time = streamer->wait_out_time =
+        streamer->critical_wait_time = 0;
+    streamer->read_time = streamer->write_time = streamer->degrid_time = 0;
+    streamer->received_data = 0;
+    streamer->received_subgrids = streamer->baselines_covered = 0;
+    streamer->written_vis_data = streamer->rewritten_vis_data = 0;
+
+    // Load gridding kernel
+    if (wcfg->gridder_path) {
+        if (load_sep_kern(wcfg->gridder_path, &streamer->kern))
+            return false;
+        streamer->have_kern = true;
+    }

     // Create HDF5 output file if we are meant to output any amount of
     // visibilities
@@ -312,72 +522,119 @@

         // Open file and "vis" group
         printf("\nCreating %s... ", filename);
-        vis_file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
-        vis_group = H5Gcreate(vis_file, "vis", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
-        if (vis_file < 0 || vis_group < 0) {
+        streamer->vis_file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+        streamer->vis_group = H5Gcreate(streamer->vis_file, "vis", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        if (streamer->vis_file < 0 || streamer->vis_group < 0) {
             fprintf(stderr, "Could not open visibility file %s!\n", filename);
         } else {
-            create_bl_groups(vis_group, wcfg, subgrid_worker);
-        }
-    }
-
-    // Load gridding kernel
-    if (wcfg->gridder_path)
-        if (!load_sep_kern(wcfg->gridder_path, &kern))
-            have_kern = true;
+            create_bl_groups(streamer->vis_group, wcfg, subgrid_worker);
+        }
+
+        H5Fflush(streamer->vis_file, H5F_SCOPE_LOCAL);
+    }

     // Allocate receive queue
-    const int recv_queue_depth = 64;
-    const int data_length = cfg->NMBF_NMBF_size / sizeof(double complex);
-    const int queue_size = sizeof(double complex) * data_length * facets * recv_queue_depth;
-    const int requests_size = sizeof(MPI_Request) * facets * recv_queue_depth;
-    printf("Allocating %d MB receive queue\n", (queue_size+requests_size) / 1000000);
-    double complex *NMBF_NMBF_queue = (double complex *)malloc(queue_size);
-    MPI_Request *request_queue = (MPI_Request *) malloc(requests_size);
-    MPI_Status *status_queue = (MPI_Status *) malloc(sizeof(MPI_Status) * facets * recv_queue_depth);
+    streamer->queue_length = 32;
+    const int nmbf_length = cfg->NMBF_NMBF_size / sizeof(double complex);
+    const int queue_size = sizeof(double complex) * nmbf_length * facets * streamer->queue_length;
+    const int sg_queue_size = cfg->SG_size * streamer->queue_length;
+    const int requests_size = sizeof(MPI_Request) * facets * streamer->queue_length;
+    printf("Allocating %.3g GB receive queue\n", (double)(queue_size+sg_queue_size+requests_size) / 1000000000);
+    streamer->nmbf_queue = (double complex *)malloc(queue_size);
+    streamer->request_queue = (MPI_Request *)malloc(requests_size);
+    streamer->subgrid_queue = (double complex *)malloc(sg_queue_size);
+    streamer->subgrid_locks = (int *)calloc(sizeof(int), streamer->queue_length);
+
+    // Plan FFTs
+    streamer->subgrid_plan = fftw_plan_dft_2d(cfg->xM_size, cfg->xM_size,
+                                              streamer->subgrid_queue,
+                                              streamer->subgrid_queue,
+                                              FFTW_BACKWARD, FFTW_MEASURE);
+
+    // Populate receive queue
+    int iwork;
+    for (iwork = 0; iwork < wcfg->subgrid_max_work && iwork < streamer->queue_length; iwork++) {
+        streamer_ireceive(streamer, iwork);
+    }
+
+    // Allocate visibility queue
+    struct vis_spec *const spec = &streamer->work_cfg->spec;
+    const int vis_data_size = sizeof(double complex) * spec->time_chunk * spec->freq_chunk;
+    streamer->vis_queue_length = 1024;
+    streamer->vis_queue = malloc(streamer->vis_queue_length * vis_data_size);
+    streamer->vis_a1 = malloc(streamer->vis_queue_length * sizeof(int));
+    streamer->vis_a2 = malloc(streamer->vis_queue_length * sizeof(int));
+    streamer->vis_tchunk = malloc(streamer->vis_queue_length * sizeof(int));
+    streamer->vis_fchunk = malloc(streamer->vis_queue_length * sizeof(int));
+    streamer->vis_in_lock = malloc(streamer->vis_queue_length * sizeof(omp_lock_t));
+    streamer->vis_out_lock = malloc(streamer->vis_queue_length * sizeof(omp_lock_t));
+    streamer->vis_in_ptr = streamer->vis_out_ptr = 0;
+
+    int i;
+    for (i = 0; i < streamer->vis_queue_length; i++) {
+        omp_init_lock(streamer->vis_in_lock + i);
+        omp_init_lock(streamer->vis_out_lock + i);
+        omp_set_lock(streamer->vis_out_lock + i);
+    }
+
+    return true;
+}
+
+void streamer(struct work_config *wcfg, int subgrid_worker, int *producer_ranks)
+{
+
+    struct streamer streamer;
+    if (!streamer_init(&streamer, wcfg, subgrid_worker, producer_ranks)) {
+        return;
+    }
+
+    struct subgrid_work *work = wcfg->subgrid_work + subgrid_worker * wcfg->subgrid_max_work;
+    const int facets = wcfg->facet_workers * wcfg->facet_max_work;
+    const int nmbf_length = wcfg->recombine.NMBF_NMBF_size / sizeof(double complex);
+
+    MPI_Status *status_queue = (MPI_Status *)
+        malloc(sizeof(MPI_Status) * facets * streamer.queue_length);

     // Work that has been done. This is needed because for split
     // subgrids, multiple work entries might correspond to just a
     // single subgrid getting transferred.
     char *done_work = calloc(sizeof(char), wcfg->subgrid_max_work);

-    // Start receive queue
+    printf("Waiting for data...\n");
+    double stream_start = get_time_ns();
+
+    // Start doing work
+    int num_workers = 0;
+#pragma omp parallel sections
+    {
+#pragma omp section
+    if(streamer.vis_group >= 0)
+        streamer_writer(&streamer);
+
+#pragma omp section
+    {
+    num_workers = omp_get_num_threads();
+
     int iwork;
-    for (iwork = 0; iwork < wcfg->subgrid_max_work && iwork < recv_queue_depth; iwork++) {
-        streamer_ireceive(wcfg,
-                          NMBF_NMBF_queue + iwork * facets * data_length,
-                          request_queue + iwork * facets,
-                          subgrid_worker, iwork, producer_ranks);
-    }
-
-    printf("Waiting for data...\n");
-
-    // Plan FFTs
-    double complex *subgrid = (double complex *)malloc(cfg->SG_size);
-    fftw_plan subgrid_plan = fftw_plan_dft_2d(cfg->xM_size, cfg->xM_size,
-                                              subgrid, subgrid, FFTW_BACKWARD, FFTW_MEASURE);
-
-    // Start doing work
-    uint64_t received_data = 0; int received_subgrids = 0;
     for (iwork = 0; iwork < wcfg->subgrid_max_work; iwork++) {
-        int work_slot = iwork % recv_queue_depth;
-        double complex *data_slot = NMBF_NMBF_queue + work_slot * facets * data_length;
-        MPI_Request *request_slot = request_queue + work_slot * facets;
+        int work_slot = iwork % streamer.queue_length;
+        double complex *data_slot = streamer.nmbf_queue + work_slot * facets * nmbf_length;

         if (work[iwork].nbl && !done_work[iwork]) {

+            double start = get_time_ns();
             // Wait for all facet data for this work to arrive (TODO:
             // start doing some work earlier)
-            MPI_Waitall(facets, request_queue + facets * work_slot,
+            MPI_Waitall(facets, streamer.request_queue + facets * work_slot,
                         status_queue + facets * work_slot);
-            memset(request_queue + facets * work_slot, MPI_REQUEST_NULL, sizeof(MPI_Request) * facets);
-            received_data += sizeof(double complex) * facets * data_length;
-            received_subgrids++;
+            memset(streamer.request_queue + facets * work_slot, MPI_REQUEST_NULL, sizeof(MPI_Request) * facets);
+            streamer.received_data += sizeof(double complex) * facets * nmbf_length;
+            streamer.received_subgrids++;
+            streamer.wait_time += get_time_ns() - start;
         }

         // Do work on received data
-        streamer_work(wcfg, have_kern ? &kern : NULL, vis_group,
-                      subgrid_worker, iwork, data_slot, subgrid, subgrid_plan);
+        streamer_work(&streamer, iwork, data_slot);

         // Mark work done
         int iw;
@@ -387,20 +644,54 @@
                 done_work[iw] = true;

         // Set up slot for new data (if appropriate)
-        int iwork_r = iwork + recv_queue_depth;
+        int iwork_r = iwork + streamer.queue_length;
         if (iwork_r < wcfg->subgrid_max_work && work[iwork_r].nbl && !done_work[iwork_r]) {
-            streamer_ireceive(wcfg, data_slot, request_slot, subgrid_worker, iwork_r, producer_ranks);
-        }
-
-    }
-
-    free(NMBF_NMBF_queue); free(request_queue); free(status_queue); free(done_work);
-    fftw_free(subgrid_plan); free(subgrid);
-
-    if (vis_group >= 0) {
-        H5Gclose(vis_group); H5Fclose(vis_file);
-    }
-
-    printf("Received %.2f GB (%d subgrids)\n",
-           (double)received_data / 1000000000, received_subgrids);
-}
+            streamer_ireceive(&streamer, iwork_r);
+        }
+
+    }
+
+    #pragma omp taskwait
+
+    // Signal writer task to exit
+    omp_set_lock(streamer.vis_in_lock + streamer.vis_in_ptr);
+    streamer.vis_tchunk[streamer.vis_in_ptr] = -1;
+    streamer.vis_fchunk[streamer.vis_in_ptr] = -1;
+    omp_unset_lock(streamer.vis_out_lock + streamer.vis_in_ptr);
+
+    }
+    }
+
+    free(streamer.nmbf_queue); free(streamer.subgrid_queue);
+    free(streamer.request_queue); free(status_queue); free(done_work);
+    fftw_free(streamer.subgrid_plan);
+
+    if (streamer.vis_group >= 0) {
+        H5Gclose(streamer.vis_group); H5Fclose(streamer.vis_file);
+    }
+
+    double stream_time = get_time_ns() - stream_start;
+    printf("Streamed for %.3gs\n", stream_time);
+    printf("Received %.2f GB (%ld subgrids, %ld baselines)\n",
+           (double)streamer.received_data / 1000000000, streamer.received_subgrids,
+           streamer.baselines_covered);
+    printf("Written %.2f GB (rewritten %.2f GB), rate %.2f GB/s (%.2f GB/s effective)\n",
+           (double)streamer.written_vis_data / 1000000000,
+           (double)streamer.rewritten_vis_data / 1000000000,
+           (double)streamer.written_vis_data / 1000000000 / stream_time,
+           (double)(streamer.written_vis_data - streamer.rewritten_vis_data)
+           / 1000000000 / stream_time);
+    printf("Receiver: Wait: %gs, Recombine: %gs, Idle: %gs\n",
+           streamer.wait_time, streamer.recombine_time,
+           stream_time - streamer.wait_time - streamer.recombine_time);
+    printf("Worker: Wait: %gs, Critical: %gs, Degrid: %gs, Idle: %gs\n",
+           streamer.wait_in_time, streamer.critical_wait_time,
+           streamer.degrid_time,
+           (num_workers - 1) * stream_time
+           - streamer.wait_in_time - streamer.critical_wait_time - streamer.degrid_time
+           - streamer.wait_time - streamer.recombine_time);
+    printf("Writer: Wait: %gs, Read: %gs, Write: %gs, Idle: %gs\n",
+           streamer.wait_out_time, streamer.read_time, streamer.write_time,
+           stream_time - streamer.wait_out_time - streamer.read_time - streamer.write_time);
+
+}


More cleanup, generalize apply_va logic

More cleanup, generalize apply_va logic

--- runtime.c
+++ runtime.c
@@ -3230,24 +3230,6 @@
   return_closcall2(data, __glo_call_95cc_scheme_base, cont, car(args));
 }

-void apply_va(void *data, object cont, int argc, object func, ...)
-{
-  object tmp = NULL;
-  int i;
-  va_list ap;
-  va_start(ap, func);
-  for (i = 1; i < argc; i++) {
-    tmp = va_arg(ap, object);
-  }
-  va_end(ap);
-//  fprintf(stdout, "DEBUG applying argc %d, func ", argc);
-//  Cyc_display(func, stdout);
-//  fprintf(stdout, " to values ");
-//  Cyc_display(tmp, stdout);
-//  fprintf(stdout, "\n");
-  apply(data, cont, func, tmp);
-}
-
 // Prepend value to the given list
 #define stack_prepend(lis, value) { \
   pair_type *tmp2 = alloca(sizeof(pair_type)); \
@@ -3265,36 +3247,58 @@
   } \
 }

+// Front-end to apply
+//
+// Core of va processing is done here, because we need different
+// functions for apply_va and dispatch_apply_va, and those functions
+// need to start and end va. BUT, we need to allocate new objects
+// so this stuff can't be returned, so a workaround is to put it in
+// this macro.
+//
+// Fast path is just to take list, if we only have func and 1 arg.
+// Otherwise append all args together into a single list, per r7rs.
+#define do_apply_va \
+  va_start(ap, func); \
+  if (argc == 2) { \
+    lis = va_arg(ap, object); \
+    Cyc_check_pair_or_null(data, lis); \
+  } else { \
+    for (i = 1; i < argc; i++) { \
+      tmp = va_arg(ap, object); \
+      if (tmp == NULL){ \
+        continue; \
+      } else if (is_object_type(tmp) && type_of(tmp) == pair_tag) { \
+        l = tmp; \
+        stack_list_prepend(l, lis); \
+      } else { \
+        stack_prepend(lis, tmp); \
+      } \
+    } \
+    l = lis; \
+    lis = NULL; \
+    stack_list_prepend(l, lis); \
+  } \
+  va_end(ap);
+
 void dispatch_apply_va(void *data, int argc, object clo, object cont, object func, ...)
 {
-  list lis = NULL, tmp, l;
+  list lis = NULL, l;
+  object tmp;
   int i;
   va_list ap;
   argc = argc - 1; // Required for "dispatch" function
-  va_start(ap, func);
-  if (argc == 2) {
-    // Fast path, nothing to append
-    lis = va_arg(ap, object);
-    Cyc_check_pair_or_null(data, lis);
-  } else {
-    for (i = 1; i < argc; i++) {
-      tmp = va_arg(ap, object);
-      if (tmp == NULL){
-        continue;
-      } else if (is_object_type(tmp) && type_of(tmp) == pair_tag) {
-        l = tmp;
-        stack_list_prepend(l, lis);
-      } else {
-        stack_prepend(lis, tmp);
-      }
-    }
-    // Reverse lis
-    l = lis;
-    lis = NULL;
-    stack_list_prepend(l, lis);
-  }
-  va_end(ap);
+  do_apply_va
   apply(data, cont, func, lis);
+}
+
+void apply_va(void *data, object cont, int argc, object func, ...)
+{
+  list lis = NULL, l;
+  object tmp;
+  int i;
+  va_list ap;
+  do_apply_va
+  apply(data, cont, func, tmp);
 }

 /*


Document the remaining methods on PXSourceListDelegate.

--- PXSourceList/PXSourceListDelegate.h
+++ PXSourceList/PXSourceListDelegate.h
@@ -179,18 +179,107 @@
  @since Requires PXSourceList 2.0.0 or above.
  */
 - (BOOL)sourceList:(PXSourceList *)sourceList shouldTypeSelectForEvent:(NSEvent *)event withCurrentSearchString:(NSString *)searchString;
+
+/**
+ @brief Returns a Boolean value which indicates whether a cell expansion tooltip should be displayed for a given item.
+ @discussion This method is analagous to `-outlineView:shouldShowCellExpansionForItem:` declared on `NSOutlineViewDelegate`, although it doesn't pass an `NSTableColumn` parameter as `PXSourceList` implicitly only uses one table column. See the documentation for `-outlineView:shouldShowCellExpansionForItem:` for more information.
+
+ @param sourceList The Source List that sent the message.
+ @param item An item in the data source.
+
+ @return `YES` to allow an expansion tooltip to be displayed for *item*, otherwise `NO`.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (BOOL)sourceList:(PXSourceList *)sourceList shouldShowCellExpansionForItem:(id)item;

+/**
+ @brief Returns a Boolean value which indicates whether the Source List should allow editing of a given item.
+ @discussion This method is analagous to `-outlineView:shouldEditTableColumn:item:` declared on `NSOutlineViewDelegate`, although it doesn't pass an `NSTableColumn` parameter as `PXSourceList` implicitly only uses one table column. See the documentation for `-outlineView:shouldEditTableColumn:item:` for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param item An item in the data source.
+
+ @return `YES` to allow editing of *item*, or `NO` otherwise.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (BOOL)sourceList:(PXSourceList*)aSourceList shouldEditItem:(id)item;

+/**
+ @brief Returns a Boolean value that indicates whether a given cell should be tracked
+ @discussion This method is analagous to `-outlineView:shouldTrackCell:forTableColumn:item:` declared on `NSOutlineViewDelegate`, although it doesn't pass an `NSTableColumn` parameter as `PXSourceList` implicitly only uses one table column. See the documentation for `-outlineView:shouldTrackCell:forTableColumn:item:` for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param cell The cell used to display *item*
+ @param item An item in the data source
+
+ @return `YES` if the cell should be tracked for *item*, otherwise `NO`.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (BOOL)sourceList:(PXSourceList*)aSourceList shouldTrackCell:(NSCell *)cell forItem:(id)item;

+/**
+ @brief Returns a Boolean value that indicates whether a given item should be expanded.
+ @discussion This method is analagous to `-outlineView:shouldExpandItem:` declared on `NSOutlineViewDelegate`. See the documentation for this method for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param item An item in the data source
+
+ @return `YES` to allow expansion of *item*, otherwise `NO`.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (BOOL)sourceList:(PXSourceList*)aSourceList shouldExpandItem:(id)item;
+
+/**
+ @brief Returns a Boolean value that indicates whether a given item should be collapsed.
+ @discussion This method is analagous to `-outlineView:shouldCollapseItem:` declared on `NSOutlineViewDelegate`. See the documentation for this method for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param item An item in the data source
+
+ @return `YES` to allow *item* to be collapsed, otherwise `NO`.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (BOOL)sourceList:(PXSourceList*)aSourceList shouldCollapseItem:(id)item;

+/**
+ @brief Returns the height in points of the row for the given item.
+ @discussion This method is analagous to `-outlineView:heightOfRowByItem:` declared on `NSOutlineViewDelegate`. See the documentation for this method for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param item An item in the data source
+
+ @return The height of the row used to display *item* in points.
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (CGFloat)sourceList:(PXSourceList*)aSourceList heightOfRowByItem:(id)item;

+/**
+ @brief Informs the delegate that the Source List is about to display the cell associated with the given item.
+ @discussion This method is analagous to `-outlineView:willDisplayCell:forTableColumn:item:` declared on `NSOutlineViewDelegate`, although it doesn't pass an `NSTableColumn` parameter as `PXSourceList` implicitly only uses one table column. See the documentation for `-outlineView:willDisplayCell:forTableColumn:item:` for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param cell The cell about to be displayed
+ @param item An item in the data source
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (NSCell*)sourceList:(PXSourceList*)aSourceList willDisplayCell:(id)cell forItem:(id)item;
+
+/**
+ @brief Returns the cell for use with a given item in the Source List.
+ @discussion This method is analagous to `-outlineView:dataCellForTableColumn:item:` declared on `NSOutlineViewDelegate`, although it doesn't pass an `NSTableColumn` parameter as `PXSourceList` implicitly only uses one table column. See the documentation for `-outlineView:dataCellForTableColumn:item:` for more information.
+
+ @param aSourceList The Source List that sent the message.
+ @param item An item in the data source
+
+ @since Requires PXSourceList 0.8 or above.
+ */
 - (NSCell*)sourceList:(PXSourceList*)aSourceList dataCellForItem:(id)item;

 @end


Fix MSVC warnings C4204 and C4244.

Fix MSVC warnings C4204 and C4244.

warning C4204: nonstandard extension used: non-constant aggregate
initializer
warning C4244: 'initializing': conversion from 'int32_t' to 'int16_t',
possible loss of data

Avoiding designated initializers also restores C++ compatibility.

--- ryu/d2s.c
+++ ryu/d2s.c
@@ -545,10 +545,9 @@
 #endif

   // Step 5: Print the decimal representation.
-  struct floating_decimal_64 fd = {
-    .exponent = exp,
-    .mantissa = sign ? -(int64_t) output : output
-  };
+  struct floating_decimal_64 fd;
+  fd.exponent = (int16_t) exp;
+  fd.mantissa = sign ? -(int64_t) output : output;
   return fd_to_char(fd, result);
 }


Comments: Change "x86-64" to "x64".

Comments: Change "x86-64" to "x64".

I consider this to be more readable and less confusing.
Also, d2s_intrinsics.h already says "x64".

--- ryu/d2s.c
+++ ryu/d2s.c
@@ -102,10 +102,10 @@
 //    We explicitly cast from 64-bit to 128-bit, so the compiler can tell
 //    that these are only 64-bit inputs, and can map these to the best
 //    possible sequence of assembly instructions.
-//    x86-64 machines happen to have matching assembly instructions for
+//    x64 machines happen to have matching assembly instructions for
 //    64x64-bit multiplications and 128-bit shifts.
 //
-// 2. Second best case: the compiler exposes intrinsics for the x86-64 assembly
+// 2. Second best case: the compiler exposes intrinsics for the x64 assembly
 //    instructions mentioned in 1.
 //
 // 3. We only have 64x64 bit instructions that return the lower 64 bits of


Add hardened_byte_bool_t for CREATOR_SW_CFG_KEY_IS_VALID entries.

Signed-off-by: Alphan Ulusoy <23b245cc5a07aacf75a9db847b24c67dee1707bf@google.com>

--- sw/device/lib/base/hardened.h
+++ sw/device/lib/base/hardened.h
@@ -32,4 +32,24 @@
   kHardenedBoolFalse = 0x1d4u,
 } hardened_bool_t;

+/**
+ * A byte-sized hardened boolean.
+ *
+ * This type is intended for cases where a byte-sized hardened boolean is
+ * required, e.g. for the entries of the `CREATOR_SW_CFG_KEY_IS_VALID` OTP item.
+ *
+ * The values below were chosen to ensure that the hamming difference between
+ * them is greater than 5 and they are not bitwise complements of each other.
+ */
+typedef enum hardened_byte_bool {
+  /**
+   * The truthy value.
+   */
+  kHardenedByteBoolTrue = 0xa5,
+  /**
+   * The falsy value.
+   */
+  kHardenedByteBoolFalse = 0x4b,
+} hardened_byte_bool_t;
+
 #endif  // OPENTITAN_SW_DEVICE_LIB_BASE_HARDENED_H_


04-chains-bpf: implement multiple argument chains

This is just and extention of test #3 where we also check the buffer and the
size of reads and writes.

Signed-off-by: Eric Paris <b0b36e3cd9ea4e5739ff430a3056fabf2fdb0376@redhat.com>
Signed-off-by: Paul Moore <88a1d58bf22a647dce58dd91f9595600dceabba9@redhat.com>

--- tests/04-chains-bpf.c
+++ tests/04-chains-bpf.c
@@ -42,23 +42,31 @@
 	if (rc != 0)
 		return rc;

-	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(read), 2,
-				 0, SCMP_CMP_EQ, 0, /* stdin */
-				 1, SCMP_CMP_NE, NULL);
-	if (rc != 0)
-		return rc;
-	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(read), 2,
-				 0, SCMP_CMP_EQ, 0, /* stdin */
-				 2, SCMP_CMP_GT, SSIZE_MAX);
+	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
+				 0, SCMP_CMP_EQ, STDIN_FILENO,
+				 1, SCMP_CMP_NE, NULL,
+				 2, SCMP_CMP_LT, SSIZE_MAX);
 	if (rc != 0)
 		return rc;

 	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
-				 0, SCMP_CMP_EQ, 1 /* stdout */);
+				 0, SCMP_CMP_EQ, STDOUT_FILENO,
+				 1, SCMP_CMP_NE, NULL,
+				 2, SCMP_CMP_LT, SSIZE_MAX);
 	if (rc != 0)
 		return rc;
 	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
-				 0, SCMP_CMP_EQ, 2 /* stderr */);
+				 0, SCMP_CMP_EQ, STDERR_FILENO,
+				 1, SCMP_CMP_NE, NULL,
+				 2, SCMP_CMP_LT, SSIZE_MAX);
+	if (rc != 0)
+		return rc;
+
+	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
+	if (rc != 0)
+		return rc;
+
+	rc = seccomp_add_syscall(SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
 	if (rc != 0)
 		return rc;


update

update

--- HLSocial/Header/UMSocialDataService.h
+++ HLSocial/Header/UMSocialDataService.h
@@ -7,6 +7,7 @@
 //
 #import <Foundation/Foundation.h>
 #import "UMSocialData.h"
+#import <CoreLocation/CoreLocation.h>

 /**
  网络请求结果状态码


lwip: tcp_rexmit_rto: Remove superfluous #if TCP_OVERSIZE guard

Upstream commit: a93ae2558f97b32917599591ecfec949e58372a9

--- lwip/src/core/tcp_out.c
+++ lwip/src/core/tcp_out.c
@@ -1414,12 +1414,12 @@
   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
   /* concatenate unsent queue after unacked queue */
   seg->next = pcb->unsent;
-#if TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK
+#if TCP_OVERSIZE_DBGCHECK
   /* if last unsent changed, we need to update unsent_oversize */
   if (pcb->unsent == NULL) {
     pcb->unsent_oversize = seg->oversize_left;
   }
-#endif /* TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK*/
+#endif /* TCP_OVERSIZE_DBGCHECK */
   /* unsent queue is the concatenated queue (of unacked, unsent) */
   pcb->unsent = pcb->unacked;
   /* unacked queue is now empty */


Optimize, don't redraw the scale too often

--- champlain/champlain-view.c
+++ champlain/champlain-view.c
@@ -1101,6 +1101,8 @@
 static void
 update_scale (ChamplainView *view)
 {
+  static gfloat previous_m_per_pixel = 0.0;
+
   gboolean is_small_unit = TRUE;  /* indicates if using meters */
   ClutterActor *text, *line;
   gfloat width;
@@ -1113,7 +1115,7 @@
   gfloat factor;
   gboolean final_unit = FALSE;

-  if (!priv || !priv->map || !priv->map->current_level)
+  if (!priv->map || !priv->map->current_level)
     return;

   if (priv->show_scale)
@@ -1128,6 +1130,12 @@

   m_per_pixel = champlain_map_source_get_meters_per_pixel (priv->map_source,
       priv->zoom_level, priv->latitude, priv->longitude);
+
+  /* Don't redraw too often */
+  if (fabs (m_per_pixel - previous_m_per_pixel) < 0.01)
+    return;
+
+  previous_m_per_pixel = m_per_pixel;

   if (priv->scale_unit == CHAMPLAIN_UNIT_MILES)
     m_per_pixel *= 3.28; /* m_per_pixel is now in ft */


use base2 for readahead-hit

use base2 for readahead-hit

--- mount_slash/io.c
+++ mount_slash/io.c
@@ -1326,7 +1326,7 @@
 	    tsd.tv_sec * 1000000 + tsd.tv_nsec / 1000);

 	if (rc == 0 && perfect_ra)
-		OPSTAT_ADD("readahead-hit", r->biorq_len);
+		OPSTAT2_ADD("readahead-hit", r->biorq_len);

  out:
 	DEBUG_BIORQ(PLL_DIAG, r, "aio=%d rc=%d", aiowait, rc);


Removed unused static function.

Removed unused static function.

--- runtime.c
+++ runtime.c
@@ -846,17 +846,6 @@

 }

-static id objectNew(id cls)
-{
-	static SEL newSel = NULL;
-	if (NULL == newSel)
-	{
-		newSel = sel_get_uid("new");
-	}
-	IMP newIMP = (IMP)objc_msg_lookup((void*)cls, newSel);
-	return newIMP((id)cls, newSel);
-}
-
 const char *sel_getName(SEL sel)
 {
 	return sel_get_name(sel);


Always check whether to wrap when viewport moved

Because viewport is repositioned when wrapped, the x - priv->viewport_x
may be less than 100 even when the viewport moved more. The check for wrap
should be cheap enough to be performed every time the function is called.

--- champlain/champlain-view.c
+++ champlain/champlain-view.c
@@ -1344,7 +1344,7 @@

   champlain_viewport_get_origin (CHAMPLAIN_VIEWPORT (priv->viewport), &x, &y);

-  if (ABS (x - priv->viewport_x) > 100 || ABS (y - priv->viewport_y) > 100)
+  if (priv->hwrap)
     {
       gint size, cols, map_width;

@@ -1352,12 +1352,15 @@
       cols = champlain_map_source_get_column_count (priv->map_source,
                                                     priv->zoom_level);
       map_width = size * cols;
-
+
       /* Faux wrapping, by positioning viewport to correct wrap point */
-      if (priv->hwrap && (x < 0 || x >= map_width))
+      if (x < 0 || x >= map_width)
         position_viewport (view, x_to_wrap_x (x, map_width), y);
-      else
-        update_coords (view, x, y, FALSE);
+    }
+
+  if (ABS (x - priv->viewport_x) > 100 || ABS (y - priv->viewport_y) > 100)
+    {
+      update_coords (view, x, y, FALSE);

       load_visible_tiles (view, FALSE);
       priv->location_updated = TRUE;


uut: drain EC console before programming

Cr50 doesn't handle the uart break conditions properly, so it will fill
up the EC uart with zeros when ECTX_CR50RX stays asserted. We assert
that signal to start uut programming, so the buffer is almost guaranteed
to be filled with garbage when uut programming starts. We were seeing
synchronization fail because the baudrate check would read a zero from
the buffer instead of the expected output. This change completely drains
the EC console before starting uut to get rid of the garbage that
interferes with programming.

stm32mon does the exact same thing. We should create common code for
initializing serial devices.

BUG=b:123775217
BRANCH=none
TEST=program cheza using ccd uut

Change-Id: I2df562a5b4513ada528e887e057e78a8f1f3054c
Signed-off-by: Mary Ruthven <81380f3403fed74252e92df3ed012a1819ec6296@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1457579
Commit-Ready: ChromeOS CL Exonerator Bot <fa429e5907f00867f797423aea74327bb02c91b6@appspot.gserviceaccount.com>
Tested-by: Mary Ruthven <81380f3403fed74252e92df3ed012a1819ec6296@chromium.org>
Reviewed-by: Vadim Bendebury <5515d6d2d0829cbe0dd0dcf2094aaded06d58514@chromium.org>

--- util/uut/l_com_port.c
+++ util/uut/l_com_port.c
@@ -200,6 +200,57 @@
 	return true;
 }

+/**
+ * Drain the console RX buffer before programming. The device should be in
+ * programming mode and shouldn't be printing anything. Anything that's
+ * currently in the buffer could interfere with programming. discard_input
+ * will discard everything currently in the buffer. It prints any non zero
+ * characters and returns when the console is empty and ready for programming.
+ *
+ * This is the same as discard_input in stm32mon.
+ * TODO: create common library for initializing serial consoles.
+ */
+static void discard_input(int fd)
+{
+	uint8_t buffer[64];
+	int res, i;
+	int count_of_zeros;
+
+	/* Keep track of discarded zeros */
+	count_of_zeros = 0;
+	do {
+		res = read(fd, buffer, sizeof(buffer));
+		if (res > 0) {
+
+			/* Discard zeros in the beginning of the buffer. */
+			for (i = 0; i < res; i++)
+				if (buffer[i])
+					break;
+
+			count_of_zeros += i;
+			if (i == res) {
+				/* Only zeros, nothing to print out. */
+				continue;
+			}
+
+			/* Discard zeros in the end of the buffer. */
+			while (!buffer[res - 1]) {
+				count_of_zeros++;
+				res--;
+			}
+
+			printf("Recv[%d]:", res - i);
+			for (; i < res; i++)
+				printf("%02x ", buffer[i]);
+			printf("\n");
+		}
+	} while (res > 0);
+
+	if (count_of_zeros)
+		printf("%d zeros ignored\n", count_of_zeros);
+}
+
+
 /******************************************************************************
  * Function: int com_port_open()
  *
@@ -240,6 +291,12 @@
 		close(port_handler);
 		return INVALID_HANDLE_VALUE;
 	}
+
+	/*
+	 * Drain the console, so what ever is already in the EC console wont
+	 * interfere with programming.
+	 */
+	discard_input(port_handler);

 	return port_handler;
 }


lower psclog level

lower psclog level

--- mount_slash/io.c
+++ mount_slash/io.c
@@ -770,8 +770,9 @@
 	}

 	/* AIOWAIT is removed no matter what. */
-	e->bmpce_flags &= ~(BMPCEF_AIOWAIT | BMPCEF_FAULTING | BMPCEF_PINNED);
-	DEBUG_BMPCE(PLL_DIAG, e, "rpc_done");
+	e->bmpce_flags &= ~(BMPCEF_AIOWAIT | BMPCEF_FAULTING |
+	    BMPCEF_PINNED);
+	DEBUG_BMPCE(PLL_DEBUG, e, "rpc_done");

 	BMPCE_WAKE(e);
 	BMPCE_ULOCK(e);


Make q unsigned, move pow-of-2 check, part 2.

This ports commits 87d807b and fab5f9d from d2s.c to f2s.c,
also fixing signedness warnings.

--- ryu/f2s.c
+++ ryu/f2s.c
@@ -65,8 +65,8 @@
  1292469707114105741u, 1615587133892632177u, 2019483917365790221u
 };

-static inline int32_t pow5Factor(uint32_t value) {
-  for (int32_t count = 0; value > 0; ++count) {
+static inline uint32_t pow5Factor(uint32_t value) {
+  for (uint32_t count = 0; value > 0; ++count) {
     if (value % 5 != 0) {
       return count;
     }
@@ -76,8 +76,14 @@
 }

 // Returns true if value is divisible by 5^p.
-static inline bool multipleOfPowerOf5(const uint32_t value, const int32_t p) {
+static inline bool multipleOfPowerOf5(const uint32_t value, const uint32_t p) {
   return pow5Factor(value) >= p;
+}
+
+// Returns true if value is divisible by 2^p.
+static inline bool multipleOfPowerOf2(const uint32_t value, const uint32_t p) {
+  // return __builtin_ctz(value) >= p;
+  return (value & ((1u << p) - 1)) == 0;
 }

 // It seems to be slightly faster to avoid uint128_t here, although the
@@ -173,7 +179,7 @@
   bool vrIsTrailingZeros = false;
   uint8_t lastRemovedDigit = 0;
   if (e2 >= 0) {
-    const int32_t q = log10Pow2(e2);
+    const uint32_t q = log10Pow2(e2);
     e10 = q;
     const int32_t k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1;
     const int32_t i = -e2 + q + k;
@@ -181,7 +187,7 @@
     vp = mulPow5InvDivPow2(mp, q, i);
     vm = mulPow5InvDivPow2(mm, q, i);
 #ifdef RYU_DEBUG
-    printf("%u * 2^%d / 10^%d\n", mv, e2, q);
+    printf("%u * 2^%d / 10^%u\n", mv, e2, q);
     printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
 #endif
     if (q != 0 && ((vp - 1) / 10 <= vm / 10)) {
@@ -203,7 +209,7 @@
       }
     }
   } else {
-    const int32_t q = log10Pow5(-e2);
+    const uint32_t q = log10Pow5(-e2);
     e10 = q + e2;
     const int32_t i = -e2 - q;
     const int32_t k = pow5bits(i) - FLOAT_POW5_BITCOUNT;
@@ -212,8 +218,8 @@
     vp = mulPow5divPow2(mp, i, j);
     vm = mulPow5divPow2(mm, i, j);
 #ifdef RYU_DEBUG
-    printf("%u * 5^%d / 10^%d\n", mv, -e2, q);
-    printf("%d %d %d %d\n", q, i, k, j);
+    printf("%u * 5^%d / 10^%u\n", mv, -e2, q);
+    printf("%u %d %d %d\n", q, i, k, j);
     printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
 #endif
     if (q != 0 && ((vp - 1) / 10 <= vm / 10)) {
@@ -232,7 +238,7 @@
         --vp;
       }
     } else if (q < 31) { // TODO(ulfjack): Use a tighter bound here.
-      vrIsTrailingZeros = (mv & ((1u << (q - 1)) - 1)) == 0;
+      vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1);
 #ifdef RYU_DEBUG
       printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
 #endif


MOD: (SAMPLES) removal of unnecessary macro

--HG--
branch : samples-framework-devel

--- samples/common/include/SampleBase.h
+++ samples/common/include/SampleBase.h
@@ -38,8 +38,4 @@
 #   define SAMPLE_EXPORT
 #endif

-#define ADD_SAMPLE(instance, name, summary, description, type, credits) \
-    class SamplesFramework; \
-	SamplesFramework::framework->addSampleDataCppModule(instance, name, summary, description, sampleTypeEnum, credits)
-
 #endif


normalize: don't output "" on error

normalize: don't output "" on error

--- lib/proc.c
+++ lib/proc.c
@@ -1088,7 +1088,6 @@
   flag_names = VAR(2);
   if (GRN_TEXT_LEN(normalizer_name) == 0) {
     ERR(GRN_INVALID_ARGUMENT, "normalizer name is missing");
-    GRN_OUTPUT_CSTR("");
     return NULL;
   }

@@ -1108,7 +1107,6 @@
           "[normalize] nonexistent normalizer: <%.*s>",
           (int)GRN_TEXT_LEN(normalizer_name),
           GRN_TEXT_VALUE(normalizer_name));
-      GRN_OUTPUT_CSTR("");
       return NULL;
     }

@@ -1121,7 +1119,6 @@
           (int)GRN_TEXT_LEN(&inspected),
           GRN_TEXT_VALUE(&inspected));
       GRN_OBJ_FIN(ctx, &inspected);
-      GRN_OUTPUT_CSTR("");
       grn_obj_unlink(ctx, normalizer);
       return NULL;
     }


registry.c: Remove DBusConnection argument from remaining impl_ methods

Since the registry always goes through the dbus daemon, we do not need
to keep track of multiple connections.

--- registryd/registry.c
+++ registryd/registry.c
@@ -414,7 +414,7 @@
 /*---------------------------------------------------------------------------*/

 static DBusMessage*
-impl_Embed (DBusConnection *bus, DBusMessage *message, void *user_data)
+impl_Embed (DBusMessage *message, void *user_data)
 {
   SpiRegistry *reg = SPI_REGISTRY (user_data);
   DBusMessageIter iter, iter_struct;
@@ -436,9 +436,9 @@
 	goto error;
   dbus_message_iter_get_basic (&iter_struct, &obj_path);

-  add_application(reg, bus, app_name, obj_path);
-
-  set_id (reg, bus, app_name, obj_path);
+  add_application(reg, reg->bus, app_name, obj_path);
+
+  set_id (reg, reg->bus, app_name, obj_path);

   reply = dbus_message_new_method_return (message);
   dbus_message_iter_init_append (reply, &reply_iter);
@@ -452,7 +452,7 @@
 }

 static DBusMessage*
-impl_Unembed (DBusConnection *bus, DBusMessage *message, void *user_data)
+impl_Unembed (DBusMessage *message, void *user_data)
 {
   SpiRegistry *reg = SPI_REGISTRY (user_data);
   DBusMessageIter iter, iter_struct;
@@ -471,7 +471,7 @@
   dbus_message_iter_get_basic (&iter_struct, &obj_path);

   if (find_index_of_reference (reg->apps, app_name, obj_path, &index))
-      remove_application(reg, bus, index);
+    remove_application (reg, reg->bus, index);

   return NULL;
 error:
@@ -494,8 +494,7 @@
 }

 static DBusMessage *
-impl_GetAccessibleAtPoint (DBusConnection * bus, DBusMessage * message,
-                           void *user_data)
+impl_GetAccessibleAtPoint (DBusMessage * message, void *user_data)
 {
   SpiRegistry *reg = SPI_REGISTRY (user_data);
   DBusMessage *reply = NULL;
@@ -814,8 +813,7 @@
 }

 static DBusMessage *
-impl_GetApplication (DBusConnection * bus,
-                     DBusMessage * message, void *user_data)
+impl_GetApplication (DBusMessage * message, void *user_data)
 {
   SpiRegistry *reg = SPI_REGISTRY (user_data);
   DBusMessage *reply = NULL;
@@ -871,7 +869,7 @@
  * a method call and signal for now.
  */
 static DBusMessage *
-impl_register_event (DBusConnection *bus, DBusMessage *message, void *user_data)
+impl_register_event (DBusMessage *message, void *user_data)
 {
   SpiRegistry *registry = SPI_REGISTRY (user_data);
   const char *orig_name;
@@ -949,7 +947,7 @@
       ls = g_slist_next (ls);
     }
     dbus_message_iter_close_container (&iter, &iter_array);
-    dbus_connection_send (bus, signal, NULL);
+    dbus_connection_send (registry->bus, signal, NULL);
     dbus_message_unref (signal);
   }

@@ -1203,7 +1201,7 @@
       else if (!strcmp (member, "GetAttributes"))
           reply = impl_GetAttributes (message, user_data);
       else if (!strcmp (member, "GetApplication"))
-          reply = impl_GetApplication (bus, message, user_data);
+          reply = impl_GetApplication (message, user_data);
       else if (!strcmp (member, "GetInterfaces"))
           reply = impl_GetInterfaces (message, user_data);
       else
@@ -1216,7 +1214,7 @@
       if      (!strcmp (member, "Contains"))
           reply = impl_Contains (message, user_data);
       else if (!strcmp (member, "GetAccessibleAtPoint"))
-          reply = impl_GetAccessibleAtPoint (bus, message, user_data);
+          reply = impl_GetAccessibleAtPoint (message, user_data);
       else if (!strcmp (member, "GetExtents"))
           reply = impl_GetExtents (message, user_data);
       else if (!strcmp (member, "GetPosition"))
@@ -1239,9 +1237,9 @@
     {
       result = DBUS_HANDLER_RESULT_HANDLED;
       if      (!strcmp (member, "Embed"))
-          reply = impl_Embed (bus, message, user_data);
+          reply = impl_Embed (message, user_data);
       else if (!strcmp (member, "Unembed"))
-          reply = impl_Unembed (bus, message, user_data);
+          reply = impl_Unembed (message, user_data);
       else
           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
@@ -1335,7 +1333,7 @@
     {
       result = DBUS_HANDLER_RESULT_HANDLED;
       if (!strcmp(member, "RegisterEvent"))
-      reply = impl_register_event (bus, message, user_data);
+      reply = impl_register_event (message, user_data);
       else if (!strcmp(member, "DeregisterEvent"))
         reply = impl_deregister_event (message, user_data);
       else if (!strcmp(member, "GetRegisteredEvents"))


unsupported ioctl's should be returned with ENOTTY
not -1;

ok miod@


bpf_sim: use fopen()/fread()/fclose()

bpf_sim: use fopen()/fread()/fclose()

Also do some minor cleanup and typo correction while we are here.

Signed-off-by: Paul Moore <88a1d58bf22a647dce58dd91f9595600dceabba9@redhat.com>

--- tools/bpf_sim.c
+++ tools/bpf_sim.c
@@ -59,7 +59,7 @@
 static void exit_usage(const char *program)
 {
 	fprintf(stderr, "usage: %s [-m {32,64}] -f <bpf_file> [-v]"
-			" -s <syscall_num> [-0 <a0>] ... [-5 <a5>]",
+			" -s <syscall_num> [-0 <a0>] ... [-5 <a5>]\n",
 			program);
 	exit(EINVAL);
 }
@@ -110,15 +110,15 @@
 static void end_action(uint32_t action, unsigned int line)
 {
 	if (action == 0x00000000)
-		fprintf(stdout, "KILL");
+		fprintf(stdout, "KILL\n");
 	else if (action == 0x00020000)
-		fprintf(stdout, "TRAP");
+		fprintf(stdout, "TRAP\n");
 	else if ((action & 0xffff0000) == 0x00030000)
-		fprintf(stdout, "ERRNO(%u)", (action & 0x0000ffff));
+		fprintf(stdout, "ERRNO(%u)\n", (action & 0x0000ffff));
 	else if ((action & 0xffff0000) == 0x7ff00000)
-		fprintf(stdout, "TRACE(%u)", (action & 0x0000ffff));
+		fprintf(stdout, "TRACE(%u)\n", (action & 0x0000ffff));
 	else if (action == 0x7fff0000)
-		fprintf(stdout, "ALLOW");
+		fprintf(stdout, "ALLOW\n");
 	else
 		exit_error(EDOM, line);
 	exit(0);
@@ -187,10 +187,9 @@
 			end_action(bpf->k, ip_c);
 			break;
 		default:
-			/* XXX - since we don't support the full bpf language
-			 *       just yet, this could be either a fault or
-			 *       and error, we'll treat it as a fault until we
-			 *       provide full bpf support */
+			/* since we don't support the full bpf language just
+			 * yet, this could be either a fault or an error, we'll
+			 * treat it as a fault until we provide full support */
 			exit_fault(EOPNOTSUPP);
 		}
 	}
@@ -205,9 +204,10 @@
 int main(int argc, char *argv[])
 {
 	int opt;
-	int fd, fd_read_len;
 	char *opt_file = NULL;
 	unsigned int opt_arg_flag = 0;
+	FILE *file;
+	size_t file_read_len;
 	struct bpf_syscall_data sys_data;
 	struct bpf_program bpf_prg;

@@ -304,21 +304,20 @@
 		exit_fault(ENOMEM);

 	/* load the bpf program */
-	fd = open(opt_file, 0);
-	if (fd < 0)
+	file = fopen(opt_file, "r");
+	if (file == NULL)
 		exit_fault(errno);
 	do {
-		/* XXX - need to account for partial reads */
-		fd_read_len = read(fd, &(bpf_prg.i[bpf_prg.i_cnt]),
-				   sizeof(*bpf_prg.i));
-		if (fd_read_len == sizeof(*bpf_prg.i))
+		file_read_len = fread(&(bpf_prg.i[bpf_prg.i_cnt]),
+				      sizeof(*bpf_prg.i), 1, file);
+		if (file_read_len == 1)
 			bpf_prg.i_cnt++;

 		/* check the size */
 		if (bpf_prg.i_cnt == BPF_PRG_MAX_LEN)
 			exit_fault(E2BIG);
-	} while (fd_read_len > 0);
-	close(fd);
+	} while (file_read_len > 0);
+	fclose(file);

 	/* execute the bpf program */
 	bpf_execute(&bpf_prg, &sys_data);


dht: don't overwrite the layout after the subvolume expansion

Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>

BUG: 864 (dht self-heal overwrites layout causing 'missing' files.)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=864

--- xlators/cluster/dht/src/dht-selfheal.c
+++ xlators/cluster/dht/src/dht-selfheal.c
@@ -413,7 +413,7 @@
 		ret = 0;
 	}

-	if (holes || missing || overlaps) {
+	if (holes || overlaps) {
 		dht_selfheal_layout_new_directory (frame, loc, layout);
 		ret = 0;
 	}


Fix clone sample

Fix clone sample

--- examples/network/clone.c
+++ examples/network/clone.c
@@ -64,7 +64,7 @@

 int do_clone(git_repository *repo, int argc, char **argv)
 {
-	progress_data pd;
+	progress_data pd = {0};
 	git_repository *cloned_repo = NULL;
 	git_remote *origin;
 	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
@@ -82,27 +82,16 @@
 	}

 	// Set up options
+	clone_opts.checkout_opts = &checkout_opts;
 	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
 	checkout_opts.progress_cb = checkout_progress;
-	memset(&pd, 0, sizeof(pd));
 	checkout_opts.progress_payload = &pd;
-
-	// Create the origin remote, and set up for auth
-	error = git_remote_new(&origin, NULL, "origin", url, GIT_REMOTE_DEFAULT_FETCH);
-	if (error != 0) {
-		const git_error *err = giterr_last();
-		if (err) printf("ERROR %d: %s\n", err->klass, err->message);
-		else printf("ERROR %d: no detailed info\n", error);
-		return error;
-	}
-	git_remote_set_cred_acquire_cb(origin, cred_acquire, NULL);
+	clone_opts.fetch_progress_cb = &fetch_progress;
+	clone_opts.fetch_progress_payload = &pd;
+	clone_opts.cred_acquire_cb = cred_acquire;

 	// Do the clone
-	clone_opts.checkout_opts = &checkout_opts;
-	clone_opts.fetch_progress_cb = &fetch_progress;
-	clone_opts.fetch_progress_payload = &pd;
-	error = git_clone(&cloned_repo, origin, path, &clone_opts);
-	git_remote_free(origin);
+	error = git_clone(&cloned_repo, url, path, &clone_opts);
 	printf("\n");
 	if (error != 0) {
 		const git_error *err = giterr_last();


Remove one more compiler warning

Remove one more compiler warning

This commit was SVN r1201.

--- utils/hwloc-distrib.c
+++ utils/hwloc-distrib.c
@@ -26,7 +26,7 @@
 {
   long n = -1;
   char * synthetic = NULL;
-  char * xmlpath = NULL;
+  const char * xmlpath = NULL;
   int verbose = 0;
   char **orig_argv = argv;


Fixed bi bug when using wildcards

Fixed bi bug when using wildcards

--- src/olsr_switch/ohs_cmd.c
+++ src/olsr_switch/ohs_cmd.c
@@ -37,7 +37,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: ohs_cmd.c,v 1.13 2005/06/01 18:53:29 kattemat Exp $
+ * $Id: ohs_cmd.c,v 1.14 2005/06/02 19:06:24 kattemat Exp $
  */

 #include "olsr_host_switch.h"
@@ -177,7 +177,7 @@
     goto print_usage;

   /* No use for bi if both src and dst are widcards */
-  if(wildc_dst && wildc_dst)
+  if(wildc_src && wildc_dst)
     {
       bi = 0;
     }


batman-adv: make batadv_tt_save_orig_buffer() generic

This is a simple batadv_tt_save_orig_buffer() refactoring
aiming to make it more generic and avoid useless casts.

Signed-off-by: Antonio Quartulli <a08f08bac39aeae6c9580ade7aa8387b5a0e7428@open-mesh.com>
Signed-off-by: Marek Lindner <104240d543ffdbcddd3f116d866dc6166bffcd7a@yahoo.de>

--- net/batman-adv/translation-table.c
+++ net/batman-adv/translation-table.c
@@ -1496,11 +1496,9 @@

 static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
 				       struct batadv_orig_node *orig_node,
-				       const unsigned char *tt_buff,
-				       uint16_t tt_num_changes)
-{
-	uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
-
+				       const void *tt_buff,
+				       uint16_t tt_buff_len)
+{
 	/* Replace the old buffer only if I received something in the
 	 * last OGM (the OGM could carry no changes)
 	 */
@@ -2037,8 +2035,8 @@
 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change,
 				  tt_num_changes, ttvn);

-	batadv_tt_save_orig_buffer(bat_priv, orig_node,
-				   (unsigned char *)tt_change, tt_num_changes);
+	batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
+				   batadv_tt_len(tt_num_changes));
 	atomic_set(&orig_node->last_ttvn, ttvn);
 }


lib/sign: support S3 CNAME bucket aliases

Assume any hostname that does not include the S3 host component is a
CNAME bucket alias.

--- lib/sign.c
+++ lib/sign.c
@@ -490,6 +490,7 @@
 	return path_part;
 }

+#define URL_S3_BASE "s3.amazonaws.com"
 /*
  * @slash_url_host points to the last forward slash after the protocol string
  */
@@ -499,20 +500,40 @@
 	char *d;
 	char *bucket = NULL;

+	if (strncmp(slash_url_host + 1, URL_S3_BASE,
+		    sizeof(URL_S3_BASE) - 1) == 0) {
+		/* base URL only */
+		return strdup("");
+	}
+
 	/* find the first dot, up to which may be the bucket name */
 	d = strchr(slash_url_host, '.');
-	assert(d != NULL);
-	/* FIXME URL assumption, use a #def at least */
-	if (strncmp(d, ".s3.", sizeof(".s3.") - 1) == 0) {
+	if ((d != NULL)
+	 && (strncmp(d + 1, URL_S3_BASE, sizeof(URL_S3_BASE) - 1) == 0)) {
+		dbg(6, "bucket prefix in S3 host path\n");
 		/*
 		 * There is a bucket name before the aws hostname, ensure the
 		 * required '/' prefix is included in the bucket string.
 		 */
-		bucket = strndup(slash_url_host, (d - slash_url_host));
+		return strndup(slash_url_host, (d - slash_url_host));
 	} else {
-		bucket = strdup("");
-	}
-	return bucket;
+		const char *sep = NULL;
+		dbg(2, "non S3 host, assuming CNAME bucket alias\n");
+		/* copy up to port, path or query sep */
+		sep = strchr(slash_url_host + 1, ':');
+		if (sep == NULL)
+			sep = strchr(slash_url_host + 1, '/');
+		if (sep == NULL)
+			sep = strchr(slash_url_host + 1, '?');
+
+		if (sep == NULL) {
+			return strdup(slash_url_host);
+		} else {
+			return strndup(slash_url_host, sep - slash_url_host);
+		}
+	}
+	dbg(0, "rsc bucket unhandled!\n");
+	return NULL;
 }

 /*


Fix compilation error. See http://cdash.cern.ch/viewBuildError.php?buildid=48591

--- net/davix/inc/TDavixFileInternal.h
+++ net/davix/inc/TDavixFileInternal.h
@@ -46,6 +46,7 @@
    class RequestParams;
    class DavPosix;
 }
+struct Davix_fd;

 class TDavixFileInternal {


sort: declare a variable when it's used

sort: declare a variable when it's used

--- lib/sort.c
+++ lib/sort.c
@@ -218,7 +218,6 @@
                      uint32_t *size,
                      sort_data *data)
 {
-  const uint8_t *value;
   sort_value_copy *copy = entry->value.copy;
   if (entry->value.n_cached_values <= key->index_value) {
     if (key->column_cache) {
@@ -242,7 +241,7 @@
     }
     entry->value.n_cached_values++;
   }
-  value =
+  const uint8_t *value =
     (const uint8_t *)GRN_BULK_HEAD(copy->values) +
     compare_data->values_offset;
   *size =


samples: blink_led: Add support for STM32F413

The STM32F413 has PWM output capabilities. Add support to the blink_led
samples.

Tested using a Nucleo STM32F413ZH board (PWM output on pin 28 of the
CN11 Morpho connector and pin 29 of the CN10 Zio connector).

Change-Id: I3b25b09cab54265b28088ac9681aec588d9d48b5
Signed-off-by: Florian Vaussard <ef1e2bd37ca89620283a38ee0519838a257cab3b@heig-vd.ch>

--- samples/basic/blink_led/src/main.c
+++ samples/basic/blink_led/src/main.c
@@ -15,7 +15,8 @@
 #include <device.h>
 #include <pwm.h>

-#if defined(CONFIG_SOC_STM32F401XE) || defined(CONFIG_SOC_STM32L476XG)
+#if defined(CONFIG_SOC_STM32F401XE) || defined(CONFIG_SOC_STM32L476XG) || \
+	defined(CONFIG_SOC_STM32F413XH)
 #define PWM_DRIVER CONFIG_PWM_STM32_2_DEV_NAME
 #define PWM_CHANNEL 1
 #elif CONFIG_SOC_STM32F103XB


samples: display: Added support for sitronix_st7735r

Requires a ST7735R based LCD

Signed-off-by: Kim Bøndergaard <a6312121e15caec74845b7ba5af23330d52d4ac0@fam-boendergaard.dk>
Signed-off-by: Kim Bøndergaard <695fc8bd4ef74b2b3e6e15e6638babb1294ffb95@prevas.dk>

--- samples/drivers/display/src/main.c
+++ samples/drivers/display/src/main.c
@@ -30,6 +30,10 @@
 #define DISPLAY_DEV_NAME DT_LABEL(DT_INST(0, sitronix_st7789v))
 #endif

+#if DT_NODE_HAS_STATUS(DT_INST(0, sitronix_st7735r), okay)
+#define DISPLAY_DEV_NAME DT_LABEL(DT_INST(0, sitronix_st7735r))
+#endif
+
 #if DT_NODE_HAS_STATUS(DT_INST(0, fsl_imx6sx_lcdif), okay)
 #define DISPLAY_DEV_NAME DT_LABEL(DT_INST(0, fsl_imx6sx_lcdif))
 #endif
@@ -77,7 +81,7 @@
 #endif

 static void fill_buffer_argb8888(enum corner corner, uint8_t grey, uint8_t *buf,
-			       size_t buf_size)
+				 size_t buf_size)
 {
 	uint32_t color = 0;

@@ -219,7 +223,7 @@

 	display_get_capabilities(display_dev, &capabilities);

-	if (capabilities.screen_info & SCREEN_INFO_MONO_VTILED)  {
+	if (capabilities.screen_info & SCREEN_INFO_MONO_VTILED) {
 		rect_w = 16;
 		rect_h = 8;
 	} else {


samples: sensor: max17262: Remove dead code

MAX17262 and MAX17262_LABEL defines aren't used anymore so remove them

Signed-off-by: Kumar Gala <383ef5577c6e1178b93f59ec8d0936f76d2a98c4@kernel.org>

--- samples/sensor/max17262/src/main.c
+++ samples/sensor/max17262/src/main.c
@@ -8,15 +8,6 @@
 #include <zephyr/device.h>
 #include <zephyr/devicetree.h>
 #include <zephyr/drivers/sensor.h>
-
-#define MAX17262 DT_INST(0, maxim_max17262)
-
-#if DT_NODE_HAS_STATUS(MAX17262, okay)
-#define MAX17262_LABEL DT_LABEL(MAX17262)
-#else
-#error Your devicetree has no enabled nodes with compatible "maxim,max17262"
-#define MAX17262_LABEL "<none>"
-#endif

 void main(void)
 {


Corrected comment: whom(1) does not use context_foil().

--- sbr/mts.c
+++ sbr/mts.c
@@ -357,8 +357,8 @@
     /* If there's a Local-Mailbox profile component, try to extract
        the username from it.  But don't try very hard, this assumes
        the very simple User Name <user@name.com> form.
-       Note that post(8) and whom(1) use context_foil (), so they
-       won't see the profile component. */
+       Note that post(8) uses context_foil(), so it won't see the profile
+       component. */
     if ((np = context_find("Local-Mailbox")) != NULL) {
 	char *left_angle_bracket = strchr (np, '<');
 	char *at_sign = strchr (np, '@');
@@ -397,8 +397,8 @@
     /* The $SIGNATURE environment variable overrides the GECOS field's idea of
        your real name. If SIGNATURE isn't set, use the Signature profile
        setting if it exists.
-       Note that post(8) and whom(1) use context_foil (), so they
-       won't see the profile component. */
+       Note that post(8) uses context_foil(), so it won't see the profile
+       component. */
     if ((cp = getenv ("SIGNATURE")) && *cp)
 	strncpy (fullname, cp, sizeof(fullname));
     else if ((cp = context_find("Signature")))


Call isc_log_wouldlog() in a few places.

--- lib/dns/xfrin.c
+++ lib/dns/xfrin.c
@@ -15,7 +15,7 @@
  * SOFTWARE.
  */

-/* $Id: xfrin.c,v 1.82 2000/07/05 20:28:34 gson Exp $ */
+/* $Id: xfrin.c,v 1.83 2000/07/13 00:27:17 bwelling Exp $ */

 #include <config.h>

@@ -1215,6 +1215,9 @@
 {
         va_list ap;

+	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
+		return;
+
 	va_start(ap, fmt);
 	xfrin_logv(level, zonename, masteraddr, fmt, ap);
 	va_end(ap);
@@ -1229,6 +1232,9 @@
 {
         va_list ap;

+	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
+		return;
+
 	va_start(ap, fmt);
 	xfrin_logv(level, &xfr->name, &xfr->masteraddr, fmt, ap);
 	va_end(ap);


inspect: remove needless unlink

inspect: remove needless unlink

--- lib/util.c
+++ lib/util.c
@@ -504,7 +504,6 @@
     GRN_TEXT_PUTS(ctx, buf, " range:");
     if (range) {
       grn_inspect_name(ctx, buf, range);
-      grn_obj_unlink(ctx, range);
     } else {
       grn_text_lltoa(ctx, buf, range_id);
     }
@@ -655,7 +654,6 @@
   domain = grn_ctx_at(ctx, domain_id);
   if (domain) {
     grn_inspect_name(ctx, buf, domain);
-    grn_obj_unlink(ctx, domain);
   } else if (domain_id) {
     grn_text_lltoa(ctx, buf, domain_id);
   } else {
@@ -723,7 +721,6 @@
                                        GRN_INFO_DEFAULT_TOKENIZER, NULL);
   if (default_tokenizer) {
     grn_inspect_name(ctx, buf, default_tokenizer);
-    grn_obj_unlink(ctx, default_tokenizer);
   } else {
     GRN_TEXT_PUTS(ctx, buf, "(nil)");
   }
@@ -740,7 +737,6 @@
   normalizer = grn_obj_get_info(ctx, obj, GRN_INFO_NORMALIZER, NULL);
   if (normalizer) {
     grn_inspect_name(ctx, buf, normalizer);
-    grn_obj_unlink(ctx, normalizer);
   } else {
     GRN_TEXT_PUTS(ctx, buf, "(nil)");
   }
@@ -1076,7 +1072,6 @@
               grn_obj_get_value(ctx, col, id, &value);
               grn_inspect(ctx, buf, &value);
               GRN_OBJ_FIN(ctx, &value);
-              grn_obj_unlink(ctx, col);
             }
           });
       }
@@ -1088,10 +1083,6 @@
   }

   GRN_TEXT_PUTS(ctx, buf, ">");
-
-  if (table) {
-    grn_obj_unlink(ctx, table);
-  }

   return GRN_SUCCESS;
 }
@@ -1162,7 +1153,6 @@
       domain = grn_ctx_at(ctx, obj->header.domain);
       if (domain) {
         grn_id type = domain->header.type;
-        grn_obj_unlink(ctx, domain);
         switch (type) {
         case GRN_TABLE_HASH_KEY :
         case GRN_TABLE_PAT_KEY :
@@ -1182,7 +1172,6 @@
     domain = grn_ctx_at(ctx, obj->header.domain);
     if (domain) {
       grn_id type = domain->header.type;
-      grn_obj_unlink(ctx, domain);
       switch (type) {
       case GRN_TABLE_HASH_KEY :
       case GRN_TABLE_PAT_KEY :


review of NSEC and NSEC3 zones results

review of NSEC and NSEC3 zones results

git-svn-id: e875384d7a5ebd9b2def38a8354dae1fda8e73bc@2058 be551aaa-1e26-0410-a405-d3ace91eadb9

--- validator/val_nsec3.c
+++ validator/val_nsec3.c
@@ -424,7 +424,7 @@
 		if(!nsec3_rrset_has_known(list[i]))
 			continue;

-		/* since NSECs are base32.zonename, we can find the zone
+		/* since NSEC3s are base32.zonename, we can find the zone
 		 * name by stripping off the first label of the record */
 		nm = list[i]->rk.dname;
 		nmlen = list[i]->rk.dname_len;


Remove lint warning.

Remove lint warning.

git-svn-id: e875384d7a5ebd9b2def38a8354dae1fda8e73bc@3629 be551aaa-1e26-0410-a405-d3ace91eadb9

--- validator/val_utils.c
+++ validator/val_utils.c
@@ -693,7 +693,7 @@
 			ds_key_algo_is_supported(ds_rrset, i))
 			return 1;
 	}
-	if(verbose < VERB_ALGO)
+	if(verbosity < VERB_ALGO)
 		return 0;
 	if(rrset_get_count(ds_rrset) == 0)
 		verbose(VERB_ALGO, "DS is not usable");


xbps_symlink_target: rename var to avoid shadowing a global var.

--- lib/util.c
+++ lib/util.c
@@ -482,15 +482,15 @@
 	}

 	if (strstr(lnk, "./") || lnk[0] != '/') {
-		char *p, *p1, *dname, labs[PATH_MAX];
+		char *p, *p1, *dname, lnkrs[PATH_MAX];
 		/* relative */
 		p = strdup(path);
 		assert(p);
 		dname = dirname(p);
 		assert(dname);
-		snprintf(labs, sizeof(labs), "%s/%s", dname, lnk);
+		snprintf(lnkrs, sizeof(lnkrs), "%s/%s", dname, lnk);
 		free(p);
-		p = xbps_sanitize_path(labs);
+		p = xbps_sanitize_path(lnkrs);
 		assert(p);
 		if ((strstr(p, "./")) && (p1 = realpath(p, NULL))) {
 			if (strcmp(xhp->rootdir, "/") == 0)


Use same election timeout always

Use same election timeout always

In particular, we wait at least 150ms after starting up before declaring
an election, to give the old leader a chance to send us a heartbeat.

--- v/raft.c
+++ v/raft.c
@@ -148,12 +148,14 @@
   return buf_u;
 }

-/* _raft_election_rand(): pseudorandom component of election timeout.
+/* _raft_election_rand(): election timeout.
 */
 static c3_w
 _raft_election_rand()
 {
-  return ((float) rand() / RAND_MAX) * 150;
+  c3_w ret = (1.0 + (float) rand() / RAND_MAX) * 150;
+  //uL(fprintf(uH, "raft: timeout %d\n", ret));
+  return ret;
 }

 /* _raft_promote(): actions on raft leader election.
@@ -285,7 +287,7 @@
     sas_i = uv_timer_stop(&raf_u->tim_u);
     c3_assert(0 == sas_i);
     sas_i = uv_timer_start(&raf_u->tim_u, &_raft_time_cb,
-                           150 + _raft_election_rand(), 0);
+                           _raft_election_rand(), 0);
     c3_assert(0 == sas_i);
   }

@@ -1287,7 +1289,7 @@
     }
     case u2_raty_cand: {
       sas_i = uv_timer_start(tim_u, _raft_time_cb,
-                             150 + _raft_election_rand(), 0);
+                             _raft_election_rand(), 0);
       c3_assert(sas_i == 0);
       _raft_start_election(raf_u);
       break;


fix jack_connect to close jack_client in case of error (debian bug 465073)

git-svn-id: 9d792367086e53bac42cb25f723fe47762daf29a@3476 0c269be4-1314-0410-8aa9-9f06e86f4224

--- tools/connect.c
+++ tools/connect.c
@@ -65,6 +65,7 @@
 	jack_port_t *port2 = 0;
 	int connecting, disconnecting;
 	int port1_flags, port2_flags;
+	int rc = 1;

 	struct option long_options[] = {
 	    { "server", 1, 0, 's' },
@@ -124,11 +125,11 @@

 	if ((port1 = jack_port_by_name(client, argv[argc-1])) == 0) {
 		fprintf (stderr, "ERROR %s not a valid port\n", argv[argc-1]);
-		return 1;
+		goto exit;
 		}
 	if ((port2 = jack_port_by_name(client, argv[argc-2])) == 0) {
 		fprintf (stderr, "ERROR %s not a valid port\n", argv[argc-2]);
-		return 1;
+		goto exit;
 		}

 	port1_flags = jack_port_flags (port1);
@@ -148,7 +149,7 @@

 	if (!src_port || !dst_port) {
 		fprintf (stderr, "arguments must include 1 input port and 1 output port\n");
-		return 1;
+		goto exit;
 	}

 	/* connect the ports. Note: you can't do this before
@@ -157,16 +158,20 @@

 	if (connecting) {
 		if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
-			return 1;
+			goto exit;
 		}
 	}
 	if (disconnecting) {
 		if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
-			return 1;
+			goto exit;
 		}
 	}

+	/* everything was ok, so setting exitcode to 0 */
+	rc = 0;
+
+exit:
 	jack_client_close (client);
-	exit (0);
+	exit (rc);
 }


When configuring RAID3 with verification option, force synchronization
of parity component, because we can't return an EIO error for read of
every sector which wasn't written first.

Discussed with:	phk

--- sbin/geom/class/raid3/geom_raid3.c
+++ sbin/geom/class/raid3/geom_raid3.c
@@ -280,6 +280,13 @@
 				str += strlen(_PATH_DEV);
 			strlcpy(md.md_provider, str, sizeof(md.md_provider));
 		}
+		if (*verify && md.md_no == md.md_all - 1) {
+			/*
+			 * In "verify" mode, force synchronization of parity
+			 * component on start.
+			 */
+			md.md_syncid = 0;
+		}
 		raid3_metadata_encode(&md, sector);
 		error = g_metadata_store(str, sector, sizeof(sector));
 		if (error != 0) {


PUD: improve createDownlinkSocket a bit

PUD: improve createDownlinkSocket a bit

Signed-off-by: Ferry Huberts <1f083df4a0371a8eba2ce71fc6b0e214b2551710@mindef.nl>

--- lib/pud/src/networkInterfaces.c
+++ lib/pud/src/networkInterfaces.c
@@ -454,8 +454,19 @@
  */
 static int createDownlinkSocket(socket_handler_func rxSocketHandlerFunction) {
 	int downlinkSocket = -1;
-	int reuse = 1;
-	struct sockaddr_in address;
+	int socketReuseFlagValue = 1;
+	union olsr_sockaddr address;
+
+	memset(&address, 0, sizeof(address));
+	if (olsr_cnf->ip_version == AF_INET) {
+		address.in4.sin_family = AF_INET;
+		address.in4.sin_addr.s_addr = INADDR_ANY;
+		address.in4.sin_port = getDownlinkPort();
+	} else {
+		address.in6.sin6_family = AF_INET6;
+		address.in6.sin6_addr = in6addr_any;
+		address.in6.sin6_port = getDownlinkPort();
+	}

 	/*  Create a datagram socket on which to receive */
 	errno = 0;
@@ -468,22 +479,18 @@
 	/* Enable SO_REUSEADDR to allow multiple applications to receive the same
 	 * messages */
 	errno = 0;
-	if (setsockopt(downlinkSocket, SOL_SOCKET, SO_REUSEADDR, &reuse,
-			sizeof(reuse)) < 0) {
+	if (setsockopt(downlinkSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
+			sizeof(socketReuseFlagValue)) < 0) {
 		pudError(true, "Could not set REUSE option on the downlink socket");
 		goto bail;
 	}

-	/* Bind to the proper port number with the IP address INADDR_ANY (required) */
-	memset(&address, 0, sizeof(address));
-	address.sin_family = AF_INET;
-	address.sin_addr.s_addr = INADDR_ANY;
-	address.sin_port = getDownlinkPort();
-
-	errno = 0;
-	if (bind(downlinkSocket, (struct sockaddr *) &address,
-			sizeof(address))) {
-		pudError(true, "Could not bind downlink socket to port %d", getDownlinkPort());
+	/* Bind to the proper port number with the IP address INADDR_ANY
+	 * (INADDR_ANY is really required here, do not change it) */
+	errno = 0;
+	if (bind(downlinkSocket, (struct sockaddr *) &address, sizeof(address))) {
+		pudError(true, "Could not bind downlink socket to port %d",
+				getDownlinkPort());
 		goto bail;
 	}


portable; Linux has setgroups(2) in <grp.h>

--- sandbox.c
+++ sandbox.c
@@ -33,6 +33,7 @@
 #include <linux/seccomp.h>

 #include <stddef.h> /* offsetof */
+#include <grp.h> /* setgroups */

 /* Linux seccomp_filter sandbox */
 #define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL


sbc: fix frame length calculation for DUAL_CHANNEL mode

According to A2DP specification, section 12.9, for DUAL_CHANNEL mode, we
shall use the same formula as for MONO mode.

--- sbc/sbc.c
+++ sbc/sbc.c
@@ -1402,7 +1402,7 @@

 	ret = 4 + (4 * subbands * channels) / 8;
 	/* This term is not always evenly divide so we round it up */
-	if (channels == 1)
+	if (channels == 1 || sbc->mode == SBC_MODE_DUAL_CHANNEL)
 		ret += ((blocks * channels * bitpool) + 7) / 8;
 	else
 		ret += (((joint ? subbands : 0) + blocks * bitpool) + 7) / 8;


clean up device main.c demo code

clean up device main.c demo code

--- demos/device/keyboard/main.c
+++ demos/device/keyboard/main.c
@@ -16,6 +16,9 @@

 void print_greeting(void);

+void led_blinking_task(void * p_para);
+void keyboard_device_app_task(void * p_para);
+
 int main(void)
 {
   uint32_t current_tick = system_ticks;
@@ -28,29 +31,20 @@
   {
     if (current_tick + 1000 < system_ticks)
     {
-      static uint32_t led_on_mask = 0;
-
       current_tick += 1000;

-      board_leds(led_on_mask, 1 - led_on_mask);
-      led_on_mask = 1 - led_on_mask; // toggle
+      led_blinking_task(NULL);

+      #if TUSB_CFG_DEVICE_HID_KEYBOARD
+      keyboard_device_app_task(NULL);
+      #endif
+
+      #if TUSB_CFG_DEVICE_HID_MOUSE
       if (usb_isConfigured())
       {
-        #if TUSB_CFG_DEVICE_HID_KEYBOARD
-        static uint32_t count =0;
-        if (count < 4)
-        {
-          uint8_t keys[6] = {0x04}; // A character
-          tusbd_hid_keyboard_send_report(0x00, keys, 1);
-          count++;
-        }
-        #endif
-
-        #if TUSB_CFG_DEVICE_HID_MOUSE
           tusb_hid_mouse_send(0, 10, 10);
-        #endif
       }
+      #endif
     }

     #if defined TUSB_CFG_DEVICE_CDC && 0
@@ -90,6 +84,30 @@
   return 0;
 }

+void led_blinking_task(void * p_para)
+{
+  static uint32_t led_on_mask = 0;
+
+  board_leds(led_on_mask, 1 - led_on_mask);
+  led_on_mask = 1 - led_on_mask; // toggle
+}
+
+#if TUSB_CFG_DEVICE_HID_KEYBOARD
+void keyboard_device_app_task(void * p_para)
+{
+  if (usb_isConfigured())
+  {
+    static uint32_t count =0;
+    if (count < 4)
+    {
+      uint8_t keys[6] = {0x04}; // A character
+      tusbd_hid_keyboard_send_report(0x00, keys, 1);
+      count++;
+    }
+  }
+}
+#endif
+
 //--------------------------------------------------------------------+
 // HELPER FUNCTION
 //--------------------------------------------------------------------+


better unexpected character message in Parse_Context

--- utils/parse_context.h
+++ utils/parse_context.h
@@ -157,9 +157,9 @@
     }

     /** Expect a literal character.  Throws if the character is not matched. */
-    void expect_literal(char c, const char * error = "expected '%c'")
-    {
-        if (!match_literal(c)) exception_fmt(error, c);
+    void expect_literal(char c, const char * error = "expected '%c', got '%c'")
+    {
+        if (!match_literal(c)) exception_fmt(error, c, (eof() ? '\0' : *cur_));
     }

     /** Match a literal string.  Returns true if it was matched and false if


NO-JIRA: Removes the path from the usage filename displayed for proton.

git-svn-id: 33ed6c3feaacb64944efc691d1ae8e09b17f2bf9@1402223 13f79535-47bb-0310-9956-ffa450edef68

--- proton-c/src/proton.c
+++ proton-c/src/proton.c
@@ -27,6 +27,7 @@
 #include <proton/message.h>
 #include <proton/util.h>
 #include <unistd.h>
+#include <libgen.h>
 #include "util.h"
 #include "pn_config.h"
 #include <proton/codec.h>
@@ -426,7 +427,7 @@
       buffer(argc, argv);
       exit(EXIT_SUCCESS);
     case 'h':
-      printf("Usage: %s [-h] [-c [user[:password]@]host[:port]] [-a <address>] [-m <sasl-mech>]\n", argv[0]);
+      printf("Usage: %s [-h] [-c [user[:password]@]host[:port]] [-a <address>] [-m <sasl-mech>]\n", basename(argv[0]));
       printf("\n");
       printf("    -c    The connect url.\n");
       printf("    -a    The AMQP address.\n");


gen1/save: fixed resource leak reported by cppcheck

--- lib/gen1/save.c
+++ lib/gen1/save.c
@@ -42,6 +42,7 @@
     fseek(gen1_save, SEEK_END, 0);

     if(ftell(gen1_save) < PKSAV_GEN1_SAVE_SIZE) {
+        fclose(gen1_save);
         return false;
     }

@@ -72,6 +73,7 @@
     fseek(gen1_save_file, SEEK_END, 0);

     if(ftell(gen1_save_file) < PKSAV_GEN1_SAVE_SIZE) {
+        fclose(gen1_save_file);
         return PKSAV_ERROR_INVALID_SAVE;
     }


[libzstd] Bump the library version to 1.4.0

Bumps the library version to 1.4.0 in preparation to stabilize the
advanced API.

--- lib/zstd.h
+++ lib/zstd.h
@@ -70,8 +70,8 @@

 /*------   Version   ------*/
 #define ZSTD_VERSION_MAJOR    1
-#define ZSTD_VERSION_MINOR    3
-#define ZSTD_VERSION_RELEASE  8
+#define ZSTD_VERSION_MINOR    4
+#define ZSTD_VERSION_RELEASE  0

 #define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
 ZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< to check runtime library version */


Made CBot respond to some insults with some other insults.

error: pathspec 'plugin/sadness.c' did not match any file(s) known to git

--- plugin/sadness.c
+++ plugin/sadness.c
@@ -0,0 +1,40 @@
+/***************************************************************************//**
+
+  @file         sadness.c
+
+  @author       Stephen Brennan
+
+  @date         Created Tuesday, 28 July 2015
+
+  @brief        CBot plugin to respond to hatred and sadness.
+
+  @copyright    Copyright (c) 2015, Stephen Brennan.  Released under the Revised
+                BSD License.  See LICENSE.txt for details.
+
+*******************************************************************************/
+
+#include <stdlib.h>
+#include "cbot/cbot.h"
+
+static cbot_send_t send;
+
+static void sadness(cbot_t *bot, const char *channel, const char *user,
+                    const char *message)
+{
+  char *responses[] = {
+    ":(",
+    "hey, robots have feelings too!",
+    "I don't like you, %s",
+    "that's not what your mom said last night"
+  };
+  send(bot, channel, responses[rand()%(sizeof(responses)/sizeof(char*))], user);
+}
+
+void sadness_load(cbot_t *bot, cbot_register_t hear, cbot_register_t respond, cbot_send_t send_)
+{
+  send = send_;
+  respond(bot, "([Yy]ou +[Ss]uck[!.]?|"
+          "[Ss]ucks[!.]?|"
+          "[Ii] +[Hh]ate +[Yy]ou[!.]?|"
+          "[Ss]hut [Uu]p[!.]?)", sadness);
+}


Split statistics printing from memory cleanup

Created ct_print_stats that outputs stats without freeing
memory, and ct_print_stats_and_terminate which does both, along with
ct_terminate which only frees memory.

--- libctest.h
+++ libctest.h
@@ -1,10 +1,14 @@
-#ifndef __testing__
-#define __testing__
+#ifndef __ctest__
+#define __ctest__

 extern void ct_init(const char * module_name);

 extern void ct_report(const char * test_name, int success);

+extern void ct_print_stats(void);
+
 extern void ct_terminate(void);

+extern void ct_print_stats_and_terminate(void);
+
 #endif


Add missing header file <Include.h> to Console.h

This is needed for the check for iostream in the console out check.

--- Console.h
+++ Console.h
@@ -1,3 +1,5 @@
+#include <Include.h>
+
 using namespace std;

 int ConsoleOutCheck(string ProcessInput)


test-contacts/by_handle_again: prepare many more features

In theory this test should be able to prepare *every* feature and not
make redundant GetContactAttributes(). Until recently, this was broken
for LOCATION.

Some features are currently commented out because TpContact is buggy;
others are commented out because TpTestContactsConnection is buggy.

--- tests/dbus/contacts.c
+++ tests/dbus/contacts.c
@@ -7,9 +7,9 @@
  * - having to fall back to RequestAliases
  * - get_contacts_by_id with features (but it's trivial)
  *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- * Copyright (C) 2007 Will Thompson
+ * Copyright © 2008–2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright © 2008 Nokia Corporation
+ * Copyright © 2007 Will Thompson
  *
  * Copying and distribution of this file, with or without modification,
  * are permitted in any medium without royalty provided the copyright
@@ -841,7 +841,24 @@
   TpContact *contact;
   gpointer weak_pointer;
   const gchar *alias = "Alice in Wonderland";
-  TpContactFeature feature = TP_CONTACT_FEATURE_ALIAS;
+  /* We only actively test TP_CONTACT_FEATURE_ALIAS, but preparing any of these
+   * once should be enough, assuming that the CM is not broken.
+   *
+   * FIXME: commented-out features are currently broken, either in TpContact or
+   * in TpTestsContactsConnection.
+   */
+  TpContactFeature features[] = {
+      TP_CONTACT_FEATURE_ALIAS,
+      // TP_CONTACT_FEATURE_AVATAR_TOKEN,
+      TP_CONTACT_FEATURE_PRESENCE,
+      TP_CONTACT_FEATURE_LOCATION,
+      // TP_CONTACT_FEATURE_CAPABILITIES,
+      // TP_CONTACT_FEATURE_AVATAR_DATA,
+      // TP_CONTACT_FEATURE_CONTACT_INFO,
+      // TP_CONTACT_FEATURE_CLIENT_TYPES,
+      TP_CONTACT_FEATURE_SUBSCRIPTION_STATES,
+      TP_CONTACT_FEATURE_CONTACT_GROUPS
+  };

   g_test_bug ("25181");

@@ -852,7 +869,7 @@

   tp_connection_get_contacts_by_handle (f->client_conn,
       1, &handle,
-      1, &feature,
+      G_N_ELEMENTS (features), features,
       by_handle_cb,
       &result, finish, NULL);
   g_main_loop_run (result.loop);
@@ -874,7 +891,7 @@

   tp_connection_get_contacts_by_handle (f->client_conn,
       1, &handle,
-      1, &feature,
+      G_N_ELEMENTS (features), features,
       by_handle_cb,
       &result, finish, NULL);
   g_main_loop_run (result.loop);


Create DAC6574.h

Create DAC6574.h

error: pathspec 'DAC6574.h' did not match any file(s) known to git

--- DAC6574.h
+++ DAC6574.h
@@ -0,0 +1,58 @@
+/*
+ Name:		DAC6574.h
+ Created:	6/27/2017 1:27:25 PM
+ Author:	gabor.baroczi.ext
+ Editor:	http://www.visualmicro.com
+*/
+
+#ifndef _DAC6574_h
+#define _DAC6574_h
+
+#include <inttypes.h>
+#include <Wire.h>
+
+#define CH_A 0B00
+#define CH_B 0B01
+#define CH_C 0B10
+#define CH_D 0B11
+
+#define POWER_NORMAL 0b0
+#define POWER_DOWN	0b1
+
+#define CMD_STORE 0b00
+#define CMD_SET_OUTPUT 0b01
+#define CMD_4CH_SET_OUTPUT 0b10
+#define CMD_BROADCAST 0b10
+
+#define ADDRESS_4C_DEFAULT 0x4C
+#define ADDRESS_4D 0x4D
+#define ADDRESS_4E 0x4E
+#define ADDRESS_4F 0x4F
+
+#define HIGH_IMPEDANCE_OUTPUT 0b00
+#define _1K_TO_GND 0b01
+#define _100K_TO_GND 0b10
+#define HIGH_IMPEDANCE 0b11
+
+#if defined(ARDUINO) && ARDUINO >= 100
+	#include "arduino.h"
+#else
+	#include "WProgram.h"
+#endif
+class DAC6574 {
+public:
+	DAC6574();
+	DAC6574(uint8_t addr);
+	void begin();
+	void storeData1CH(uint8_t channel, uint16_t data);
+	void setOutput1CH(uint8_t channel, uint16_t data);
+	void setOutputAllCH(uint16_t data);
+	void powerDown1CH(uint8_t channel, uint8_t mode);
+	void powerDownAllCH(uint8_t mode);
+
+
+private:
+	uint8_t _i2caddr;
+};
+
+#endif


staging: rtl8192u: Remove commented header.

This patch removes the commented header <linux/config.h>
as it is not used in modern linux systems.

Signed-off-by: Navya Sri Nizamkari <2220f5fded1749fc9f263cc20f55877611b12255@gmail.com>
Acked-by: Arnd Bergmann <f2c659f01951776204a6c5b902787d9019fbeebd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <4645f7897fd33786a2ee1264d590b3c400559d85@linuxfoundation.org>

--- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
+++ drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
@@ -9,7 +9,6 @@
  * more details.
  */

-//#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>