Motr  M0
addb2.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2014-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 
126 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_ADDB
127 
128 #include "lib/finject.h"
129 #include "lib/errno.h" /* ENOMEM, EPROTO */
130 #include "lib/thread.h" /* m0_thread_tls */
131 #include "lib/arith.h" /* M0_CNT_DEC, M0_CNT_INC */
132 #include "lib/tlist.h"
133 #include "lib/trace.h"
134 #include "lib/memory.h"
135 #include "lib/mutex.h"
136 #include "lib/mutex.h"
137 #include "lib/locality.h"
138 #include "fid/fid.h"
139 #include "module/instance.h" /* m0_get */
140 
141 #include "addb2/addb2.h"
142 #include "addb2/internal.h"
143 #include "addb2/consumer.h"
144 #include "addb2/addb2_xc.h"
145 #include "addb2/storage.h" /* m0_addb2_frame_header */
146 #include "addb2/storage_xc.h"
147 #include "addb2/identifier.h" /* M0_AVI_NODATA */
148 
149 enum {
150 #ifndef __KERNEL__
151 
159  BUFFER_SIZE = 64 * 1024,
164 #else
165  BUFFER_SIZE = 4096,
166  BUFFER_MIN = 0,
167 #endif
168 
174  TAG_MASK = 0xff00000000000000ull,
182 };
183 
188 #define DEBUG_OWNERSHIP (1)
189 
195 M0_BASSERT(BUFFER_SIZE > M0_ADDB2_LABEL_MAX * 3 * sizeof(uint64_t));
196 
200 struct buffer {
205  uint64_t b_magix;
206 };
207 
211 struct tentry {
219  struct m0_tl e_sensor;
226 };
227 
239  struct buffer *ma_cur;
248  struct m0_tl ma_idle;
262  struct m0_tl ma_busy;
273  uint32_t ma_nesting;
278  const struct m0_addb2_mach_ops *ma_ops;
303  void *ma_cookie;
322  unsigned ma_sensor_skip;
323  uint64_t ma_magix;
324 #if DEBUG_OWNERSHIP
325  char ma_name[100];
326  char ma_last[100];
327 #endif
328 };
329 
334 M0_TL_DESCR_DEFINE(tr, "addb2 traces",
335  M0_INTERNAL, struct m0_addb2_trace_obj, o_linkage, o_magix,
337 M0_TL_DEFINE(tr, M0_INTERNAL, struct m0_addb2_trace_obj);
338 
342 M0_TL_DESCR_DEFINE(buf, "addb2 buffers",
343  static, struct buffer, b_linkage, b_magix,
345 M0_TL_DEFINE(buf, static, struct buffer);
346 
350 M0_TL_DESCR_DEFINE(sensor, "addb2 sensors",
351  static, struct m0_addb2_sensor, s_linkage, s_magix,
353 M0_TL_DEFINE(sensor, static, struct m0_addb2_sensor);
354 
358 M0_TL_DESCR_DEFINE(mach, "addb2 machines",
359  M0_INTERNAL, struct m0_addb2_mach, ma_linkage, ma_magix,
361 M0_TL_DEFINE(mach, M0_INTERNAL, struct m0_addb2_mach);
362 
369 enum {
374  PUSH = 0x10,
376  POP = 0xf0,
380  DATA = 0x20,
385  SENSOR = 0x30
386 };
387 
388 static int buffer_alloc(struct m0_addb2_mach *mach);
389 static void buffer_fini(struct buffer *buffer);
390 static m0_bcount_t buffer_space(const struct buffer *buffer);
391 static void buffer_add(struct buffer *buf, uint64_t datum);
392 static struct buffer *mach_buffer(struct m0_addb2_mach *mach);
393 static struct tentry *mach_top(struct m0_addb2_mach *m);
394 static struct buffer *cur(struct m0_addb2_mach *mach, m0_bcount_t space);
395 static struct m0_addb2_mach *mach(void);
396 static void mach_put(struct m0_addb2_mach *m);
397 static void mach_idle(struct m0_addb2_mach *m);
398 static void add(struct m0_addb2_mach *mach, uint64_t id, int n,
399  const uint64_t *value);
400 static void pack(struct m0_addb2_mach *mach);
401 static uint64_t tag(uint8_t code, uint64_t id);
402 static void sensor_place(struct m0_addb2_mach *m, struct m0_addb2_sensor *s);
403 static void record_consume(struct m0_addb2_mach *m,
404  uint64_t id, int n, const uint64_t *value);
405 static bool trace_invariant(const struct m0_addb2_trace *tr);
406 
410 #define MACH_DEPTH(mach) (mach->ma_rec.ar_label_nr)
411 
412 void m0_addb2_push(uint64_t id, int n, const uint64_t *value)
413 {
414  struct m0_addb2_mach *m = mach();
415 
416  if (m != NULL) {
417  struct tentry *e;
418  struct m0_addb2_value *v;
419 
421  M0_PRE(n <= ARRAY_SIZE(e->e_value));
422  M0_PRE(!m->ma_stopping);
423  /*
424  * Note that add() must go before MACH_DEPTH(mach)++, because
425  * add() might allocate a new trace buffer and mach_buffer()
426  * will place all stacked labels to the buffer.
427  */
428  add(m, tag(PUSH | n, id), n, value);
429  MACH_DEPTH(m)++;
430  e = mach_top(m);
431  v = e->e_recval;
432  v->va_id = id;
433  v->va_nr = n;
434  M0_ASSERT(v->va_data == e->e_value);
435  memcpy(e->e_value, value, n * sizeof *value);
436  mach_put(m);
437  }
438 }
439 
440 void m0_addb2_pop(uint64_t id)
441 {
442  struct m0_addb2_mach *m = mach();
443 
444  if (m != NULL) {
445  struct tentry *e = mach_top(m);
446  struct m0_addb2_sensor *s;
447 
448  M0_PRE(MACH_DEPTH(m) > 0);
449  M0_PRE(!m->ma_stopping);
450  M0_ASSERT_INFO(e->e_recval->va_id == id,
451  "Want: %" PRIx64 " got: %" PRIx64 ".",
452  e->e_recval->va_id, id);
453 
455  sensor_place(m, s);
456  s->s_ops->so_fini(s);
457  }
458  sensor_tlist_fini(&e->e_sensor);
459  add(m, tag(POP, id), 0, NULL);
460  /* decrease the depth *after* add(), see m0_addb2_push(). */
461  -- MACH_DEPTH(m);
462  mach_put(m);
463  }
464 }
465 
466 void m0_addb2_add(uint64_t id, int n, const uint64_t *value)
467 {
468  struct m0_addb2_mach *m = mach();
469 
470  if (m != NULL) {
471  M0_PRE(n <= ARRAY_SIZE(m->ma_label[0].e_value));
472  M0_PRE(!m->ma_stopping);
473 
474  add(m, tag(DATA | n, id), n, value);
475  record_consume(m, id, n, value);
476  mach_put(m);
477  }
478 }
479 
480 void m0_addb2_sensor_add(struct m0_addb2_sensor *s, uint64_t id, unsigned nr,
481  int idx, const struct m0_addb2_sensor_ops *ops)
482 {
483  struct m0_addb2_mach *m = mach();
484 
485  M0_PRE(M0_IS0(s));
486  M0_PRE(nr <= VALUE_MAX_NR);
487 
488  if (m != NULL) {
489  struct tentry *te = idx < 0 ? mach_top(m) : &m->ma_label[idx];
490 
491  M0_PRE(MACH_DEPTH(m) > 0);
492  M0_PRE(ergo(idx >= 0, idx < MACH_DEPTH(m)));
493  M0_PRE(!m->ma_stopping);
494 
495  s->s_id = id;
496  s->s_nr = nr;
497  s->s_ops = ops;
498  sensor_tlink_init_at_tail(s, &te->e_sensor);
499  sensor_place(m, s);
500  mach_put(m);
501  }
502 }
503 
505 {
506  struct m0_addb2_mach *m = mach();
507 
508  if (m != NULL) {
509  M0_PRE(!m->ma_stopping);
510 
511  if (sensor_tlink_is_in(s)) {
512  sensor_place(m, s);
513  sensor_tlist_del(s);
514  }
515  sensor_tlink_fini(s);
516  mach_put(m);
517  }
518 }
519 
520 struct m0_addb2_mach *
521 m0_addb2_mach_init(const struct m0_addb2_mach_ops *ops, void *cookie)
522 {
523  struct m0_addb2_mach *mach;
524 
526  if (mach != NULL) {
527  int i;
528 
529  mach->ma_ops = ops;
530  mach->ma_cookie = cookie;
534  buf_tlist_init(&mach->ma_idle);
535  buf_tlist_init(&mach->ma_busy);
537  mach_tlink_init(mach);
538 #if DEBUG_OWNERSHIP
539  strcpy(mach->ma_name, m0_thread_self()->t_namebuf);
540 #endif
541  for (i = 0; i < ARRAY_SIZE(mach->ma_rec.ar_label); ++i) {
542  struct tentry *t = &mach->ma_label[i];
543  struct m0_addb2_value *v = &mach->ma_rec.ar_label[i];
544 
545  v->va_data = t->e_value;
546  t->e_recval = v;
547  sensor_tlist_init(&t->e_sensor);
548  }
549  for (i = 0; i < BUFFER_MIN; ++i) {
550  if (buffer_alloc(mach) != 0) {
552  mach = NULL;
553  break;
554  }
555  }
556  }
557  return mach;
558 }
559 
561 {
562  struct buffer *buf;
563 
564  M0_PRE(MACH_DEPTH(mach) == 0);
565  /*
566  * This lock-unlock is a barrier against concurrently finishing last
567  * m0_addb2_trace_done(), which signalled ->apo_idle().
568  *
569  * It *is* valid to acquire and finalise a lock in the same function in
570  * this particular case.
571  */
574 
575  if (mach->ma_cur != NULL)
578  buffer_fini(buf);
579  }
581  mach_tlink_fini(mach);
582  buf_tlist_fini(&mach->ma_idle);
583  buf_tlist_fini(&mach->ma_busy);
586  m0_free(mach);
587 }
588 
590 {
591  struct m0_addb2_mach *m = mach();
592 
593  if (m != NULL) {
595  delay))) {
596  pack(m);
597  }
598  mach_put(m);
599  }
600 }
601 
602 static int addb2_force_loc_cb(void *unused)
603 {
605  return 0;
606 }
607 
608 static void addb2_force_loc(struct m0_locality *loc)
609 {
611 }
612 
614 {
615  struct m0_locality *loc;
616  struct m0_locality *loc_first;
617  uint64_t i;
618 
621  i = 0;
622  loc = m0_locality_get(0);
623  loc_first = loc;
624  do {
625  addb2_force_loc(loc);
626  loc = m0_locality_get(++i);
627  } while (loc != loc_first);
628 }
629 
631 {
632  mach->ma_stopping = true;
633  pack(mach);
635  mach_idle(mach);
637 }
638 
640 {
643 }
644 
646 {
647  return mach->ma_cookie;
648 }
649 
650 void m0_addb2_trace_done(const struct m0_addb2_trace *ctrace)
651 {
652  /* can safely discard const, because we passed this trace to
653  ->apo_submit(). */
654  struct m0_addb2_trace *trace = (struct m0_addb2_trace *)ctrace;
655  struct buffer *buf = M0_AMB(buf, trace, b_trace.o_tr);
656  struct m0_addb2_mach *mach = buf->b_trace.o_mach;
657 
658  M0_PRE_EX(trace_invariant(ctrace));
659  if (mach != NULL) { /* mach == NULL for a trace from network. */
661  M0_PRE_EX(buf_tlist_contains(&mach->ma_busy, buf));
663  if (mach->ma_busy_nr + mach->ma_idle_nr +
664  !!(mach->ma_cur != NULL) <= BUFFER_MIN) {
665  buf_tlist_move(&mach->ma_idle, buf);
667  buf->b_trace.o_tr.tr_nr = 0;
668  } else {
669  buf_tlist_del(buf);
670  buffer_fini(buf);
671  }
672  if (mach->ma_stopping)
673  mach_idle(mach);
675  }
676 }
677 
679 {
680  return &m->ma_src;
681 }
682 
683 M0_INTERNAL m0_bcount_t m0_addb2_trace_size(const struct m0_addb2_trace *trace)
684 {
685  return sizeof trace->tr_nr + trace->tr_nr * sizeof trace->tr_body[0];
686 }
687 
688 /* Consumer cursor */
689 
691  const struct m0_addb2_trace *trace)
692 {
693  M0_PRE(M0_IS0(cur));
694 
695  cur->cu_trace = trace;
696  m0_addb2_source_init(&cur->cu_src);
697 }
698 
700 {
701  m0_addb2_source_fini(&cur->cu_src);
702 }
703 
705 {
706  struct m0_addb2_record *r = &cur->cu_rec;
707 
708  M0_PRE_EX(trace_invariant(cur->cu_trace));
709  /* Sync changes with trace_invariant(). */
710  while (cur->cu_pos < cur->cu_trace->tr_nr) {
711  uint64_t *addr = &cur->cu_trace->tr_body[cur->cu_pos];
712  uint64_t datum = addr[0];
713  m0_time_t time = addr[1];
714  uint64_t tag = datum >> (64 - 8);
715  uint8_t nr = tag & 0xf;
716 
717  M0_CASSERT(VALUE_MAX_NR == 0xf);
718 
719  datum &= ~TAG_MASK;
720  addr += 2;
721  switch (tag & ~0xFULL) {
722  case PUSH:
723  if (r->ar_label_nr < ARRAY_SIZE(r->ar_label)) {
724  r->ar_label[r->ar_label_nr ++] =
725  (struct m0_addb2_value) {
726  .va_id = datum,
727  .va_time = time,
728  .va_nr = nr,
729  .va_data = addr
730  };
731  cur->cu_pos += nr + 2;
732  continue;
733  } else
734  M0_LOG(M0_NOTICE, "Too many labels.");
735  break;
736  case POP:
737  if (r->ar_label_nr > 0) {
738  -- r->ar_label_nr;
739  cur->cu_pos += 2;
740  continue;
741  } else
742  M0_LOG(M0_WARN, "Underflow.");
743  break;
744  case DATA:
745  case SENSOR:
746  r->ar_val = (struct m0_addb2_value) {
747  .va_id = datum,
748  .va_time = time,
749  .va_nr = nr,
750  .va_data = addr
751  };
752  cur->cu_pos += nr + 2;
753  if (datum == M0_AVI_NODATA) /* skip internal record */
754  continue;
755  m0_addb2_consume(&cur->cu_src, r);
756  return +1;
757  default:
758  M0_LOG(M0_NOTICE, "Opcode: %" PRIx64 ".", datum);
759  }
760  return M0_ERR(-EPROTO);
761  }
762  return 0;
763 }
764 
765 M0_INTERNAL struct m0_addb2_module *m0_addb2_module_get(void)
766 {
767  return m0_get()->i_moddata[M0_MODULE_ADDB2];
768 }
769 
771 {
772  struct m0_addb2_module *am;
773 
774  M0_ALLOC_PTR(am);
775  if (am != NULL) {
778  return 0;
779  } else
780  return M0_ERR(-ENOMEM);
781 }
782 
784 {
786 }
787 
791 static struct buffer *cur(struct m0_addb2_mach *mach, m0_bcount_t space)
792 {
793  struct buffer *buf = mach_buffer(mach);
794 
795  M0_PRE(space <= BUFFER_SIZE);
796 
797  if (buf != NULL && buffer_space(buf) < space)
798  pack(mach);
799  return mach_buffer(mach);
800 }
801 
808 static struct buffer *mach_buffer(struct m0_addb2_mach *mach)
809 {
810  if (mach->ma_cur == NULL) {
812  if (mach->ma_idle_nr == 0) {
813  if (mach->ma_busy_nr <= BUFFER_MAX)
815  else
816  M0_LOG(M0_NOTICE, "Too many ADDB2 buffers.");
817  }
818  mach->ma_cur = buf_tlist_pop(&mach->ma_idle);
819  /*
820  * Initialise the new current buffer: re-create current context
821  * by re-applying push operations and reading associated
822  * sensors.
823  */
824  if (mach->ma_cur != NULL) {
825  int i;
826  int n = 0;
827 
829  for (i = 0; i < MACH_DEPTH(mach); ++i) {
830  struct tentry *e = &mach->ma_label[i];
831  struct m0_addb2_value *v = e->e_recval;
832  struct m0_addb2_sensor *s;
833 
834  add(mach, tag(PUSH | v->va_nr, v->va_id),
835  v->va_nr, v->va_data);
836  if (n < 0)
837  continue;
838  m0_tl_for(sensor, &e->e_sensor, s) {
839  if (buffer_space(mach->ma_cur) <
841  /*
842  * Too much space in the buffer
843  * is occupied by the
844  * sensors. Skip the rest of the
845  * sensors, they will be added
846  * to the next buffer.
847  */
848  mach->ma_sensor_skip = n;
849  n = -1;
850  break;
851  }
852  if (n >= mach->ma_sensor_skip)
853  sensor_place(mach, s);
854  ++n;
855  } m0_tl_endfor;
856  }
857  if (n >= 0)
858  /*
859  * Placed all the sensors, start from the
860  * beginning.
861  */
862  mach->ma_sensor_skip = 0;
863  mach->ma_cur->b_trace.o_force = false;
864  }
866  }
867  return mach->ma_cur;
868 }
869 
873 struct m0_addb2_mach *(*m0_addb2__mach)(void) = NULL;
874 
881 static struct m0_addb2_mach *mach(void)
882 {
883  struct m0_thread_tls *tls = m0_thread_tls();
884  struct m0_addb2_mach *mach = tls != NULL ? tls->tls_addb2_mach : NULL;
885 
886  if (M0_FI_ENABLED("surrogate-mach") && m0_addb2__mach != NULL)
887  mach = m0_addb2__mach();
888 
889  if (mach != NULL) {
890  if (mach->ma_nesting > 0) {
891  /* This is a normal situation, e.g., allocation of a new
892  buffer triggers m0_addb2_add() call in m0_alloc(). */
893  M0_LOG(M0_DEBUG, "Recursive ADDB2 invocation.");
894  mach = NULL;
895  } else if (mach->ma_stopping)
896  mach = NULL;
897  else {
898  ++ mach->ma_nesting;
899 #if DEBUG_OWNERSHIP
900  strcpy(mach->ma_last, m0_thread_self()->t_namebuf);
901 #endif
902  }
903  }
904  M0_POST(ergo(mach != NULL, mach->ma_nesting == 1));
905  return mach;
906 }
907 
911 static void mach_put(struct m0_addb2_mach *m)
912 {
913  M0_PRE(m->ma_nesting > 0);
914  -- m->ma_nesting;
915 }
916 
920 static void mach_idle(struct m0_addb2_mach *m)
921 {
922  if (m->ma_busy_nr == 0) {
923  if (m->ma_ops->apo_idle != NULL)
924  m->ma_ops->apo_idle(m);
926  }
927 }
928 
934 static void add(struct m0_addb2_mach *mach,
935  uint64_t id, int n, const uint64_t *value)
936 {
937  m0_time_t now = m0_time_now();
938  struct buffer *buf = cur(mach,
939  sizeof id + sizeof now + n * sizeof value[0]);
940 
941  if (buf != NULL) {
942  buffer_add(buf, id);
943  buffer_add(buf, now);
944  while (n-- > 0)
945  buffer_add(buf, *value++);
946  }
947  M0_POST_EX(ergo(buf != NULL, trace_invariant(&buf->b_trace.o_tr)));
948 }
949 
955 static void buffer_add(struct buffer *buf, uint64_t datum)
956 {
957  struct m0_addb2_trace *tr = &buf->b_trace.o_tr;
958 
959  M0_PRE(buffer_space(buf) >= sizeof datum);
960  tr->tr_body[tr->tr_nr ++] = datum;
961 }
962 
966 static void pack(struct m0_addb2_mach *m)
967 {
968  if (m->ma_cur != NULL) {
969  struct m0_addb2_trace_obj *o = &m->ma_cur->b_trace;
970  bool wait;
971 
973  o->o_force = m->ma_stopping;
974  /*
975  * The buffer is on the busy list until m0_addb2_trace_done() is
976  * called.
977  */
978  buf_tlist_add_tail(&m->ma_busy, m->ma_cur);
982  wait = m->ma_ops->apo_submit(m, o) > 0;
984  if (!wait) {
985  /*
986  * The buffer was processed "instantly", can be re-used
987  * outright.
988  */
989  buf_tlist_move(&m->ma_idle, m->ma_cur);
992  o->o_tr.tr_nr = 0;
993  }
994  m->ma_cur = NULL;
996  }
997  m->ma_packed = m0_time_now();
998 }
999 
1003 static m0_bcount_t buffer_space(const struct buffer *buffer)
1004 {
1006  sizeof buffer->b_trace.o_tr.tr_body[0];
1007  M0_PRE(BUFFER_SIZE >= used);
1008  return BUFFER_SIZE - used;
1009 }
1010 
1014 static int buffer_alloc(struct m0_addb2_mach *mach)
1015 {
1016  struct buffer *buf;
1017  void *area;
1018 
1019  M0_ALLOC_PTR(buf);
1020  area = m0_alloc(BUFFER_SIZE);
1021  if (buf != NULL && area != NULL) {
1022  buf->b_trace.o_tr.tr_body = area;
1023  buf->b_trace.o_mach = mach;
1024  buf_tlink_init_at_tail(buf, &mach->ma_idle);
1026  M0_POST_EX(trace_invariant(&buf->b_trace.o_tr));
1027  return 0;
1028  } else {
1029  M0_LOG(M0_NOTICE, "Cannot allocate ADDB2 buffer.");
1030  m0_free(buf);
1031  m0_free(area);
1032  return M0_ERR(-ENOMEM);
1033  }
1034 }
1035 
1036 static void buffer_fini(struct buffer *buf)
1037 {
1038  M0_PRE_EX(trace_invariant(&buf->b_trace.o_tr));
1039  buf_tlink_fini(buf);
1040  m0_free(buf->b_trace.o_tr.tr_body);
1041  m0_free(buf);
1042 }
1043 
1047 static uint64_t tag(uint8_t code, uint64_t id)
1048 {
1049  M0_PRE((id & TAG_MASK) == 0);
1050  return id | (((uint64_t)code) << (64 - 8));
1051 }
1052 
1056 static struct tentry *mach_top(struct m0_addb2_mach *m)
1057 {
1058  M0_PRE(MACH_DEPTH(m) > 0);
1059  return &m->ma_label[MACH_DEPTH(m) - 1];
1060 }
1061 
1065 static void sensor_place(struct m0_addb2_mach *m, struct m0_addb2_sensor *s)
1066 {
1067  int nr = s->s_nr;
1068 
1069  M0_PRE(s != NULL);
1070  M0_PRE(nr <= VALUE_MAX_NR);
1071 
1072  {
1073  uint64_t area[nr]; /* VLA! */
1074 
1075  s->s_ops->so_snapshot(s, area);
1076  add(m, tag(SENSOR | nr, s->s_id), nr, area);
1077  record_consume(m, s->s_id, nr, area);
1078  }
1079 }
1080 
1085 static void record_consume(struct m0_addb2_mach *m,
1086  uint64_t id, int n, const uint64_t *value)
1087 {
1088  m->ma_rec.ar_val = (struct m0_addb2_value) {
1089  .va_id = id,
1090  .va_nr = n,
1091  .va_data = value
1092  };
1094 }
1095 
1096 M0_INTERNAL uint64_t m0_addb2__dummy_payload[1] = {};
1097 
1098 M0_INTERNAL uint64_t m0_addb2__dummy_payload_size =
1100 
1101 static bool trace_invariant(const struct m0_addb2_trace *tr)
1102 {
1103  int i = 0;
1104  int depth = 0;
1105  uint64_t stack[M0_ADDB2_LABEL_MAX];
1106 
1107  /* Sync changes with m0_addb2_cursor_next(). */
1108  while (i < tr->tr_nr) {
1109  uint64_t datum = tr->tr_body[i];
1110  uint64_t tag = datum >> (64 - 8);
1111  uint8_t nr = tag & 0xf;
1112 
1113  datum &= ~TAG_MASK;
1114  switch (tag & ~0xfull) {
1115  case PUSH:
1116  if (_0C(depth < ARRAY_SIZE(stack)))
1117  stack[depth++] = datum;
1118  else
1119  return false;
1120  break;
1121  case POP:
1122  if (_0C(depth > 0) && _0C(stack[depth - 1] == datum))
1123  --depth;
1124  else
1125  return false;
1126  i += 2;
1127  continue;
1128  case DATA:
1129  case SENSOR:
1130  break;
1131  default:
1132  return false;
1133  }
1134  i += nr + 2;
1135  }
1136  return true;
1137 }
1138 
1139 M0_INTERNAL void m0_addb2__mach_print(const struct m0_addb2_mach *m)
1140 {
1141 #if DEBUG_OWNERSHIP
1142  const char *orig = m->ma_name;
1143  const char *last = m->ma_last;
1144  M0_LOG(M0_FATAL, "mach: %p \"%s\" \"%s\".", m, orig, last);
1145 #else
1146  M0_LOG(M0_FATAL, "mach: %p.", m);
1147 #endif
1148 }
1149 
1150 #undef M0_TRACE_SUBSYSTEM
1151 
1154 /*
1155  * Local variables:
1156  * c-indentation-style: "K&R"
1157  * c-basic-offset: 8
1158  * tab-width: 8
1159  * fill-column: 80
1160  * scroll-step: 1
1161  * End:
1162  */
1163 /*
1164  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
1165  */
uint64_t id
Definition: cob.h:2380
void m0_addb2_force(m0_time_t delay)
Definition: addb2.c:589
static size_t nr
Definition: dump.c:1505
int m0_addb2_module_init(void)
Definition: addb2.c:770
static void sensor(void)
Definition: consumer.c:243
#define M0_PRE(cond)
static struct m0_semaphore wait
Definition: item.c:151
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL struct m0_locality * m0_locality_get(uint64_t value)
Definition: locality.c:156
static void sensor_place(struct m0_addb2_mach *m, struct m0_addb2_sensor *s)
Definition: addb2.c:1065
struct m0_addb2_value * e_recval
Definition: addb2.c:225
#define NULL
Definition: misc.h:38
uint64_t b_magix
Definition: addb2.c:205
static struct m0_addb2_mach * m
Definition: consumer.c:38
M0_INTERNAL struct m0_addb2_module * m0_addb2_module_get(void)
Definition: addb2.c:765
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
const struct m0_addb2_mach_ops * ma_ops
Definition: addb2.c:278
#define ergo(a, b)
Definition: misc.h:293
uint64_t e_value[VALUE_MAX_NR]
Definition: addb2.c:215
struct m0_addb2_mach * tls_addb2_mach
Definition: thread.h:68
static uint64_t tag(uint8_t code, uint64_t id)
Definition: addb2.c:1047
unsigned va_nr
Definition: consumer.h:105
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
static struct buffer * mach_buffer(struct m0_addb2_mach *mach)
Definition: addb2.c:808
static void mach_put(struct m0_addb2_mach *m)
Definition: addb2.c:911
#define M0_CASSERT(cond)
struct buffer * ma_cur
Definition: addb2.c:239
void * ma_cookie
Definition: addb2.c:303
static int delay
Definition: dump.c:174
int m0_addb2_cursor_next(struct m0_addb2_cursor *cur)
Definition: addb2.c:704
void m0_addb2_cursor_fini(struct m0_addb2_cursor *cur)
Definition: addb2.c:699
struct m0_addb2_trace_obj b_trace
Definition: addb2.c:204
Definition: addb2.c:374
int const char const void * value
Definition: dir.c:325
void m0_addb2_mach_fini(struct m0_addb2_mach *mach)
Definition: addb2.c:560
static void mach_idle(struct m0_addb2_mach *m)
Definition: addb2.c:920
uint64_t va_id
Definition: consumer.h:103
static struct tentry * mach_top(struct m0_addb2_mach *m)
Definition: addb2.c:1056
static void pack(struct m0_addb2_mach *mach)
Definition: addb2.c:966
struct m0_addb2_source ma_src
Definition: addb2.c:292
uint64_t m0_bcount_t
Definition: types.h:77
M0_INTERNAL struct m0 * m0_get(void)
Definition: instance.c:41
m0_time_t ma_packed
Definition: addb2.c:315
static int void * buf
Definition: dir.c:1019
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
int m0_locality_call(struct m0_locality *loc, int(*cb)(void *), void *data)
Definition: locality.c:570
M0_INTERNAL uint64_t m0_addb2__dummy_payload[1]
Definition: addb2.c:1096
M0_TL_DESCR_DEFINE(tr, "addb2 traces", M0_INTERNAL, struct m0_addb2_trace_obj, o_linkage, o_magix, M0_ADDB2_TRACE_MAGIC, M0_ADDB2_TRACE_HEAD_MAGIC)
Definition: addb2.c:385
#define PRIx64
Definition: types.h:61
M0_INTERNAL void m0_addb2__mach_print(const struct m0_addb2_mach *m)
Definition: addb2.c:1139
Definition: addb2.c:380
Definition: sock.c:887
struct m0_addb2_trace o_tr
Definition: addb2.h:451
#define m0_tl_endfor
Definition: tlist.h:700
Definition: addb2.c:376
#define M0_ASSERT_EX(cond)
M0_INTERNAL struct m0_thread_tls * m0_thread_tls(void)
Definition: kthread.c:67
char ma_name[100]
Definition: addb2.c:325
M0_BASSERT(BUFFER_SIZE > M0_ADDB2_LABEL_MAX *3 *sizeof(uint64_t))
int i
Definition: dir.c:1033
static unsigned depth
Definition: base.c:377
void m0_addb2_trace_done(const struct m0_addb2_trace *ctrace)
Definition: addb2.c:650
m0_bcount_t ma_idle_nr
Definition: addb2.c:252
bool m0_time_is_in_past(m0_time_t t)
Definition: time.c:102
return M0_ERR(-EOPNOTSUPP)
uint64_t ma_magix
Definition: addb2.c:323
struct m0_tlink ma_linkage
Definition: addb2.c:311
void m0_addb2_push(uint64_t id, int n, const uint64_t *value)
Definition: addb2.c:412
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
void m0_addb2_module_fini(void)
Definition: addb2.c:783
#define MACH_DEPTH(mach)
Definition: addb2.c:410
static void buffer_add(struct buffer *buf, uint64_t datum)
Definition: addb2.c:955
#define M0_ASSERT(cond)
struct m0_tl ma_busy
Definition: addb2.c:262
static bool trace_invariant(const struct m0_addb2_trace *tr)
Definition: addb2.c:1101
void m0_addb2_mach_stop(struct m0_addb2_mach *mach)
Definition: addb2.c:630
m0_time_t m0_time_now(void)
Definition: time.c:134
static struct m0_thread t[8]
Definition: service_ut.c:1230
Definition: tlist.h:251
M0_INTERNAL uint64_t m0_addb2__dummy_payload_size
Definition: addb2.c:1098
struct m0_tl ma_idle
Definition: addb2.c:248
uint32_t ma_nesting
Definition: addb2.c:273
void m0_addb2_sensor_add(struct m0_addb2_sensor *s, uint64_t id, unsigned nr, int idx, const struct m0_addb2_sensor_ops *ops)
Definition: addb2.c:480
void m0_addb2_consume(struct m0_addb2_source *src, const struct m0_addb2_record *rec)
Definition: consumer.c:143
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
void * m0_alloc(size_t size)
Definition: memory.c:126
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
struct m0_addb2_value ar_label[M0_ADDB2_LABEL_MAX]
Definition: consumer.h:118
#define M0_POST(cond)
Definition: xcode.h:73
struct m0_addb2_mach *(* m0_addb2__mach)(void)
Definition: addb2.c:873
static int addb2_force_loc_cb(void *unused)
Definition: addb2.c:602
static int buffer_alloc(struct m0_addb2_mach *mach)
Definition: addb2.c:1014
M0_TL_DEFINE(tr, M0_INTERNAL, struct m0_addb2_trace_obj)
static __thread struct m0_thread_tls * tls
Definition: uthread.c:66
m0_bcount_t ma_busy_nr
Definition: addb2.c:266
static m0_bcount_t buffer_space(const struct buffer *buffer)
Definition: addb2.c:1003
void m0_addb2_cursor_init(struct m0_addb2_cursor *cur, const struct m0_addb2_trace *trace)
Definition: addb2.c:690
void m0_addb2_add(uint64_t id, int n, const uint64_t *value)
Definition: addb2.c:466
int(* apo_submit)(struct m0_addb2_mach *mach, struct m0_addb2_trace_obj *tobj)
Definition: addb2.h:368
struct m0_tl e_sensor
Definition: addb2.c:219
m0_time_t m0_time_add(const m0_time_t t1, const m0_time_t t2)
Definition: time.c:47
void m0_addb2_pop(uint64_t id)
Definition: addb2.c:440
static int used
Definition: base.c:304
static void buffer_fini(struct buffer *buffer)
Definition: addb2.c:1036
Definition: addb2.c:211
static void addb2_force_loc(struct m0_locality *loc)
Definition: addb2.c:608
struct m0_semaphore ma_idlewait
Definition: addb2.c:307
uint64_t n
Definition: fops.h:107
static void record_consume(struct m0_addb2_mach *m, uint64_t id, int n, const uint64_t *value)
Definition: addb2.c:1085
struct m0_mutex ma_lock
Definition: addb2.c:285
M0_INTERNAL struct m0_locality * m0_locality0_get(void)
Definition: locality.c:169
#define M0_CNT_INC(cnt)
Definition: arith.h:226
struct m0_tlink b_linkage
Definition: addb2.c:202
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
#define M0_IS0(obj)
Definition: misc.h:70
void(* apo_idle)(struct m0_addb2_mach *mach)
Definition: addb2.h:374
void * m0_addb2_mach_cookie(const struct m0_addb2_mach *mach)
Definition: addb2.c:645
struct m0_addb2_value ar_val
Definition: consumer.h:114
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
const uint64_t * va_data
Definition: consumer.h:106
static int r[NR]
Definition: thread.c:46
void * i_moddata[M0_MODULE_NR]
Definition: instance.h:94
M0_INTERNAL struct m0_thread * m0_thread_self(void)
Definition: thread.c:122
Definition: addb2.c:200
M0_INTERNAL m0_bcount_t m0_addb2_trace_size(const struct m0_addb2_trace *trace)
Definition: addb2.c:683
void m0_addb2_force_all(void)
Definition: addb2.c:613
#define _0C(exp)
Definition: assert.h:311
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
bool ma_stopping
Definition: addb2.c:277
char ma_last[100]
Definition: addb2.c:326
static struct m0_addb2_mach * mach(void)
Definition: addb2.c:881
#define M0_CNT_DEC(cnt)
Definition: arith.h:219
#define M0_ASSERT_INFO(cond, fmt,...)
struct m0_addb2_record ma_rec
Definition: addb2.c:298
void m0_addb2_source_fini(struct m0_addb2_source *src)
Definition: consumer.c:60
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
void m0_addb2_sensor_del(struct m0_addb2_sensor *s)
Definition: addb2.c:504
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
uint64_t tr_nr
Definition: addb2.h:442
struct m0_fom_ops ops
Definition: io_foms.c:623
#define M0_PRE_EX(cond)
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
static struct m0_addb2_source * s
Definition: consumer.c:39
void m0_addb2_source_init(struct m0_addb2_source *src)
Definition: consumer.c:55
struct m0_addb2_source * m0_addb2_mach_source(struct m0_addb2_mach *m)
Definition: addb2.c:678
uint64_t tr_nr
Definition: addb2.h:434
struct tentry ma_label[M0_ADDB2_LABEL_MAX]
Definition: addb2.c:235
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define M0_POST_EX(cond)
const m0_time_t M0_TIME_IMMEDIATELY
Definition: time.c:107
static struct m0_addb2_frame_header last
Definition: storage.c:93
void m0_addb2_mach_wait(struct m0_addb2_mach *mach)
Definition: addb2.c:639
Definition: trace.h:478
unsigned ma_sensor_skip
Definition: addb2.c:322
struct m0_addb2_mach * m0_addb2_mach_init(const struct m0_addb2_mach_ops *ops, void *cookie)
Definition: addb2.c:521
static void add(struct m0_addb2_mach *mach, uint64_t id, int n, const uint64_t *value)
Definition: addb2.c:934
uint64_t * tr_body
Definition: addb2.h:443