-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PCRE2: optimize memory allocations #15395
base: master
Are you sure you want to change the base?
Changes from 15 commits
f24a948
93e141f
4aeeb47
b6ebabc
621fe5f
a14032e
f5da032
c225013
4b0accf
64458fb
19f631b
7487cb5
0cbd5e8
9fe3a62
72961ca
52f908d
8688b4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,33 @@ | ||||||||||||||||||||||||||||||
class Thread | ||||||||||||||||||||||||||||||
struct Local(T) | ||||||||||||||||||||||||||||||
# def initialize | ||||||||||||||||||||||||||||||
# {% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||||||||||||||||||||||||||||||
# end | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
# def initialize(&destructor : Proc(T, Nil)) | ||||||||||||||||||||||||||||||
# {% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||||||||||||||||||||||||||||||
# end | ||||||||||||||||||||||||||||||
Comment on lines
+3
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps these could be uncommented and then called via
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It avoids some repetition, but I'm not sure it would improve readability? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we could use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, you lost me @straight-shoota 😕
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fine to not support non pointer values. If we ever need to, we'll figure it out then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea for using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Errata: Box doesn't allocate into the GC heap when T is Nil or Reference but we want to store pointers and that will allocate. Maybe it's an overlook? 🤔 |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
def get : T | ||||||||||||||||||||||||||||||
get? || raise KeyError.new | ||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||
ysbaddaden marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
def get(& : -> T) : T | ||||||||||||||||||||||||||||||
get? || set(yield) | ||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
# def get? : T? | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
# def set(value : T) : T | ||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
{% if flag?(:wasi) %} | ||||||||||||||||||||||||||||||
require "./wasi/thread_local" | ||||||||||||||||||||||||||||||
{% elsif flag?(:unix) %} | ||||||||||||||||||||||||||||||
require "./unix/thread_local" | ||||||||||||||||||||||||||||||
{% elsif flag?(:win32) %} | ||||||||||||||||||||||||||||||
require "./win32/thread_local" | ||||||||||||||||||||||||||||||
{% else %} | ||||||||||||||||||||||||||||||
{% raise "Thread not supported" %} | ||||||||||||||||||||||||||||||
{% end %} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,30 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
require "c/pthread" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
class Thread | ||||||||||||||||||||||||||||||||||||||||||||||||||
struct Local(T) | ||||||||||||||||||||||||||||||||||||||||||||||||||
@key : LibC::PthreadKeyT | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
def initialize | ||||||||||||||||||||||||||||||||||||||||||||||||||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||||||||||||||||||||||||||||||||||||||||||||||||||
err = LibC.pthread_key_create(out @key, nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||
raise RuntimeError.from_os_error("pthread_key_create", Errno.new(err)) unless err == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
def initialize(&destructor : Proc(T, Nil)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||||||||||||||||||||||||||||||||||||||||||||||||||
err = LibC.pthread_key_create(out @key, destructor.unsafe_as(Proc(Void*, Nil))) | ||||||||||||||||||||||||||||||||||||||||||||||||||
raise RuntimeError.from_os_error("pthread_key_create", Errno.new(err)) unless err == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+7
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Extract the common code into a helper to remove duplication.
Suggested change
ditto for win32 |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
def get? : T? | ||||||||||||||||||||||||||||||||||||||||||||||||||
pointer = LibC.pthread_getspecific(@key) | ||||||||||||||||||||||||||||||||||||||||||||||||||
pointer.as(T) if pointer | ||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
def set(value : T) : T | ||||||||||||||||||||||||||||||||||||||||||||||||||
err = LibC.pthread_setspecific(@key, value.as(Void*)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
raise RuntimeError.from_os_error("pthread_setspecific", Errno.new(err)) unless err == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
value | ||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
class Thread | ||
struct Local(T) | ||
@value : T? | ||
|
||
def initialize | ||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||
end | ||
|
||
def initialize(&destructor : T ->) | ||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||
end | ||
|
||
def get? : T? | ||
@value | ||
end | ||
|
||
def set(value : T) : T | ||
@value = value | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
require "c/fibersapi" | ||
|
||
class Thread | ||
struct Local(T) | ||
@key : LibC::DWORD | ||
|
||
def initialize | ||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||
@key = LibC.FlsAlloc | ||
raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if @key == LibC::FLS_OUT_OF_INDEXES | ||
end | ||
|
||
def initialize(&destructor : Proc(T, Nil)) | ||
{% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %} | ||
@key = LibC.FlsAlloc(destructor.unsafe_as(Proc(Void*, Nil))) | ||
ysbaddaden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if @key == LibC::FLS_OUT_OF_INDEXES | ||
end | ||
|
||
def get? : T? | ||
pointer = LibC.FlsGetValue(@key) | ||
pointer.as(T) if pointer | ||
end | ||
|
||
def set(value : T) : T | ||
ret = LibC.FlsSetValue(@key, value.as(Void*)) | ||
raise RuntimeError.from_winerror("FlsSetValue") if ret == 0 | ||
value | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: cleanup before merge (not needed anymore).