<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Slight nitpick: control of *what*?<br>
    <br>
    Your comment should read something like "transfer control of the
    current thread" or something similar.  <br>
    <br>
    Otherwise, LGTM.  <br>
    <br>
    Philip<br>
    <br>
    <div class="moz-cite-prefix">On 05/15/2014 01:43 PM, Juergen
      Ributzka wrote:<br>
    </div>
    <blockquote
      cite="mid:2200977E-0478-47ED-90F5-603258A7BF92@apple.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div>The addition about the undefined state of the current context
        is a very good point. Although I wouldn’t like to shut the door
        completely and allow for future extensions to relax this
        constraint for APIs that explicitly state that they are safe to
        use during a yield callback.</div>
      <div><br>
      </div>
      <div>I agree with Andy that we shouldn’t mention multi-threaded
        context at all in the API docs, because we are not even
        supporting it right now. I think this feature should be opt-in
        anyways, so extending the API documentation once we support it
        should be sufficient.</div>
      <div><br>
      </div>
      <div>What I would like to see of course is that we would still be
        able to support this callback for a multi-threaded context/pass
        manager design in such a way, that it is possible to suspend any
        thread at a suspension point and it won’t block any other thread
        even in the same context. But I don’t want to write this in
        stone now. This gives us all the flexibility we need for
        developing a good concurrent design.</div>
      <div><br>
      </div>
      <div>Having the ability to dynamically add and remove threads from
        an active compilation would be a nice feature that we should try
        to incorporate when possible and that would work nicely with the
        yield callback.</div>
      <div><br>
      </div>
      <div>Anyways, I am digressing to much. As I said before we should
        only specify the multi-threaded context constrains in the API
        doc once they are actually available. For now this is simply
        undefined behavior and not even supported.</div>
      <div><br>
      </div>
      <div>I extended the API with Philip’s suggestions and updated the
        doc. Please ignore proper 80col formatting for now ;-)</div>
      <div><br>
      </div>
      <div>Does this look good to everyone?</div>
      <div><br>
      </div>
      <div>-Juergen</div>
      <div><br>
      </div>
      <div>
        <div><font face="Menlo">Core.h:</font></div>
        <font face="Menlo">typedef void
          (*LLVMYieldCallback)(LLVMContextRef, void *);</font>
        <div><font face="Menlo"><br>
          </font></div>
        <div><font face="Menlo">/**</font></div>
        <div><font face="Menlo"> * Set the yield callback function for
            this context.</font></div>
        <div><font face="Menlo"> *<br>
             * @see LLVMContext::setYieldCallback()<br>
             */<br>
            void LLVMContextSetYieldCallback(LLVMContextRef C,<br>
                                             LLVMYieldCallback Callback,<br>
                                             void *OpaqueHandle);</font></div>
        <div><font face="Menlo"><br>
          </font></div>
        <div><font face="Menlo">LLVMContext.h:</font></div>
        <div><font face="Menlo">/// \brief Registers a yield callback
            with the given context.<br>
            ///</font></div>
        <div><font face="Menlo">/// The yield callback function may be
            called by LLVM to transfer</font></div>
        <div><font face="Menlo">/// control back to the client that
            invoked the LLVM compilation. This can</font></div>
        <div><font face="Menlo">/// be used to yield control of the
            thread, or perform periodic work needed</font></div>
        <div><font face="Menlo">/// by the client.  There is no
            guaranteed frequency at which callbacks must</font></div>
        <div><font face="Menlo">/// occur; in fact, the client is not
            guaranteed to ever receive this callback.</font></div>
        <div><font face="Menlo">/// It is at the sole discretion of LLVM
            to do so and only if it can guarantee</font></div>
        <div><font face="Menlo">/// that suspending the thread won't
            block any forward progress in other LLVM</font></div>
        <div><font face="Menlo">/// contexts in the same process.</font></div>
        <div><font face="Menlo">///</font></div>
        <div><font face="Menlo">/// At a suspend point, the state of the
            current LLVM context is intentionally</font></div>
        <div><font face="Menlo">/// undefined. No assumptions about it
            can or should be made. Only LLVM context</font></div>
        <div><font face="Menlo">/// API calls </font><span
            style="font-family: Menlo;">that explicitly state that they
            can be used during a yield callback</span></div>
        <div><span style="font-family: Menlo;">/// are </span><span
            style="font-family: Menlo;">allowed to be used. Any other
            API calls into the context are not supported</span></div>
        <div><font face="Menlo">/// until the yield callback function
            returns control to LLVM. Other LLVM contexts</font></div>
        <div><font face="Menlo">/// are unaffected by this restriction.</font></div>
        <div><font face="Menlo">void setYieldCallback(YieldCallbackTy
            Callback, void *OpaqueHandle);<br>
            <br>
            /// \brief Calls the yield callback (if applicable).<br>
            ///<br>
            /// This transfers control back to the client, which may
            suspend the current<br>
            /// thread. Only call this method when LLVM doesn't hold any
            global mutex or<br>
            /// cannot block the execution in another LLVM context.<br>
            void yieldToClient();</font></div>
      </div>
      <div><br>
      </div>
      <br>
      <div>
        <div>On May 15, 2014, at 11:32 AM, Andrew Trick <<a
            moz-do-not-send="true" href="mailto:atrick@apple.com">atrick@apple.com</a>>
          wrote:</div>
        <br class="Apple-interchange-newline">
        <blockquote type="cite">
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br
              class="Apple-interchange-newline">
            On May 15, 2014, at 9:50 AM, Philip Reames <<a
              moz-do-not-send="true"
              href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>>
            wrote:</div>
          <br class="Apple-interchange-newline" style="font-family:
            Helvetica; font-size: 12px; font-style: normal;
            font-variant: normal; font-weight: normal; letter-spacing:
            normal; line-height: normal; orphans: auto; text-align:
            start; text-indent: 0px; text-transform: none; white-space:
            normal; widows: auto; word-spacing: 0px;
            -webkit-text-stroke-width: 0px;">
          <blockquote type="cite" style="font-family: Helvetica;
            font-size: 12px; font-style: normal; font-variant: normal;
            font-weight: normal; letter-spacing: normal; line-height:
            normal; orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="moz-cite-prefix">Given the use case (user mode
                scheduling), I'm not going to oppose this proposal.  I
                would like to see a couple of things clarified
                documentation wise:<br>
                - When is this interface valid?  (i.e. the single thread
                case)<br>
                - If a context does have multiple threads, is this
                called once per thread?  Or once per thread group after
                internal coordination?  (you can write this out of scope
                if desired)<br>
                - If we later introduce multiple threads, and this
                mechanism doesn't support it, what will happen?  Will
                the function just not be called? <span
                  class="Apple-converted-space"> </span><br>
                - You hint at this already, but clarifying the state of
                the current context at a suspend point would be
                helpful. <span class="Apple-converted-space"> </span><br>
                <br>
                Here's a possible draft that includes the above:<br>
                <font face="Menlo">The may-suspend callback function may
                  be called by LLVM to transfer control back to the
                  client that invoked the LLVM compilation. This can be
                  used to yield control of the thread, or perform
                  periodic work needed by the client.  There is no
                  guaranteed frequency at which callbacks must occur; in
                  fact, the client is not guaranteed to ever receive
                  this callback. It is at the sole discretion of LLVM to
                  do so and only if it can guarantee that suspending the
                  thread won't block any forward progress in other LLVM
                  contexts. <span class="Apple-converted-space"> </span></font><br>
                <br>
                <font face="Menlo">At a suspend point, the state of the
                  current LLVM context is intentionally undefined.  No
                  assumptions about it can or should be made.  In
                  particular, call backs into the context are not
                  supported until the suspend function returns control
                  to LLVM.  Other LLVM contexts are unaffected.</font></div>
            </div>
          </blockquote>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">Great.</div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <blockquote type="cite" style="font-family: Helvetica;
            font-size: 12px; font-style: normal; font-variant: normal;
            font-weight: normal; letter-spacing: normal; line-height:
            normal; orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="moz-cite-prefix">Currently, LLVM assumes one
                thread per LLVM context.  If, or when, we introduce
                multiple threads, this interface will not be available
                for contexts which opt-in to the thread pool model.  We
                may extend this interface at a later time to support
                thread pools, but for the moment, that use case is
                explicitly unsupported. <span
                  class="Apple-converted-space"> </span><br>
              </div>
            </div>
          </blockquote>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">Correct.
            We should avoid mentioning multi-thread contexts in the API
            docs. It is very misleading to describe a feature that LLVM
            does not support. We can instead add a statement to the docs
            explaining that the callback is only synchronous with
            respect to the calling thread and places no guarantee on the
            state of other threads, regardless of their context.</div>
          <br style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
          <blockquote type="cite" style="font-family: Helvetica;
            font-size: 12px; font-style: normal; font-variant: normal;
            font-weight: normal; letter-spacing: normal; line-height:
            normal; orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="moz-cite-prefix">p.s. Bikeshed wise, might
                "yield" be a better term than "suspend" here? <span
                  class="Apple-converted-space"> </span><br>
              </div>
            </div>
          </blockquote>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">I
            personally like calling it “yield” because it is more
            intuitive and describes the use case. I proposed maySuspend
            because I wanted to be accurate. It is really the client
            deciding what to do with the callback. LLVM should make no
            assumption that it’s actually yielding.</div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">Chandler
            likes “yield” too, so lets go with that unless anyone else
            wants to weigh in.</div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">On the
            commits list, Juergen introduced our current use case, along
            with a couple other future use cases for this API. I’m sorry
            I neglected to clearly reiterate our usage, but when it
            comes to documenting the C API I intentionally try not to
            limit its potential to a narrow use case.</div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>
          </div>
          <div style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">-Andy</div>
          <br style="font-family: Helvetica; font-size: 12px;
            font-style: normal; font-variant: normal; font-weight:
            normal; letter-spacing: normal; line-height: normal;
            orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
          <blockquote type="cite" style="font-family: Helvetica;
            font-size: 12px; font-style: normal; font-variant: normal;
            font-weight: normal; letter-spacing: normal; line-height:
            normal; orphans: auto; text-align: start; text-indent: 0px;
            text-transform: none; white-space: normal; widows: auto;
            word-spacing: 0px; -webkit-text-stroke-width: 0px;">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="moz-cite-prefix">Philip<br>
                <br>
                On 05/13/2014 11:49 AM, Juergen Ributzka wrote:<br>
              </div>
              <blockquote
                cite="mid:0A13BA19-4D1C-40D5-A31E-99C1909B82B0@apple.com"
                type="cite">
                <div>Sounds good. Lets get started by nailing down the C
                  API and semantics for this first.</div>
                <div><br>
                </div>
                <div>I mirrored the C API for the LLVM context
                  diagnostic handler and used Andy’s suggested name for
                  the callback.</div>
                <div>The opaque handle was suggested by Duncan and can
                  provide optional user specified information that is</div>
                <div>provided back during the callback (i.e. barrier,
                  etc).</div>
                <div><br>
                </div>
                <div>Cheers,</div>
                <div>Juergen </div>
                <div><br>
                </div>
                <div>
                  <div><font face="Menlo">Core.h:</font></div>
                  <font face="Menlo">typedef void
                    (*LLVMMaySuspendCallback)(LLVMContextRef, void *);</font>
                  <div><font face="Menlo"><br>
                    </font></div>
                  <div><font face="Menlo">/**</font></div>
                  <div><font face="Menlo"> * Set the may-suspend
                      callback function for this context.<br>
                       *<br>
                       * @see LLVMContext::setMaySuspendCallback()<br>
                       */<br>
                      void
                      LLVMContextSetMaySuspendCallback(LLVMContextRef C,<br>
                                                         
                        LLVMMaySuspendCallback Callback,<br>
                                                            void
                      *OpaqueHandle);</font></div>
                  <div><font face="Menlo"><br>
                    </font></div>
                  <div><font face="Menlo">LLVMContext.h:</font></div>
                  <div><font face="Menlo">/// \brief Registers a
                      may-suspend callback with the context.<br>
                      ///<br>
                      /// The may-suspend callback function may be
                      called by LLVM to transfer<br>
                      /// control back to the client that invoked the
                      LLVM compilation. The client<br>
                      /// is not garantueed to ever receive this
                      callback. It is at the sole<br>
                      /// discretion of LLVM to do so and only if it
                      can guarantee that suspending<br>
                      /// the thread won't block any forward progress in
                      other LLVM contexts.<br>
                      void setMaySuspendCallback(MaySuspendCallbackTy
                      Callback, void *OpaqueHandle);<br>
                      <br>
                      /// \brief Calls the may-suspend callback (if
                      applicable).<br>
                      ///<br>
                      /// This transfers control back to the client,
                      which may suspend the current<br>
                      /// thread. Only call this method when LLVM
                      doesn't hold any global mutex or<br>
                      /// cannot block the execution in another LLVM
                      context.<br>
                      void callMaySuspendCallback();</font></div>
                </div>
                <div><br>
                  <div>
                    <div>On May 12, 2014, at 5:26 PM, Nick Lewycky <<a
                        moz-do-not-send="true"
                        href="mailto:nlewycky@google.com">nlewycky@google.com</a>>
                      wrote:</div>
                    <br class="Apple-interchange-newline">
                    <blockquote type="cite">
                      <blockquote class="gmail_quote"
                        style="font-family: Helvetica; font-size: 12px;
                        font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px; margin: 0px
                        0px 0px 0.8ex; border-left-width: 1px;
                        border-left-color: rgb(204, 204, 204);
                        border-left-style: solid; padding-left: 1ex;
                        position: static; z-index: auto;">
                        <div style="word-wrap: break-word;">Would you
                          (or anyone) oppose a simple
                          maySuspendContext() callback API? It would
                          mean nothing more than the thread(s) for a
                          given LLVM context can be suspended
                          independent from other contexts.</div>
                      </blockquote>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;"><br>
                      </div>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;">I think
                        this is the right approach. So a given thread
                        hits a safe point, it optionally calls a
                        "suspend check" or "i an safe to suspend right
                        now" callback if set. It doesn't stop other
                        threads, it doesn't continue until the function
                        returns.</div>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;"><br>
                      </div>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;">If you
                        want to stop all threads then the user callback
                        may contain a barrier and count down how many
                        threads have stopped until it sees all of them.</div>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;"><br>
                      </div>
                      <div style="font-family: Helvetica; font-size:
                        12px; font-style: normal; font-variant: normal;
                        font-weight: normal; letter-spacing: normal;
                        line-height: normal; orphans: auto; text-align:
                        start; text-indent: 0px; text-transform: none;
                        white-space: normal; widows: auto; word-spacing:
                        0px; -webkit-text-stroke-width: 0px;">Nick</div>
                    </blockquote>
                  </div>
                  <br>
                </div>
                <br>
                <fieldset class="mimeAttachmentHeader"></fieldset>
                <br>
                <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://llvm.cs.uiuc.edu/">http://llvm.cs.uiuc.edu</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
              </blockquote>
              <br>
            </div>
            _______________________________________________<br>
            LLVM Developers mailing list<br>
            <a moz-do-not-send="true" href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a><span
              class="Apple-converted-space"> </span>        <a
              moz-do-not-send="true" href="http://llvm.cs.uiuc.edu/">http://llvm.cs.uiuc.edu</a><br>
            <a moz-do-not-send="true"
              href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a></blockquote>
        </blockquote>
      </div>
      <br>
    </blockquote>
    <br>
  </body>
</html>