{"action":"created","comment":{"url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/comments/38815062","id":38815062,"diff_hunk":"@@ -0,0 +1,62 @@\n+/*\n+ * Copyright (C) 2015 Ben Hamilton\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package com.zaxxer.nuprocess.osx;\n+\n+import com.sun.jna.Native;\n+import com.sun.jna.Pointer;\n+\n+import java.util.ArrayList;\n+import java.util.List;\n+\n+/**\n+ * @author Ben Hamilton\n+ */\n+final class KeventArray\n+{\n+   private final int size;\n+   private final Pointer pointer;\n+   private final List<Kevent> kevents;\n+\n+   public KeventArray(int size)\n+   {\n+      this.size = size;\n+      long memory = Native.malloc(32 * size);\n+      pointer = new Pointer(memory);\n+      kevents = new ArrayList<Kevent>(size);\n+      for (int i = 0; i < size; i++) {\n+         kevents.add(new Kevent(pointer.share(i * 32)));\n+      }\n+   }\n+\n+   public void free()","path":"src/main/java/com/zaxxer/nuprocess/osx/KeventArray.java","position":null,"original_position":45,"commit_id":"40774e0f42d6b0176230fef517874ba62e510b4f","original_commit_id":"f7fe1d0786538294df888eb36463a13f9bbbdee4","user":{"login":"bhamiltoncx","id":671827,"avatar_url":"https://avatars.githubusercontent.com/u/671827?v=3","gravatar_id":"","url":"https://api.github.com/users/bhamiltoncx","html_url":"https://github.com/bhamiltoncx","followers_url":"https://api.github.com/users/bhamiltoncx/followers","following_url":"https://api.github.com/users/bhamiltoncx/following{/other_user}","gists_url":"https://api.github.com/users/bhamiltoncx/gists{/gist_id}","starred_url":"https://api.github.com/users/bhamiltoncx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhamiltoncx/subscriptions","organizations_url":"https://api.github.com/users/bhamiltoncx/orgs","repos_url":"https://api.github.com/users/bhamiltoncx/repos","events_url":"https://api.github.com/users/bhamiltoncx/events{/privacy}","received_events_url":"https://api.github.com/users/bhamiltoncx/received_events","type":"User","site_admin":false},"body":"Removed method entirely.","created_at":"2015-09-05T21:43:06Z","updated_at":"2015-09-05T21:43:06Z","html_url":"https://github.com/brettwooldridge/NuProcess/pull/31#discussion_r38815062","pull_request_url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31","_links":{"self":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/comments/38815062"},"html":{"href":"https://github.com/brettwooldridge/NuProcess/pull/31#discussion_r38815062"},"pull_request":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31"}}},"pull_request":{"url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31","id":44263227,"html_url":"https://github.com/brettwooldridge/NuProcess/pull/31","diff_url":"https://github.com/brettwooldridge/NuProcess/pull/31.diff","patch_url":"https://github.com/brettwooldridge/NuProcess/pull/31.patch","issue_url":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/31","number":31,"state":"open","locked":false,"title":"Performance improvements for OS X kqueue / kevent","user":{"login":"bhamiltoncx","id":671827,"avatar_url":"https://avatars.githubusercontent.com/u/671827?v=3","gravatar_id":"","url":"https://api.github.com/users/bhamiltoncx","html_url":"https://github.com/bhamiltoncx","followers_url":"https://api.github.com/users/bhamiltoncx/followers","following_url":"https://api.github.com/users/bhamiltoncx/following{/other_user}","gists_url":"https://api.github.com/users/bhamiltoncx/gists{/gist_id}","starred_url":"https://api.github.com/users/bhamiltoncx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhamiltoncx/subscriptions","organizations_url":"https://api.github.com/users/bhamiltoncx/orgs","repos_url":"https://api.github.com/users/bhamiltoncx/repos","events_url":"https://api.github.com/users/bhamiltoncx/events{/privacy}","received_events_url":"https://api.github.com/users/bhamiltoncx/received_events","type":"User","site_admin":false},"body":"I noticed the way `ProcessKqueue` was using `kevent()` was pretty inefficient: it was repeatedly adding and removing the stdio monitoring events to the `kqueue`, and it was handling only one event at a time.\r\n\r\nSince each time we call `kevent()` it requires a round-trip to the kernel, it's important to call it as few times as possible. The most efficient way to use `kevent()` is to:\r\n\r\n1. Re-use events by registering them without the `EV_ONESHOT` flag whenever possible\r\n2. Pass in an array of kevents to read as many events as possible at the same time\r\n3. Rely on the OS automatically invalidating stdio-monitoring events when the fd is closed\r\n\r\nThis diff replaces the single `Kevent triggeredEvent` with a new `KeventArray` holding 64 events which is re-used repeatedly to avoid reallocating the array. Now, each `Kevent` just contains a `Pointer` into a `KeventArray`.\r\n\r\n(We probably should rewrite all this code to use a JNA `Structure` but I didn't feel like doing such a big change here.)\r\n\r\nFor the closeQueue / wantsWrite queues, I also made a tweak to use the efficient `BlockingQueue.drainTo()` API which removes multiple pending items in one call instead of repeatedly polling the queue.\r\n\r\nFinally, I removed the `BlockingQueue<Kevent> keventPool`, since it's no longer needed.","created_at":"2015-09-04T21:27:40Z","updated_at":"2015-09-05T21:43:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6ea29c44e4739e0c0414f2243bd80176966f2b4f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31/commits","review_comments_url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31/comments","review_comment_url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/comments{/number}","comments_url":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/31/comments","statuses_url":"https://api.github.com/repos/brettwooldridge/NuProcess/statuses/40774e0f42d6b0176230fef517874ba62e510b4f","head":{"label":"bhamiltoncx:kqueue","ref":"kqueue","sha":"40774e0f42d6b0176230fef517874ba62e510b4f","user":{"login":"bhamiltoncx","id":671827,"avatar_url":"https://avatars.githubusercontent.com/u/671827?v=3","gravatar_id":"","url":"https://api.github.com/users/bhamiltoncx","html_url":"https://github.com/bhamiltoncx","followers_url":"https://api.github.com/users/bhamiltoncx/followers","following_url":"https://api.github.com/users/bhamiltoncx/following{/other_user}","gists_url":"https://api.github.com/users/bhamiltoncx/gists{/gist_id}","starred_url":"https://api.github.com/users/bhamiltoncx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhamiltoncx/subscriptions","organizations_url":"https://api.github.com/users/bhamiltoncx/orgs","repos_url":"https://api.github.com/users/bhamiltoncx/repos","events_url":"https://api.github.com/users/bhamiltoncx/events{/privacy}","received_events_url":"https://api.github.com/users/bhamiltoncx/received_events","type":"User","site_admin":false},"repo":{"id":40569026,"name":"NuProcess","full_name":"bhamiltoncx/NuProcess","owner":{"login":"bhamiltoncx","id":671827,"avatar_url":"https://avatars.githubusercontent.com/u/671827?v=3","gravatar_id":"","url":"https://api.github.com/users/bhamiltoncx","html_url":"https://github.com/bhamiltoncx","followers_url":"https://api.github.com/users/bhamiltoncx/followers","following_url":"https://api.github.com/users/bhamiltoncx/following{/other_user}","gists_url":"https://api.github.com/users/bhamiltoncx/gists{/gist_id}","starred_url":"https://api.github.com/users/bhamiltoncx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhamiltoncx/subscriptions","organizations_url":"https://api.github.com/users/bhamiltoncx/orgs","repos_url":"https://api.github.com/users/bhamiltoncx/repos","events_url":"https://api.github.com/users/bhamiltoncx/events{/privacy}","received_events_url":"https://api.github.com/users/bhamiltoncx/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bhamiltoncx/NuProcess","description":"Low-overhead, non-blocking I/O, external Process implementation for Java","fork":true,"url":"https://api.github.com/repos/bhamiltoncx/NuProcess","forks_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/forks","keys_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/teams","hooks_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/hooks","issue_events_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/issues/events{/number}","events_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/events","assignees_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/assignees{/user}","branches_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/branches{/branch}","tags_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/tags","blobs_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/git/refs{/sha}","trees_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/statuses/{sha}","languages_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/languages","stargazers_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/stargazers","contributors_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/contributors","subscribers_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/subscribers","subscription_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/subscription","commits_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/commits{/sha}","git_commits_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/git/commits{/sha}","comments_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/comments{/number}","issue_comment_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/issues/comments{/number}","contents_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/contents/{+path}","compare_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/merges","archive_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/downloads","issues_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/issues{/number}","pulls_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/pulls{/number}","milestones_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/milestones{/number}","notifications_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/labels{/name}","releases_url":"https://api.github.com/repos/bhamiltoncx/NuProcess/releases{/id}","created_at":"2015-08-11T22:50:56Z","updated_at":"2015-08-11T22:50:57Z","pushed_at":"2015-09-05T21:42:49Z","git_url":"git://github.com/bhamiltoncx/NuProcess.git","ssh_url":"git@github.com:bhamiltoncx/NuProcess.git","clone_url":"https://github.com/bhamiltoncx/NuProcess.git","svn_url":"https://github.com/bhamiltoncx/NuProcess","homepage":null,"size":535,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"brettwooldridge:master","ref":"master","sha":"9c9e9b17c1f628b938e743f20b5889fc44a1a356","user":{"login":"brettwooldridge","id":1538661,"avatar_url":"https://avatars.githubusercontent.com/u/1538661?v=3","gravatar_id":"","url":"https://api.github.com/users/brettwooldridge","html_url":"https://github.com/brettwooldridge","followers_url":"https://api.github.com/users/brettwooldridge/followers","following_url":"https://api.github.com/users/brettwooldridge/following{/other_user}","gists_url":"https://api.github.com/users/brettwooldridge/gists{/gist_id}","starred_url":"https://api.github.com/users/brettwooldridge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brettwooldridge/subscriptions","organizations_url":"https://api.github.com/users/brettwooldridge/orgs","repos_url":"https://api.github.com/users/brettwooldridge/repos","events_url":"https://api.github.com/users/brettwooldridge/events{/privacy}","received_events_url":"https://api.github.com/users/brettwooldridge/received_events","type":"User","site_admin":false},"repo":{"id":11944439,"name":"NuProcess","full_name":"brettwooldridge/NuProcess","owner":{"login":"brettwooldridge","id":1538661,"avatar_url":"https://avatars.githubusercontent.com/u/1538661?v=3","gravatar_id":"","url":"https://api.github.com/users/brettwooldridge","html_url":"https://github.com/brettwooldridge","followers_url":"https://api.github.com/users/brettwooldridge/followers","following_url":"https://api.github.com/users/brettwooldridge/following{/other_user}","gists_url":"https://api.github.com/users/brettwooldridge/gists{/gist_id}","starred_url":"https://api.github.com/users/brettwooldridge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brettwooldridge/subscriptions","organizations_url":"https://api.github.com/users/brettwooldridge/orgs","repos_url":"https://api.github.com/users/brettwooldridge/repos","events_url":"https://api.github.com/users/brettwooldridge/events{/privacy}","received_events_url":"https://api.github.com/users/brettwooldridge/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/brettwooldridge/NuProcess","description":"Low-overhead, non-blocking I/O, external Process implementation for Java","fork":false,"url":"https://api.github.com/repos/brettwooldridge/NuProcess","forks_url":"https://api.github.com/repos/brettwooldridge/NuProcess/forks","keys_url":"https://api.github.com/repos/brettwooldridge/NuProcess/keys{/key_id}","collaborators_url":"https://api.github.com/repos/brettwooldridge/NuProcess/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/brettwooldridge/NuProcess/teams","hooks_url":"https://api.github.com/repos/brettwooldridge/NuProcess/hooks","issue_events_url":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/events{/number}","events_url":"https://api.github.com/repos/brettwooldridge/NuProcess/events","assignees_url":"https://api.github.com/repos/brettwooldridge/NuProcess/assignees{/user}","branches_url":"https://api.github.com/repos/brettwooldridge/NuProcess/branches{/branch}","tags_url":"https://api.github.com/repos/brettwooldridge/NuProcess/tags","blobs_url":"https://api.github.com/repos/brettwooldridge/NuProcess/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/brettwooldridge/NuProcess/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/brettwooldridge/NuProcess/git/refs{/sha}","trees_url":"https://api.github.com/repos/brettwooldridge/NuProcess/git/trees{/sha}","statuses_url":"https://api.github.com/repos/brettwooldridge/NuProcess/statuses/{sha}","languages_url":"https://api.github.com/repos/brettwooldridge/NuProcess/languages","stargazers_url":"https://api.github.com/repos/brettwooldridge/NuProcess/stargazers","contributors_url":"https://api.github.com/repos/brettwooldridge/NuProcess/contributors","subscribers_url":"https://api.github.com/repos/brettwooldridge/NuProcess/subscribers","subscription_url":"https://api.github.com/repos/brettwooldridge/NuProcess/subscription","commits_url":"https://api.github.com/repos/brettwooldridge/NuProcess/commits{/sha}","git_commits_url":"https://api.github.com/repos/brettwooldridge/NuProcess/git/commits{/sha}","comments_url":"https://api.github.com/repos/brettwooldridge/NuProcess/comments{/number}","issue_comment_url":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/comments{/number}","contents_url":"https://api.github.com/repos/brettwooldridge/NuProcess/contents/{+path}","compare_url":"https://api.github.com/repos/brettwooldridge/NuProcess/compare/{base}...{head}","merges_url":"https://api.github.com/repos/brettwooldridge/NuProcess/merges","archive_url":"https://api.github.com/repos/brettwooldridge/NuProcess/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/brettwooldridge/NuProcess/downloads","issues_url":"https://api.github.com/repos/brettwooldridge/NuProcess/issues{/number}","pulls_url":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls{/number}","milestones_url":"https://api.github.com/repos/brettwooldridge/NuProcess/milestones{/number}","notifications_url":"https://api.github.com/repos/brettwooldridge/NuProcess/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/brettwooldridge/NuProcess/labels{/name}","releases_url":"https://api.github.com/repos/brettwooldridge/NuProcess/releases{/id}","created_at":"2013-08-07T07:50:14Z","updated_at":"2015-09-05T15:40:19Z","pushed_at":"2015-09-05T21:42:50Z","git_url":"git://github.com/brettwooldridge/NuProcess.git","ssh_url":"git@github.com:brettwooldridge/NuProcess.git","clone_url":"https://github.com/brettwooldridge/NuProcess.git","svn_url":"https://github.com/brettwooldridge/NuProcess","homepage":null,"size":1525,"stargazers_count":55,"watchers_count":55,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":14,"mirror_url":null,"open_issues_count":10,"forks":14,"open_issues":10,"watchers":55,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31"},"html":{"href":"https://github.com/brettwooldridge/NuProcess/pull/31"},"issue":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/31"},"comments":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/issues/31/comments"},"review_comments":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31/comments"},"review_comment":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/pulls/31/commits"},"statuses":{"href":"https://api.github.com/repos/brettwooldridge/NuProcess/statuses/40774e0f42d6b0176230fef517874ba62e510b4f"}}}}