- smp_wmb(); /* Publish new pointer before write q[] */
- _STORE_SHARED(defer_queue.q[head & DEFER_QUEUE_MASK], p);
- smp_wmb(); /* Write q[] before head. */
- STORE_SHARED(defer_queue.head, head + 1);
+ if (unlikely(defer_queue.last_fct_in != fct)) {
+ defer_queue.last_fct_in = fct;
+ if (unlikely(DQ_IS_FCT_BIT(fct) || fct == DQ_FCT_MARK)) {
+ /*
+ * If the function to encode is not aligned or the
+ * marker, write DQ_FCT_MARK followed by the function
+ * pointer.
+ */
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK],
+ DQ_FCT_MARK);
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK],
+ fct);
+ } else {
+ DQ_SET_FCT_BIT(fct);
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK],
+ fct);
+ }
+ } else {
+ if (unlikely(DQ_IS_FCT_BIT(p) || p == DQ_FCT_MARK)) {
+ /*
+ * If the data to encode is not aligned or the marker,
+ * write DQ_FCT_MARK followed by the function pointer.
+ */
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK],
+ DQ_FCT_MARK);
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK],
+ fct);
+ }
+ }
+ _STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], p);
+ smp_wmb(); /* Publish new pointer before head */
+ /* Write q[] before head. */
+ STORE_SHARED(defer_queue.head, head);