rtl Turtle Grazing Putting Pressure On Seagrass By bernews.com Published On :: Sun, 06 Feb 2022 23:00:01 +0000 “In recent years green sea turtle grazing has put unprecedented pressure on Bermuda’s seagrass habitat resulting in the collapse of local beds, thus creating a conservation dilemma where one protected species, the green sea turtle, is causing the decline of other protected species, the seagrasses.” This is according to the report on the “State of Bermuda’s Marine […] Full Article All Environment News #BermudaMarine #Turtles
rtl ‘The Rise And Fall Of Bermuda’s Sea Turtle’ By bernews.com Published On :: Thu, 17 Feb 2022 13:52:32 +0000 Bermuda College and the Bermuda Environmental Sustainability Taskforce [BEST] have announced the return of their Eco Lunch & Learn series on Thursday, February 24. A spokesperson said, “The series begins its winter schedule with an illustrated presentation, ‘The Rise and Fall of Bermuda’s Sea Turtle.’ “Presenting will be Bermudian Jennifer Gray, Director of the Bermuda […] Full Article All Environment #BermudaCollege #BermudaEnvironmentalAndSustainabilityTaskforce #Turtles
rtl Aug 16: Juvenile Green Turtles Health Lecture By bernews.com Published On :: Wed, 10 Aug 2022 09:28:37 +0000 The Bermuda Zoological Society will be holding a Virtual Lecture Series installment titled “The health assessment of juvenile green turtles in Bermuda.” The lecture will held via Zoom on Tuesday, August 16 at 7.00pm and will be presented by Dr Gaelle Roth, MRCVS, Co-Director of the Bermuda Turtle Project. The event flyer says, “Discover something […] Full Article All Environment #Animal #BermudaMarine #SeminarsInBermuda #Turtles
rtl Reminder: Marine Turtles Are A Protected Species By bernews.com Published On :: Tue, 30 Aug 2022 23:40:02 +0000 Following a video circulating showing a person hanging on to a turtle, the Department of Environment and Natural Resources [DENR] reminded the public that marine turtles are afforded protection under the Protected Species Act 2003. A Government spokesperson said, “The Department of Environment and Natural Resources [DENR] wishes to remind the public that marine turtles […] Full Article All Environment News #Animal #BermudaMarine #Turtles
rtl “Name The PrivCom Turtle” Competition Winners By bernews.com Published On :: Mon, 13 Feb 2023 13:27:45 +0000 The Office of the Privacy Commissioner for Bermuda [PrivCom] announced the winners of the “Name the PrivCom Turtle” competition. A spokesperson said, “The P1 Bassett class at Heron Bay Primary School named our mascot “Isla”. As Isla is a female name, PrivCom decided to introduce Isla’s twin brother, “Islay”. The two are sure to add […] Full Article All News #Turtles
rtl Wallpaper Wednesday: Sea Turtle Cartoon By bernews.com Published On :: Wed, 08 Mar 2023 10:55:17 +0000 The latest design in Bernews’ weekly Wallpaper Wednesday series features a sea turtle cartoon, with the colourful animal depicted amongst other sea life. The design is available in two sizes; a Facebook profile cover image and also in a vertical format, ideally sized for use as a mobile phone wallpaper, WhatsApp status image or Instagram […] Full Article All Environment technology #Animal #BermudaMarine #FreeGraphics #GoodNews #Turtles #WallpaperWednesday
rtl ‘Effective Conservation Of Sea Turtle Species’ By bernews.com Published On :: Wed, 03 May 2023 15:39:41 +0000 The Sargasso Sea Commission and Inter-American Sea Turtle Convention signed an MOU aimed at “more effective conservation of sea turtle species and the habitats that they utilize.” A spokesperson said, “During the Inter-American Sea Turtle Convention [IAC] 16th Consultative Committee of Experts Meeting, Dr. David Freestone, Executive Secretary of the Sargasso Sea Commission, and Verónica […] Full Article All Environment News #Animal #GoodNews #SargassoSea #Turtles
rtl June 17: BUEI Kids Hour To Feature Sea Turtles By bernews.com Published On :: Thu, 15 Jun 2023 09:35:56 +0000 The Bermuda Underwater Exploration Institute [BUEI] iannounced that the topic for this month’s ‘Kids Hour Saturdays’ is Sea Turtles. A spokesperson said, “On Saturday, June 17th, at both 11am and 2pm, ‘Kids Hour’ will screen an episode of the TV series ‘Ocean Vet’ all about Bermuda’s Green Sea Turtles. This will be followed by a […] Full Article All Environment #Animal #BermudaMarine #BermudianChildren #Turtles
rtl Unsuccessful Attempts To Find Turtle In Difficulty By bernews.com Published On :: Fri, 22 Sep 2023 16:18:43 +0000 On Monday morning [Sept 18] local officials received a report of a “turtle in difficulty observed tangled in debris and plastic line,” prompting the RBR Coast Guard to search the area to try and assist the turtle, however unfortunately they were unable to locate it. A Bermuda Maritime Operations Centre spokesperson said, “Monday 18th September, […] Full Article All #Animal #BermudaMarine #InjuredAnimals #Turtles
rtl Video: ‘Scottie’ The Turtle Travels To Bermuda By bernews.com Published On :: Tue, 28 Nov 2023 00:50:52 +0000 A sea turtle found on a Nova Scotia beach in a “hypothermic and semi-comatose” state received care in Canada, and has now been transported to Bermuda to continue her recovery before being returned to the wild. The CBC reported, “An endangered green sea turtle found on a Nova Scotia beach has been revived and shipped […] Full Article All Environment News Videos #Animal #BermudaMarine #InjuredAnimals #Turtles
rtl Video: Sea Turtle ‘Scotti’ Released Into Wild By bernews.com Published On :: Fri, 26 Jan 2024 17:20:30 +0000 After being discovered “disoriented and cold-stunned” in Canada last November, a green sea turtle named ‘Scotti’ has been successfully rehabilitated in Bermuda and released back into the wild. The Bermuda Zoological Society posted the video below on Instagram and said, “A disoriented and cold-stunned green sea turtle found in Canada last November was released back […] Full Article All Environment News Videos #Animal #GoodNews #InjuredAnimals #Turtles
rtl Vladimír Mertlík: Je 35 let dost, nebo málo? Z žaláře národů, kolem ruského dubu až k padlým iluzím By www.reflex.cz Published On :: Tue, 12 Nov 2024 06:00:00 +0100 Zase budeme slavit i nadávat – jak kdo – na pětatřicet let od listopadu 1989. Uteklo to jako voda. Hodnotíme ten čas v průzkumech, jako bychom nevěděli, že vypovídají nejvíc o nás samých. Je to dost, nebo málo, těch pětatřicet let? Co jsme dokázali a co jsme pokazili? Ohlédněme se ve Zpětném zrcátku za tím, co zůstane potomkům, až budou hodnotit našich pětatřicet let. Začátky jsou vždycky plné slunce, slibů a těšení. Nevěsta je panensky bílá, ženich čestný a silný. Ona symbol věčné lásky, on pevnost pravdy. Proto si bez váhání slíbí věrnost až do smrti, neboť jen tak pravda a láska zvítězí nad lží a nenávistí… Hudba hraje, všichni se drží kolem ramen a vše vypadá tak snadné a nadějné… Jako budoucnost, než se stane přítomností. Takoví jsme byli, vzpomínáme pak po letech. Ale jací jsme vlastně byli? Full Article
rtl #56 Enlightenment – The Effortless Living of an Enlightened Life By www.enlightenmentpodcast.com Published On :: Fri, 20 Jul 2012 14:08:28 +0000 #56 Enlightenment - The Effortless Living of an Enlightened LifeThe post #56 Enlightenment – The Effortless Living of an Enlightened Life appeared first on Enlightenment Podcast. Full Article Advaita Vedanta Awareness Bliss emptiness Enlighten Enlightened Enlightenment Meditate Meditation meditation enlightenment Mindfulness no-self non-duality nonduality Peace Peak-Experiences Self-Actualization spiritual enlightenment Dr. Puff Dr. Robert Puff Enlightenment Podcast Mental Health Music by Kevin MacLeod Musings on "I Am That" Peak-Experience Podcast Self-Help
rtl TurtleWare: Dynamic Vars - A New Hope By turtleware.eu Published On :: Tue, 22 Oct 2024 00:00:00 GMT Table of Contents Dynamic Bindings The problem The solution Dynamic slots The context Summary Dynamic Bindings Common Lisp has an important language feature called dynamic binding. It is possible to rebind a dynamic variable somewhere on the call stack and downstream functions will see that new value, and when the stack is unwound, the old value is brought back. While Common Lisp does not specify multi-threading, it seems to be a consensus among various implementations that dynamic bindings are thread-local, allowing for controlling the computing context in a safe way. Before we start experiments, let's define a package to isolate our namespace: (defpackage "EU.TURTLEWARE.BLOG/DLET" (:local-nicknames ("MOP" #+closer-mop "C2MOP" #+(and (not closer-mop) ecl) "MOP" #+(and (not closer-mop) ccl) "CCL" #+(and (not closer-mop) sbcl) "SB-MOP")) (:use "CL")) (in-package "EU.TURTLEWARE.BLOG/DLET") Dynamic binding of variables is transparent to the programmer, because the operator LET is used for both lexical and dynamic bindings. For example: (defvar *dynamic-variable* 42) (defun test () (let ((*dynamic-variable* 15) (lexical-variable 12)) (lambda () (print (cons *dynamic-variable* lexical-variable))))) (funcall (test)) ;;; (42 . 12) (let ((*dynamic-variable* 'xx)) (funcall (test))) ;;; (xx . 12) Additionally the language specifies a special operator PROGV that gives the programmer a control over the dynamic binding mechanism, by allowing passing the dynamic variable by value instead of its name. Dynamic variables are represented by symbols: (progv (list '*dynamic-variable*) (list 'zz) (funcall (test))) ;;; (zz . 12) The problem Nowadays it is common to encapsulate the state in the instance of a class. Sometimes that state is dynamic. It would be nice if we could use dynamic binding to control it. That said slots are not variables, and if there are many objects of the same class with different states, then using dynamic variables defined with DEFVAR is not feasible. Consider the following classes which we want to be thread-safe: (defgeneric call-with-ink (cont window ink)) (defclass window-1 () ((ink :initform 'red :accessor ink))) (defmethod call-with-ink (cont (win window-1) ink) (let ((old-ink (ink win))) (setf (ink win) ink) (unwind-protect (funcall cont) (setf (ink win) old-ink)))) (defclass window-2 () ()) (defvar *ink* 'blue) (defmethod ink ((window window-2)) *ink*) (defmethod call-with-ink (cont (win window-2) ink) (let ((*ink* ink)) (funcall cont))) The first example is clearly not thread safe. If we access the WINDOW-1 instance from multiple threads, then they will overwrite a value of the slot INK. The second example is not good either, because when we have many instances of WINDOW-2 then they share the binding. Nesting CALL-WITH-INK will overwrite the binding of another window. The solution The solution is to use PROGV: (defclass window-3 () ((ink :initform (gensym)))) (defmethod initialize-instance :after ((win window-3) &key) (setf (symbol-value (slot-value win 'ink)) 'red)) (defmethod call-with-ink (cont (win window-3) ink) (progv (list (slot-value win 'ink)) (list ink) (funcall cont))) This way each instance has its own dynamic variable that may be rebound with a designated operator CALL-WITH-INK. It is thread-safe and private. We may add some syntactic sugar so it is more similar to let: (defmacro dlet (bindings &body body) (loop for (var val) in bindings collect var into vars collect val into vals finally (return `(progv (list ,@vars) (list ,@vals) ,@body)))) (defmacro dset (&rest pairs) `(setf ,@(loop for (var val) on pairs by #'cddr collect `(symbol-value ,var) collect val))) (defmacro dref (variable) `(symbol-value ,variable)) Dynamic slots While meta-classes are not easily composable, it is worth noting that we can mold it better into the language by specifying that slot itself has a dynamic value. This way CLOS aficionados will have a new tool in their arsenal. The approach we'll take is that a fresh symbol is stored as the value of each instance-allocated slot, and then accessors for the slot value will use these symbols as a dynamic variable. Here are low-level accessors: ;;; Accessing and binding symbols behind the slot. We don't use SLOT-VALUE, ;;; because it will return the _value_ of the dynamic variable, and not the ;;; variable itself. (defun slot-dvar (object slotd) (mop:standard-instance-access object (mop:slot-definition-location slotd))) (defun slot-dvar* (object slot-name) (let* ((class (class-of object)) (slotd (find slot-name (mop:class-slots class) :key #'mop:slot-definition-name))) (slot-dvar object slotd))) (defmacro slot-dlet (bindings &body body) `(dlet ,(loop for ((object slot-name) val) in bindings collect `((slot-dvar* ,object ,slot-name) ,val)) ,@body)) Now we'll define the meta-class. We need that to specialize functions responsible for processing slot definitions and the instance allocation. Notice, that we make use of a kludge to communicate between COMPUTE-EFFECTIVE-SLOT-DEFINITION and EFFECTIVE-SLOT-DEFINITION-CLASS – this is because the latter has no access to the direct slot definitions. ;;; The metaclass CLASS-WITH-DYNAMIC-SLOTS specifies alternative effective slot ;;; definitions for slots with an initarg :dynamic. (defclass class-with-dynamic-slots (standard-class) ()) ;;; Class with dynamic slots may be subclasses of the standard class. (defmethod mop:validate-superclass ((class class-with-dynamic-slots) (super standard-class)) t) ;;; When allocating the instance we initialize all slots to a fresh symbol that ;;; represents the dynamic variable. (defmethod allocate-instance ((class class-with-dynamic-slots) &rest initargs) (declare (ignore initargs)) (let ((object (call-next-method))) (loop for slotd in (mop:class-slots class) when (typep slotd 'dynamic-effective-slot) do (setf (mop:standard-instance-access object (mop:slot-definition-location slotd)) (gensym (string (mop:slot-definition-name slotd))))) object)) ;;; To improve potential composability of CLASS-WITH-DYNAMIC-SLOTS with other ;;; metaclasses we treat specially only slots that has :DYNAMIC in initargs, ;;; otherwise we call the next method. (defmethod mop:direct-slot-definition-class ((class class-with-dynamic-slots) &rest initargs) (loop for (key val) on initargs by #'cddr when (eq key :dynamic) do (return-from mop:direct-slot-definition-class (find-class 'dynamic-direct-slot))) (call-next-method)) ;;; The metaobject protocol did not specify an elegant way to communicate ;;; between the direct slot definition and the effective slot definition. ;;; Luckily we have dynamic bindings! :-) (defvar *kludge/mop-deficiency/dynamic-slot-p* nil) (defmethod mop:compute-effective-slot-definition ((class class-with-dynamic-slots) name direct-slotds) (if (typep (first direct-slotds) 'dynamic-direct-slot) (let* ((*kludge/mop-deficiency/dynamic-slot-p* t)) (call-next-method)) (call-next-method))) (defmethod mop:effective-slot-definition-class ((class class-with-dynamic-slots) &rest initargs) (declare (ignore initargs)) (if *kludge/mop-deficiency/dynamic-slot-p* (find-class 'dynamic-effective-slot) (call-next-method))) Finally we define a direct and an effective slot classes, and specialize slot accessors that are invoked by the instance accessors. ;;; There is a considerable boilerplate involving customizing slots. ;;; ;;; - direct slot definition: local to a single defclass form ;;; ;;; - effective slot definition: combination of all direct slots with the same ;;; name in the class and its superclasses ;;; (defclass dynamic-direct-slot (mop:standard-direct-slot-definition) ((dynamic :initform nil :initarg :dynamic :reader dynamic-slot-p))) ;;; DYNAMIC-EFFECTIVE-SLOT is implemented to return as slot-value values of the ;;; dynamic variable that is stored with the instance. ;;; ;;; It would be nice if we could specify :ALLOCATION :DYNAMIC for the slot, but ;;; then STANDARD-INSTANCE-ACCESS would go belly up. We could make a clever ;;; workaround, but who cares? (defclass dynamic-effective-slot (mop:standard-effective-slot-definition) ()) (defmethod mop:slot-value-using-class ((class class-with-dynamic-slots) object (slotd dynamic-effective-slot)) (dref (slot-dvar object slotd))) (defmethod (setf mop:slot-value-using-class) (new-value (class class-with-dynamic-slots) object (slotd dynamic-effective-slot)) (dset (slot-dvar object slotd) new-value)) (defmethod mop:slot-boundp-using-class ((class class-with-dynamic-slots) object (slotd dynamic-effective-slot)) (boundp (slot-dvar object slotd))) (defmethod mop:slot-makunbound-using-class ((class class-with-dynamic-slots) object (slotd dynamic-effective-slot)) (makunbound (slot-dvar object slotd))) With this, we can finally define a class with slots that have dynamic values. What's more, we may bind them like dynamic variables. ;;; Let there be light. (defclass window-4 () ((ink :initform 'red :dynamic t :accessor ink) (normal :initform 'normal :accessor normal)) (:metaclass class-with-dynamic-slots)) (let ((object (make-instance 'window-4))) (slot-dlet (((object 'ink) 15)) (print (ink object))) (print (ink object))) ContextL provides a similar solution with dynamic slots, although it provides much more, like layered classes. This example is much more self-contained. The context Lately I'm working on the repaint queue for McCLIM. While doing so I've decided to make stream operations thread-safe, so it is possible to draw on the stream and write to it from arbitrary thread asynchronously. The access to the output record history needs to be clearly locked, so that may be solved by the mutex. Graphics state is another story, consider the following functions running from separate threads: (defun team-red () (with-drawing-options (stream :ink +dark-red+) (loop for i from 0 below 50000 do (write-string (format nil "XXX: ~5d~%" i) stream)))) (defun team-blue () (with-drawing-options (stream :ink +dark-blue+) (loop for i from 0 below 50000 do (write-string (format nil "YYY: ~5d~%" i) stream)))) (defun team-pink () (with-drawing-options (stream :ink +deep-pink+) (loop for i from 0 below 25000 do (case (random 2) (0 (draw-rectangle* stream 200 (* i 100) 250 (+ (* i 100) 50))) (1 (draw-circle* stream 225 (+ (* i 100) 25) 25)))))) (defun gonow (stream) (window-clear stream) (time (let ((a (clim-sys:make-process #'team-red)) (b (clim-sys:make-process #'team-blue)) (c (clim-sys:make-process #'team-grue))) (bt:join-thread a) (bt:join-thread b) (bt:join-thread c) (format stream "done!~%"))) ) Operations like WRITE-STRING and DRAW-RECTANGLE can be implemented by holding a lock over the shared resource without much disruption. The drawing color on the other hand is set outside of the loop, so if we had locked the graphics state with a lock, then these functions would be serialized despite being called from different processes. The solution to this problem is to make graphics context a dynamic slot that is accessed with WITH-DRAWING-OPTIONS. Summary I hope that I've convinced you that dynamic variables are cool (I'm sure that majority of readers here are already convinced), and that dynamic slots are even cooler :-). Watch forward to the upcoming McCLIM release! If you like technical writeups like this, please consider supporting me on Patreon. Full Article
rtl TurtleWare: Dynamic Vars - The Empire Strikes Back By turtleware.eu Published On :: Mon, 28 Oct 2024 00:00:00 GMT Table of Contents Thread Local storage exhausted The layer of indirection I can fix her Let's write some tests! Summary Thread Local storage exhausted In the last post I've described a technique to use dynamic variables by value instead of the name by utilizing the operator PROGV. Apparently it works fine on all Common Lisp implementations I've tried except from SBCL, where the number of thread local variables is by default limited to something below 4000. To add salt to the injury, these variables are not garbage collected. Try the following code to crash into LDB: (defun foo () (loop for i from 0 below 4096 do (when (zerop (mod i 100)) (print i)) (progv (list (gensym)) (list 42) (values)))) (foo) This renders our new technique not very practical given SBCL popularity. We need to either abandon the idea or come up with a workaround. The layer of indirection Luckily for us we've already introduced a layer of indirection. Operators to access dynamic variables are called DLET, DSET and DREF. This means, that it is enough to provide a kludge implementation for SBCL with minimal changes to the remaining code. The old code works the same as previously except that instead of SYMBOL-VALUE we use the accessor DYNAMIC-VARIABLE-VALUE, and the old call to PROGV is now DYNAMIC-VARIABLE-PROGV. Moreover DYNAMIC-EFFECTIVE-SLOT used functions BOUNDP and MAKUNBOUND, so we replace these with DYNAMIC-VARIABLE-BOUND-P and DYNAMIC-VARIABLE-MAKUNBOUND. To abstract away things further we also introduce the constructor MAKE-DYNAMIC-VARIABLE (defpackage "EU.TURTLEWARE.BLOG/DLET" (:local-nicknames ("MOP" #+closer-mop "C2MOP" #+(and (not closer-mop) ecl) "MOP" #+(and (not closer-mop) ccl) "CCL" #+(and (not closer-mop) sbcl) "SB-MOP")) (:use "CL")) (in-package "EU.TURTLEWARE.BLOG/DLET") (eval-when (:compile-toplevel :execute :load-toplevel) (unless (member :bordeaux-threads *features*) (error "Please load BORDEAUX-THREADS.")) (when (member :sbcl *features*) (unless (member :fake-progv-kludge *features*) (format t "~&;; Using FAKE-PROGV-KLUDGE for SBCL.~%") (push :fake-progv-kludge *features*)))) (defmacro dlet (bindings &body body) (flet ((pred (binding) (and (listp binding) (= 2 (length binding))))) (unless (every #'pred bindings) (error "DLET: bindings must be lists of two values.~%~ Invalid bindings:~%~{ ~s~%~}" (remove-if #'pred bindings)))) (loop for (var val) in bindings collect var into vars collect val into vals finally (return `(dynamic-variable-progv (list ,@vars) (list ,@vals) ,@body)))) (defmacro dset (&rest pairs) `(setf ,@(loop for (var val) on pairs by #'cddr collect `(dref ,var) collect val))) (defmacro dref (variable) `(dynamic-variable-value ,variable)) ;;; ... (defmethod mop:slot-boundp-using-class ((class standard-class) object (slotd dynamic-effective-slot)) (dynamic-variable-bound-p (slot-dvar object slotd))) (defmethod mop:slot-makunbound-using-class ((class standard-class) object (slotd dynamic-effective-slot)) (dynamic-variable-makunbound (slot-dvar object slotd))) With these in place we can change the portable implementation to conform. #-fake-progv-kludge (progn (defun make-dynamic-variable () (gensym)) (defun dynamic-variable-value (variable) (symbol-value variable)) (defun (setf dynamic-variable-value) (value variable) (setf (symbol-value variable) value)) (defun dynamic-variable-bound-p (variable) (boundp variable)) (defun dynamic-variable-makunbound (variable) (makunbound variable)) (defmacro dynamic-variable-progv (vars vals &body body) `(progv ,vars ,vals ,@body))) I can fix her The implementation for SBCL will mediate access to the dynamic variable value with a synchronized hash table with weak keys. The current process is the key of the hash table and the list of bindings is the value of the hash table. For compatibility between implementations the top level value of the symbol will be shared. The variable +FAKE-UNBOUND+ is the marker that signifies, that the variable has no value. When the list of bindings is EQ to +CELL-UNBOUND+, then it means that we should use the global value. We add new bindings by pushing to it. #+fake-progv-kludge (progn (defvar +fake-unbound+ 'unbound) (defvar +cell-unbound+ '(no-binding)) (defclass dynamic-variable () ((tls-table :initform (make-hash-table :synchronized t :weakness :key) :reader dynamic-variable-tls-table) (top-value :initform +fake-unbound+ :accessor dynamic-variable-top-value))) (defun make-dynamic-variable () (make-instance 'dynamic-variable)) (defun dynamic-variable-bindings (dvar) (let ((process (bt:current-thread)) (tls-table (dynamic-variable-tls-table dvar))) (gethash process tls-table +cell-unbound+))) (defun (setf dynamic-variable-bindings) (value dvar) (let ((process (bt:current-thread)) (tls-table (dynamic-variable-tls-table dvar))) (setf (gethash process tls-table +cell-unbound+) value)))) We define two readers for the variable value - one that simply reads the value, and the other that signals an error if the variable is unbound. Writer for its value either replaces the current binding, or if the value cell is unbound, then we modify the top-level symbol value. We use the value +FAKE-UNBOUND+ to check whether the variable is bound and to make it unbound. #+fake-progv-kludge (progn (defun %dynamic-variable-value (dvar) (let ((tls-binds (dynamic-variable-bindings dvar))) (if (eq tls-binds +cell-unbound+) (dynamic-variable-top-value dvar) (car tls-binds)))) (defun dynamic-variable-value (dvar) (let ((tls-value (%dynamic-variable-value dvar))) (when (eq tls-value +fake-unbound+) (error 'unbound-variable :name "(unnamed)")) tls-value)) (defun (setf dynamic-variable-value) (value dvar) (let ((tls-binds (dynamic-variable-bindings dvar))) (if (eq tls-binds +cell-unbound+) (setf (dynamic-variable-top-value dvar) value) (setf (car tls-binds) value)))) (defun dynamic-variable-bound-p (dvar) (not (eq +fake-unbound+ (%dynamic-variable-value dvar)))) (defun dynamic-variable-makunbound (dvar) (setf (dynamic-variable-value dvar) +fake-unbound+))) Finally we define the operator to dynamically bind variables that behaves similar to PROGV. Note that we PUSH and POP from the thread-local hash table DYNAMIC-VARIABLE-BINDINGS, so no synchronization is necessary. #+fake-progv-kludge (defmacro dynamic-variable-progv (vars vals &body body) (let ((svars (gensym)) (svals (gensym)) (var (gensym)) (val (gensym))) `(let ((,svars ,vars)) (loop for ,svals = ,vals then (rest ,svals) for ,var in ,svars for ,val = (if ,svals (car ,svals) +fake-unbound+) do (push ,val (dynamic-variable-bindings ,var))) (unwind-protect (progn ,@body) (loop for ,var in ,svars do (pop (dynamic-variable-bindings ,var))))))) Let's write some tests! But of course, we are going to also write a test framework. It's short, I promise. As a bonus point the API is compatibile with fiveam, so it is possible to drop tests as is in the appropriate test suite. (defvar *all-tests* '()) (defun run-tests () (dolist (test (reverse *all-tests*)) (format *debug-io* "Test ~a... " test) (handler-case (funcall test) (serious-condition (c) (format *debug-io* "Failed: ~a~%" c)) (:no-error (&rest args) (declare (ignore args)) (format *debug-io* "Passed.~%"))))) (defmacro test (name &body body) `(progn (pushnew ',name *all-tests*) (defun ,name () ,@body))) (defmacro is (form) `(assert ,form)) (defmacro pass ()) (defmacro signals (condition form) `(is (block nil (handler-case ,form (,condition () (return t))) nil))) (defmacro finishes (form) `(is (handler-case ,form (serious-condition (c) (declare (ignore c)) nil) (:no-error (&rest args) (declare (ignore args)) t)))) Now let's get to tests. First we'll test our metaclass: (defclass dynamic-let.test-class () ((slot1 :initarg :slot1 :dynamic nil :accessor slot1) (slot2 :initarg :slot2 :dynamic t :accessor slot2) (slot3 :initarg :slot3 :accessor slot3)) (:metaclass class-with-dynamic-slots)) (defparameter *dynamic-let.test-instance-1* (make-instance 'dynamic-let.test-class :slot1 :a :slot2 :b :slot3 :c)) (defparameter *dynamic-let.test-instance-2* (make-instance 'dynamic-let.test-class :slot1 :x :slot2 :y :slot3 :z)) (test dynamic-let.1 (let ((o1 *dynamic-let.test-instance-1*) (o2 *dynamic-let.test-instance-2*)) (with-slots (slot1 slot2 slot3) o1 (is (eq :a slot1)) (is (eq :b slot2)) (is (eq :c slot3))) (with-slots (slot1 slot2 slot3) o2 (is (eq :x slot1)) (is (eq :y slot2)) (is (eq :z slot3))))) (test dynamic-let.2 (let ((o1 *dynamic-let.test-instance-1*) (o2 *dynamic-let.test-instance-2*)) (signals error (slot-dlet (((o1 'slot1) 1)) nil)) (slot-dlet (((o1 'slot2) :k)) (is (eq :k (slot-value o1 'slot2))) (is (eq :y (slot-value o2 'slot2)))))) (test dynamic-let.3 (let ((o1 *dynamic-let.test-instance-1*) (exit nil) (fail nil)) (flet ((make-runner (values) (lambda () (slot-dlet (((o1 'slot2) :start)) (let ((value (slot2 o1))) (unless (eq value :start) (setf fail value))) (loop until (eq exit t) do (setf (slot2 o1) (elt values (random (length values)))) (let ((value (slot2 o1))) (unless (member value values) (setf fail value) (setf exit t)))))))) (let ((r1 (bt:make-thread (make-runner '(:k1 :k2)))) (r2 (bt:make-thread (make-runner '(:k3 :k4)))) (r3 (bt:make-thread (make-runner '(:k5 :k6))))) (sleep .1) (setf exit t) (map nil #'bt:join-thread (list r1 r2 r3)) (is (eq (slot2 o1) :b)) (is (null fail)))))) Then let's test the dynamic variable itself: (test dynamic-let.4 "Test basic dvar operators." (let ((dvar (make-dynamic-variable))) (is (eql 42 (dset dvar 42))) (is (eql 42 (dref dvar))) (ignore-errors (dlet ((dvar :x)) (is (eql :x (dref dvar))) (error "foo"))) (is (eql 42 (dref dvar))))) (test dynamic-let.5 "Test bound-p operator." (let ((dvar (make-dynamic-variable))) (is (not (dynamic-variable-bound-p dvar))) (dset dvar 15) (is (dynamic-variable-bound-p dvar)) (dynamic-variable-makunbound dvar) (is (not (dynamic-variable-bound-p dvar))))) (test dynamic-let.6 "Test makunbound operator." (let ((dvar (make-dynamic-variable))) (dset dvar t) (is (dynamic-variable-bound-p dvar)) (finishes (dynamic-variable-makunbound dvar)) (is (not (dynamic-variable-bound-p dvar))))) (test dynamic-let.7 "Test locally bound-p operator." (let ((dvar (make-dynamic-variable))) (is (not (dynamic-variable-bound-p dvar))) (dlet ((dvar 15)) (is (dynamic-variable-bound-p dvar))) (is (not (dynamic-variable-bound-p dvar))))) (test dynamic-let.8 "Test locally unbound-p operator." (let ((dvar (make-dynamic-variable))) (dset dvar t) (is (dynamic-variable-bound-p dvar)) (dlet ((dvar nil)) (is (dynamic-variable-bound-p dvar)) (finishes (dynamic-variable-makunbound dvar)) (is (not (dynamic-variable-bound-p dvar)))) (is (dynamic-variable-bound-p dvar)))) (test dynamic-let.9 "Stress test the implementation (see :FAKE-PROGV-KLUDGE)." (finishes ; at the same time (let ((dvars (loop repeat 4096 collect (make-dynamic-variable)))) ;; ensure tls variable (loop for v in dvars do (dlet ((v 1)))) (loop for i from 0 below 4096 for r = (random 4096) for v1 in dvars for v2 = (elt dvars r) do (when (zerop (mod i 64)) (pass)) (dlet ((v1 42) (v2 43)) (values)))))) (test dynamic-let.0 "Stress test the implementation (see :FAKE-PROGV-KLUDGE)." (finishes ; can be gc-ed (loop for i from 0 below 4096 do (when (zerop (mod i 64)) (pass)) (dlet (((make-dynamic-variable) 42)) (values))))) All that is left is to test both dynamic variable implementations: BLOG/DLET> (lisp-implementation-type) "ECL" BLOG/DLET> (run-tests) Test DYNAMIC-LET.1... Passed. Test DYNAMIC-LET.2... Passed. Test DYNAMIC-LET.3... Passed. Test DYNAMIC-LET.4... Passed. Test DYNAMIC-LET.5... Passed. Test DYNAMIC-LET.6... Passed. Test DYNAMIC-LET.7... Passed. Test DYNAMIC-LET.8... Passed. Test DYNAMIC-LET.9... Passed. Test DYNAMIC-LET.0... Passed. NIL And with the kludge: BLOG/DLET> (lisp-implementation-type) "SBCL" BLOG/DLET> (run-tests) Test DYNAMIC-LET.1... Passed. Test DYNAMIC-LET.2... Passed. Test DYNAMIC-LET.3... Passed. Test DYNAMIC-LET.4... Passed. Test DYNAMIC-LET.5... Passed. Test DYNAMIC-LET.6... Passed. Test DYNAMIC-LET.7... Passed. Test DYNAMIC-LET.8... Passed. Test DYNAMIC-LET.9... Passed. Test DYNAMIC-LET.0... Passed. NIL Summary In this post we've made our implementation to work on SBCL even when there are more than a few thousand dynamic variables. We've also added a simple test suite that checks the basic behavior. As it often happens, after achieving some goal we get greedy and achieve more. That's the case here as well. In the next (and the last) post in this series I'll explore the idea of adding truly thread-local variables without a shared global value. This will be useful for lazily creating context on threads that are outside of our control. We'll also generalize the implementation so it is possible to subclass and implement ones own flavor of a dynamic variable. Full Article
rtl TurtleWare: Dynamic Vars - Return of the Jedi By turtleware.eu Published On :: Mon, 04 Nov 2024 00:00:00 GMT Table of Contents The protocol Control operators Synchronized hash tables with weakness First-class dynamic variables STANDARD-DYNAMIC-VARIABLE SURROGATE-DYNAMIC-VARIABLE Thread-local variables The protocol The implementation Thread-local slots What can we use it for? In the previous two posts I've presented an implementation of first-class dynamic variables using PROGV and a surrogate implementation for SBCL. Now we will double down on this idea and make the protocol extensible. Finally we'll implement a specialized version of dynamic variables where even the top level value of the variable is thread-local. The protocol Previously we've defined operators as either macros or functions. Different implementations were protected by the feature flag and symbols collided. Now we will introduce the protocol composed of a common superclass and functions that are specialized by particular implementations. Most notably we will introduce a new operator CALL-WITH-DYNAMIC-VARIABLE that is responsible for establishing a single binding. Thanks to that it will be possible to mix dynamic variables of different types within a single DLET statement. (defclass dynamic-variable () ()) (defgeneric dynamic-variable-bindings (dvar)) (defgeneric dynamic-variable-value (dvar)) (defgeneric (setf dynamic-variable-value) (value dvar)) (defgeneric dynamic-variable-bound-p (dvar)) (defgeneric dynamic-variable-makunbound (dvar)) (defgeneric call-with-dynamic-variable (cont dvar &optional value)) Moreover we'll define a constructor that is specializable by a key. This design will allow us to refer to the dynamic variable class by using a shorter name. We will also define the standard class to be used and an matching constructor. (defparameter *default-dynamic-variable-class* #-fake-progv-kludge 'standard-dynamic-variable #+fake-progv-kludge 'surrogate-dynamic-variable) (defgeneric make-dynamic-variable-using-key (key &rest initargs) (:method (class &rest initargs) (apply #'make-instance class initargs)) (:method ((class (eql t)) &rest initargs) (apply #'make-instance *default-dynamic-variable-class* initargs)) (:method ((class null) &rest initargs) (declare (ignore class initargs)) (error "Making a dynamic variable that is not, huh?"))) (defun make-dynamic-variable (&rest initargs) (apply #'make-dynamic-variable-using-key t initargs)) Control operators Control operators are the same as previously, that is a set of four macros that consume the protocol specified above. Note that DYNAMIC-VARIABLE-PROGV expands to a recursive call where each binding is processed separately. (defmacro dlet (bindings &body body) (flet ((pred (binding) (and (listp binding) (= 2 (length binding))))) (unless (every #'pred bindings) (error "DLET: bindings must be lists of two values.~%~ Invalid bindings:~%~{ ~s~%~}" (remove-if #'pred bindings)))) (loop for (var val) in bindings collect var into vars collect val into vals finally (return `(dynamic-variable-progv (list ,@vars) (list ,@vals) ,@body)))) (defmacro dset (&rest pairs) `(setf ,@(loop for (var val) on pairs by #'cddr collect `(dref ,var) collect val))) (defmacro dref (variable) `(dynamic-variable-value ,variable)) (defun call-with-dynamic-variable-progv (cont vars vals) (flet ((thunk () (if vals (call-with-dynamic-variable cont (car vars) (car vals)) (call-with-dynamic-variable cont (car vars))))) (if vars (call-with-dynamic-variable-progv #'thunk (cdr vars) (cdr vals)) (funcall cont)))) (defmacro dynamic-variable-progv (vars vals &body body) (let ((cont (gensym))) `(flet ((,cont () ,@body)) (call-with-dynamic-variable-progv (function ,cont) ,vars ,vals)))) Synchronized hash tables with weakness Previously we've used SBCL-specific options to define a synchronized hash table with weak keys. This won't do anymore, because we will need a similar object to implement the thread-local storage for top level values. trivial-garbage is a portability layer that allows to define hash tables with a specified weakness, but it does not provide an argument that would abstract away synchronization. We will ensure thread-safety with locks instead. (defclass tls-table () ((table :initform (trivial-garbage:make-weak-hash-table :test #'eq :weakness :key)) (lock :initform (bt:make-lock)))) (defun make-tls-table () (make-instance 'tls-table)) (defmacro with-tls-table ((var self) &body body) (let ((obj (gensym))) `(let* ((,obj ,self) (,var (slot-value ,obj 'table))) (bt:with-lock-held ((slot-value ,obj 'lock)) ,@body)))) First-class dynamic variables STANDARD-DYNAMIC-VARIABLE Previously in the default implementation we've represented dynamic variables with a symbol. The new implementation is similar except that the symbol is read from a STANDARD-OBJECT that represents the variable. This also enables us to specialize the function CALL-WITH-DYNAMIC-VARIABLE: (defclass standard-dynamic-variable (dynamic-variable) ((symbol :initform (gensym) :accessor dynamic-variable-bindings))) (defmethod dynamic-variable-value ((dvar standard-dynamic-variable)) (symbol-value (dynamic-variable-bindings dvar))) (defmethod (setf dynamic-variable-value) (value (dvar standard-dynamic-variable)) (setf (symbol-value (dynamic-variable-bindings dvar)) value)) (defmethod dynamic-variable-bound-p ((dvar standard-dynamic-variable)) (boundp (dynamic-variable-bindings dvar))) (defmethod dynamic-variable-makunbound ((dvar standard-dynamic-variable)) (makunbound (dynamic-variable-bindings dvar))) (defmethod call-with-dynamic-variable (cont (dvar standard-dynamic-variable) &optional (val nil val-p)) (progv (list (dynamic-variable-bindings dvar)) (if val-p (list val) ()) (funcall cont))) SURROGATE-DYNAMIC-VARIABLE The implementation of the SURROGATE-DYNAMIC-VARIABLE is almost the same as previously. The only difference is that we use the previously defined indirection to safely work with hash tables. Also note, that we are not add the feature condition - both classes is always created. (defvar +fake-unbound+ 'unbound) (defvar +cell-unbound+ '(no-binding)) (defclass surrogate-dynamic-variable (dynamic-variable) ((tls-table :initform (make-tls-table) :reader dynamic-variable-tls-table) (top-value :initform +fake-unbound+ :accessor dynamic-variable-top-value))) (defmethod dynamic-variable-bindings ((dvar surrogate-dynamic-variable)) (let ((process (bt:current-thread))) (with-tls-table (tls-table (dynamic-variable-tls-table dvar)) (gethash process tls-table +cell-unbound+)))) (defmethod (setf dynamic-variable-bindings) (value (dvar surrogate-dynamic-variable)) (let ((process (bt:current-thread))) (with-tls-table (tls-table (dynamic-variable-tls-table dvar)) (setf (gethash process tls-table) value)))) (defun %dynamic-variable-value (dvar) (let ((tls-binds (dynamic-variable-bindings dvar))) (if (eq tls-binds +cell-unbound+) (dynamic-variable-top-value dvar) (car tls-binds)))) (defmethod dynamic-variable-value ((dvar surrogate-dynamic-variable)) (let ((tls-value (%dynamic-variable-value dvar))) (when (eq tls-value +fake-unbound+) (error 'unbound-variable :name "(unnamed)")) tls-value)) (defmethod (setf dynamic-variable-value) (value (dvar surrogate-dynamic-variable)) (let ((tls-binds (dynamic-variable-bindings dvar))) (if (eq tls-binds +cell-unbound+) (setf (dynamic-variable-top-value dvar) value) (setf (car tls-binds) value)))) (defmethod dynamic-variable-bound-p ((dvar surrogate-dynamic-variable)) (not (eq +fake-unbound+ (%dynamic-variable-value dvar)))) (defmethod dynamic-variable-makunbound ((dvar surrogate-dynamic-variable)) (setf (dynamic-variable-value dvar) +fake-unbound+)) ;;; Apparently CCL likes to drop^Helide some writes and that corrupts bindings ;;; table. Let's ensure that the value is volatile. #+ccl (defvar *ccl-ensure-volatile* nil) (defmethod call-with-dynamic-variable (cont (dvar surrogate-dynamic-variable) &optional (val +fake-unbound+)) (push val (dynamic-variable-bindings dvar)) (let (#+ccl (*ccl-ensure-volatile* (dynamic-variable-bindings dvar))) (unwind-protect (funcall cont) (pop (dynamic-variable-bindings dvar))))) Thread-local variables We've refactored the previous code to be extensible. Now we can use metaobjects from the previous post without change. We can also test both implementations in the same process interchangeably by customizing the default class parameter. It is the time now to have some fun and extend dynamic variables into variables with top value not shared between different threads. This will enable ultimate thread safety. With our new protocol the implementation is trivial! The protocol First we will define the protocol class. THREAD-LOCAL-VARIABLE is a variant of a DYNAMIC-VARIABLE with thread-local top values. We specify initialization arguments :INITVAL and :INITFUN that will be used to assign the top value of a binding. The difference is that INITVAL specifies a single value, while INITFUN can produce an unique object on each invocation. INITARG takes a precedence over INTIFUN, and if neither is supplied, then a variable is unbound. We include the constructor that builds on MAKE-DYNAMIC-VARIABLE-USING-KEY, and macros corresponding to DEFVAR and DEFPARAMETER. Note that they expand to :INITFUN - this assures that the initialization form is re-evaluated for each new thread where the variable is used. (defclass thread-local-variable (dynamic-variable) ()) (defmethod initialize-instance :after ((self thread-local-variable) &key initfun initval) (declare (ignore self initfun initval))) (defparameter *default-thread-local-variable-class* #-fake-progv-kludge 'standard-thread-local-variable #+fake-progv-kludge 'surrogate-thread-local-variable) (defun make-thread-local-variable (&rest initargs) (apply #'make-dynamic-variable-using-key *default-thread-local-variable-class* initargs)) (defmacro create-tls-variable (&optional (form nil fp) &rest initargs) `(make-thread-local-variable ,@(when fp `(:initfun (lambda () ,form))) ,@initargs)) (defmacro define-tls-variable (name &rest initform-and-initargs) `(defvar ,name (create-tls-variable ,@initform-and-initargs))) (defmacro define-tls-parameter (name &rest initform-and-initargs) `(defparameter ,name (create-tls-variable ,@initform-and-initargs))) Perhaps it is a good time to introduce a new convention for tls variable names. I think that surrounding names with the minus sign is a nice idea, because it signifies, that it is something less than a global value. For example: DYNAMIC-VARS> (define-tls-variable -context- (progn (print "Initializing context!") (list :context))) -CONTEXT- DYNAMIC-VARS> -context- #<a EU.TURTLEWARE.DYNAMIC-VARS::STANDARD-THREAD-LOCAL-VARIABLE 0x7f7636c08640> DYNAMIC-VARS> (dref -context-) "Initializing context!" (:CONTEXT) DYNAMIC-VARS> (dref -context-) (:CONTEXT) DYNAMIC-VARS> (dset -context- :the-new-value) :THE-NEW-VALUE DYNAMIC-VARS> (dref -context-) :THE-NEW-VALUE DYNAMIC-VARS> (bt:make-thread (lambda () (print "Let's read it!") (print (dref -context-)))) #<process "Anonymous thread" 0x7f7637a26cc0> "Let's read it!" "Initializing context!" (:CONTEXT) DYNAMIC-VARS> (dref -context-) :THE-NEW-VALUE The implementation You might have noticed the inconspicuous operator DYNAMIC-VARIABLE-BINDINGS that is part of the protocol. It returns an opaque object that represents values of the dynamic variable in the current context: for STANDARD-DYNAMIC-VARIABLE it is a symbol for SURROGATE-DYNAMIC-VARIABLE it is a thread-local list of bindings In any case all other operators first take this object and then use it to read, write or bind the value. The gist of the tls variables implementation is to always return an object that is local to the thread. To store these objects we will use the tls-table we've defined earlier. (defclass thread-local-variable-mixin (dynamic-variable) ((tls-table :initform (make-tls-table) :reader dynamic-variable-tls-table) (tls-initfun :initarg :initfun :initform nil :accessor thread-local-variable-initfun) (tls-initval :initarg :initval :initform +fake-unbound+ :accessor thread-local-variable-initval))) For the class STANDARD-THREAD-LOCAL-VARIABLE we will simply return a different symbol depending on the thread: (defclass standard-thread-local-variable (thread-local-variable-mixin thread-local-variable standard-dynamic-variable) ()) (defmethod dynamic-variable-bindings ((tvar standard-thread-local-variable)) (flet ((make-new-tls-bindings () (let ((symbol (gensym)) (initval (thread-local-variable-initval tvar)) (initfun (thread-local-variable-initfun tvar))) (cond ((not (eq +fake-unbound+ initval)) (setf (symbol-value symbol) initval)) ((not (null initfun)) (setf (symbol-value symbol) (funcall initfun)))) symbol))) (let ((key (bt:current-thread))) (with-tls-table (tls-table (dynamic-variable-tls-table tvar)) (or (gethash key tls-table) (setf (gethash key tls-table) (make-new-tls-bindings))))))) And for the class SURROGATE-THREAD-LOCAL-VARIABLE the only difference from the SURROGATE-DYNAMIC-VARIABLE implementation is to cons a new list as the initial value (even when it is unbound) to ensure it is not EQ to +CELL-UNBOUND+. (defclass surrogate-thread-local-variable (thread-local-variable-mixin thread-local-variable surrogate-dynamic-variable) ()) (defmethod dynamic-variable-bindings ((tvar surrogate-thread-local-variable)) (flet ((make-new-tls-bindings () (let ((initval (thread-local-variable-initval tvar)) (initfun (thread-local-variable-initfun tvar))) (cond ((not (eq +fake-unbound+ initval)) (list initval)) ((not (null initfun)) (list (funcall initfun))) (t (list +fake-unbound+)))))) (let ((key (bt:current-thread))) (with-tls-table (tls-table (dynamic-variable-tls-table tvar)) (or (gethash key tls-table) (setf (gethash key tls-table) (make-new-tls-bindings))))))) That's all, now we have two implementations of thread-local variables. Ramifications are similar as with "ordinary" dynamic variables - the standard implementation is not advised for SBCL, because it will crash in LDB. Thread-local slots First we are going to allow to defined dynamic variable types with an abbreviated names. This will enable us to specify in the slot definition that type, for example (MY-SLOT :DYNAMIC :TLS :INITFORM 34) ;;; Examples how to add shorthand type names for the dynamic slots: (defmethod make-dynamic-variable-using-key ((key (eql :tls)) &rest initargs) (apply #'make-dynamic-variable-using-key *default-thread-local-variable-class* initargs)) (defmethod make-dynamic-variable-using-key ((key (eql :normal-tls)) &rest initargs) (apply #'make-dynamic-variable-using-key 'standard-thread-local-variable initargs)) (defmethod make-dynamic-variable-using-key ((key (eql :kludge-tls)) &rest initargs) (apply #'make-dynamic-variable-using-key 'surrogate-thread-local-variable initargs)) ;;; For *DEFAULT-DYNAMIC-VARIABLE* specify :DYNAMIC T. (defmethod make-dynamic-variable-using-key ((key (eql :normal-dyn)) &rest initargs) (apply #'make-dynamic-variable-using-key 'standard-dynamic-variable initargs)) (defmethod make-dynamic-variable-using-key ((key (eql :kludge-dyn)) &rest initargs) (apply #'make-dynamic-variable-using-key 'surrogate-dynamic-variable initargs)) In order to do that, we need to remember he value of the argument :DYNAMIC. We will read it with DYNAMIC-VARIABLE-TYPE and that value will be available in both direct and the effective slot: ;;; Slot definitions ;;; There is a considerable boilerplate involving customizing slots. ;;; ;;; - direct slot definition: local to a single defclass form ;;; ;;; - effective slot definition: combination of all direct slots with the same ;;; name in the class and its superclasses ;;; (defclass dynamic-direct-slot (mop:standard-direct-slot-definition) ((dynamic :initform nil :initarg :dynamic :reader dynamic-variable-type))) ;;; The metaobject protocol did not specify an elegant way to communicate ;;; between the direct slot definition and the effective slot definition. ;;; Luckily we have dynamic bindings! :-) (defvar *kludge/mop-deficiency/dynamic-variable-type* nil) ;;; DYNAMIC-EFFECTIVE-SLOT is implemented to return as slot-value values of the ;;; dynamic variable that is stored with the instance. ;;; ;;; It would be nice if we could specify :ALLOCATION :DYNAMIC for the slot, but ;;; then STANDARD-INSTANCE-ACCESS would go belly up. We could make a clever ;;; workaround, but who cares? (defclass dynamic-effective-slot (mop:standard-effective-slot-definition) ((dynamic :initform *kludge/mop-deficiency/dynamic-variable-type* :reader dynamic-variable-type))) Moreover we specialize the function MAKE-DYNAMIC-VARIABLE-USING-KEY to the effective slot class. The initargs in this method are meant for the instance. When the dynamic variable is created, we check whether it is a thread-local variable and initialize its INITVAL and INITFUN to values derived from INITARGS, MOP:SLOT-DEFINITION-INITARGS and MOP:SLOT-DEFINITION-INITFUN: (defmethod make-dynamic-variable-using-key ((key dynamic-effective-slot) &rest initargs) (let* ((dvar-type (dynamic-variable-type key)) (dvar (make-dynamic-variable-using-key dvar-type))) (when (typep dvar 'thread-local-variable) (loop with slot-initargs = (mop:slot-definition-initargs key) for (key val) on initargs by #'cddr when (member key slot-initargs) do (setf (thread-local-variable-initval dvar) val)) (setf (thread-local-variable-initfun dvar) (mop:slot-definition-initfunction key))) dvar)) The rest of the implementation of DYNAMIC-EFFECTIVE-SLOT is unchanged: (defmethod mop:slot-value-using-class ((class standard-class) object (slotd dynamic-effective-slot)) (dref (slot-dvar object slotd))) (defmethod (setf mop:slot-value-using-class) (new-value (class standard-class) object (slotd dynamic-effective-slot)) (dset (slot-dvar object slotd) new-value)) (defmethod mop:slot-boundp-using-class ((class standard-class) object (slotd dynamic-effective-slot)) (dynamic-variable-bound-p (slot-dvar object slotd))) (defmethod mop:slot-makunbound-using-class ((class standard-class) object (slotd dynamic-effective-slot)) (dynamic-variable-makunbound (slot-dvar object slotd))) The implementation of CLASS-WITH-DYNAMIC-SLOTS is also very similar. The first difference in that ALLOCATE-INSTANCE calls MAKE-DYNAMIC-VARIABLE-USING-KEY instead of MAKE-DYNAMIC-VARIABLE and supplies the effective slot definition as the key, and the instance initargs as the remaining arguments. Note that at this point initargs are already validated by MAKE-INSTANCE. The second difference is that MOP:COMPUTE-EFFECTIVE-SLOT-DEFINITION binds the flag *KLUDGE/MOP-DEFICIENCY/DYNAMIC-VARIABLE-TYPE* to DYNAMIC-VARIABLE-TYPE. ;;; This is a metaclass that allows defining dynamic slots that are bound with ;;; the operator SLOT-DLET, and, depending on the type, may have thread-local ;;; top value. ;;; ;;; The metaclass CLASS-WITH-DYNAMIC-SLOTS specifies alternative effective slot ;;; definitions for slots with an initarg :dynamic. (defclass class-with-dynamic-slots (standard-class) ()) ;;; Class with dynamic slots may be subclasses of the standard class. (defmethod mop:validate-superclass ((class class-with-dynamic-slots) (super standard-class)) t) ;;; When allocating the instance we initialize all slots to a fresh symbol that ;;; represents the dynamic variable. (defmethod allocate-instance ((class class-with-dynamic-slots) &rest initargs) (let ((object (call-next-method))) (loop for slotd in (mop:class-slots class) when (typep slotd 'dynamic-effective-slot) do (setf (mop:standard-instance-access object (mop:slot-definition-location slotd)) (apply #'make-dynamic-variable-using-key slotd initargs))) object)) ;;; To improve potential composability of CLASS-WITH-DYNAMIC-SLOTS with other ;;; metaclasses we treat specially only slots that has :DYNAMIC in initargs, ;;; otherwise we call the next method. (defmethod mop:direct-slot-definition-class ((class class-with-dynamic-slots) &rest initargs) (loop for (key) on initargs by #'cddr when (eq key :dynamic) do (return-from mop:direct-slot-definition-class (find-class 'dynamic-direct-slot))) (call-next-method)) (defmethod mop:compute-effective-slot-definition ((class class-with-dynamic-slots) name direct-slotds) (declare (ignore name)) (let ((latest-slotd (first direct-slotds))) (if (typep latest-slotd 'dynamic-direct-slot) (let ((*kludge/mop-deficiency/dynamic-variable-type* (dynamic-variable-type latest-slotd))) (call-next-method)) (call-next-method)))) (defmethod mop:effective-slot-definition-class ((class class-with-dynamic-slots) &rest initargs) (declare (ignore initargs)) (if *kludge/mop-deficiency/dynamic-variable-type* (find-class 'dynamic-effective-slot) (call-next-method))) Finally the implementation of SLOT-DLET does not change: ;;; Accessing and binding symbols behind the slot. We don't use SLOT-VALUE, ;;; because it will return the _value_ of the dynamic variable, and not the ;;; variable itself. (defun slot-dvar (object slotd) (check-type slotd dynamic-effective-slot) (mop:standard-instance-access object (mop:slot-definition-location slotd))) (defun slot-dvar* (object slot-name) (let* ((class (class-of object)) (slotd (find slot-name (mop:class-slots class) :key #'mop:slot-definition-name))) (slot-dvar object slotd))) (defmacro slot-dlet (bindings &body body) `(dlet ,(loop for ((object slot-name) val) in bindings collect `((slot-dvar* ,object ,slot-name) ,val)) ,@body)) Finally we can define a class with slots that do not share the top value: DYNAMIC-VARS> (defclass c1 () ((slot1 :initarg :slot1 :dynamic nil :accessor slot1) (slot2 :initarg :slot2 :dynamic t :accessor slot2) (slot3 :initarg :slot3 :dynamic :tls :accessor slot3)) (:metaclass class-with-dynamic-slots)) #<The EU.TURTLEWARE.DYNAMIC-VARS::CLASS-WITH-DYNAMIC-SLOTS EU.TURTLEWARE.DYNAMIC-VARS::C1> DYNAMIC-VARS> (with-slots (slot1 slot2 slot3) *object* (setf slot1 :x slot2 :y slot3 :z) (list slot1 slot2 slot3)) (:X :Y :Z) DYNAMIC-VARS> (bt:make-thread (lambda () (with-slots (slot1 slot2 slot3) *object* (setf slot1 :i slot2 :j slot3 :k) (print (list slot1 slot2 slot3))))) #<process "Anonymous thread" 0x7f76424c0240> (:I :J :K) DYNAMIC-VARS> (with-slots (slot1 slot2 slot3) *object* (list slot1 slot2 slot3)) (:I :J :Z) What can we use it for? Now that we know how to define thread-local variables, we are left with a question what can we use it for. Consider having a line-buffering stream. One possible implementation could be sketched as: (defclass line-buffering-stream (fancy-stream) ((current-line :initform (make-adjustable-string) :accessor current-line) (current-ink :initform +black+ :accessor current-ink))) (defmethod stream-write-char ((stream line-buffering-stream) char) (if (char= char # ewline) (terpri stream) (vector-push-extend char (current-line stream)))) (defmethod stream-terpri ((stream line-buffering-stream)) (%put-line-on-screen (current-line stream) (current-ink stream)) (setf (fill-pointer (current-line stream)) 0)) If this stream is shared between multiple threads, then even if individual operations and %PUT-LINE-ON-SCREEN are thread-safe , we have a problem. For example FORMAT writes are not usually atomic and individual lines are easily corrupted. If we use custom colors, these are also a subject of race conditions. The solution is as easy as making both slots thread-local. In that case the buffered line is private to each thread and it is put on the screen atomically: (defclass line-buffering-stream (fancy-stream) ((current-line :initform (make-adjustable-string) :accessor current-line :dynamic :tls) (current-ink :initform +black+ :accessor current-ink :dynamic :tls)) (:metaclass class-with-dynamic-slots)) Technique is not limited to streams. It may benefit thread-safe drawing, request processing, resource management and more. By subclassing DYNAMIC-VARIABLE we could create also variables that are local to different objects than processes. I hope that you've enjoyed reading this post as much as I had writing it. If you are interested in a full standalone implementation, with tests and system definitions, you may get it here. Cheers! Full Article
rtl One of the Strangest, Stealthiest Turtles You've Ever Seen By www.smithsonianmag.com Published On :: Mon, 21 Oct 2024 00:00:00 -0000 A mata mata turtle can go 15 minutes between breaths--it's another one of the Smithsonian's National Zoo's many unique animals. Join the Zoo's experts for an inside look at some of its 2,000 rare and extraordinary creatures. Full Article
rtl Yearlong Migration of the Kirtland's Warbler By www.smithsonianmag.com Published On :: Thu, 31 Oct 2024 00:00:00 -0000 Credit: Nathan Cooper Full Article
rtl After Months of Rehab, Moira the Cold-Stunned Sea Turtle Has Been Returned to the Wild By www.smithsonianmag.com Published On :: Mon, 04 Nov 2024 18:55:15 +0000 When fishermen found the endangered loggerhead sea turtle off Vancouver Island in February, she was listlessly floating in a bed of kelp Full Article
rtl Volunteers Scramble to Save Thousands of Sea Turtles Following Polar Vortex in Texas By www.smithsonianmag.com Published On :: Fri, 19 Feb 2021 21:19:34 +0000 As of last Wednesday, at least 3,500 sea turtles have been rescued from freezing waters in the midst record-breaking winter storm Full Article
rtl Man charged in crash deaths of 2 women who pulled over to save a turtle By www.cbc.ca Published On :: Tue, 12 Nov 2024 17:13:16 EST Police said they had pulled their car over and exited the vehicle in order to help a turtle cross the street, something a close family member told CBC at the time came as no surprise. Full Article News/Canada/Windsor
rtl DDA Warns Owners Of Red-Eared Slider Turtles About Potential Salmonella Risk By news.delaware.gov Published On :: Tue, 16 Mar 2021 15:44:16 +0000 The Delaware Department of Agriculture (DDA) is warning anyone who purchased turtles, specifically the red-eared slider turtle, between August 2020 and January 2021 to take extra precautions to prevent illness. Full Article Department of Agriculture News cdc Delaware Department of Agriculture DNREC Division of Fish and Wildlife exotic animal germs multi-state outbreak Permit red-eared slider turtle Salmonella Typhimurium small turtles
rtl Jasper C2RTL App for Datapath Verification By community.cadence.com Published On :: Wed, 13 Jul 2022 02:31:00 GMT Ensuring that the RTL designs correctly implement the C++ algorithmic intent in every circumstance is difficult to achieve with conventional verification. Learn more how Jasper C2RTL App helps to perform equivalence checking with 100x performance improvement(read more) Full Article Datapath Verification c2rtl Jasper C2RTL Equivalence Checking
rtl Achieve 80% Less Late-Stage RTL Changes and Early RTL Bug Detection By community.cadence.com Published On :: Tue, 16 Aug 2022 05:00:00 GMT It has become challenging to ensure that the designs are complete, correct, and adhere to necessary coding rules before handing them off for RTL verification and implementation. RTL Designer Signoff Solution from Cadence helps the user identify RTL bugs at a very early development stage, saving a lot of effort and cost for the design and verification team. Our reputed customers have confirmed that using RTL signoff for their design IP helped save up to 4 weeks and reduce the late-stage RTL changes by up to 80%.(read more) Full Article Jasper RTL Designer Signoff App Jasper Early Bug Detection
rtl Training Webinar: Fast Track RTL Debug with the Verisium Debug Python App Store By community.cadence.com Published On :: Thu, 24 Oct 2024 09:55:00 GMT As a verification engineer, you’re surely looking for ways to automate the debugging process. Have you developed your own scripts to ease specific debugging steps that tools don’t offer? Working with scripts locally and manually is challenging—so is reusing and organizing them. What if there was a way to create your own app with the required functionality and register it with the tool? The answer to that question is “Yes!” The Verisium Debug Python App Store lets you instantly add additional features and capabilities to your Verisium Debug Application using Python Apps that interact with Verisium Debug via the Python API. Join me, Principal Education Application Engineer Bhairava Prasad, for this Training Webinar and discover the Verisium Debug Python App Store. The app store allows you to search for existing apps, learn about them, install or uninstall them, and even customize existing apps. Date and Time Wednesday, November 20, 2024 07:00 PST San Jose / 10:00 EST New York / 15:00 GMT London / 16:00 CET Munich / 17:00 IST Jerusalem / 20:30 IST Bangalore / 23:00 CST Beijing REGISTER To register for this webinar, sign in with your Cadence Support account (email ID and password) to log in to the Learning and Support System*. Then select Enroll to register for the session. Once registered, you’ll receive a confirmation email containing all login details. A quick reminder: If you haven’t received a registration confirmation within one hour of registering, please check your spam folder and ensure your pop-up blockers are off and cookies are enabled. For issues with registration or other inquiries, reach out to eur_training_webinars@cadence.com . Like this topic? Take this opportunity and register for the free online course related to this webinar topic: Verisium Debug Training To view our complete training offerings, visit the Cadence Training website Want to share this and other great Cadence learning opportunities with someone else? Tell them to subscribe . Hungry for Training? Choose the Cadence Training Menu that’s right for you. Related Courses Xcelium Simulator Training Course | Cadence Related Blogs Unveiling the Capabilities of Verisium Manager for Optimized Operations - Verification - Cadence Blogs - Cadence Community Verisium SimAI: SoC Verification with Unprecedented Coverage Maximization - Corporate News - Cadence Blogs - Cadence Community Verisium SimAI: Maximizing Coverage, Minimizing Bugs, Unlocking Peak Throughput - Verification - Cadence Blogs - Cadence Community Related Training Bytes Introducing Verisium Debug (Video) (cadence.com) Introduction to UVM Debug of Verisium Debug (Video) (cadence.com) Verisium Debug Customized Apps with Python API Please see course learning maps a visual representation of courses and course relationships. Regional course catalogs may be viewed here . *If you don’t have a Cadence Support account, go to Cadence User Registration and complete the requested information. Or visit Registration Help . Full Article
rtl Technical Webinar: A Beginner’s Guide to RTL-to-GDSII Front-End Flow By community.cadence.com Published On :: Wed, 21 Aug 2024 06:23:00 GMT In this training webinar, we explore the concepts of RTL design, design verification, and coverage analysis while unveiling the exciting world of front-end design flow. We will guide you through the essential steps in creating integrated circuits, the building blocks of modern electronics. We’ll break down the process into manageable stages, from defining the chip’s functionality to its physical realization. We’ll investigate the front-end part of the RTL-to-GDSII flow—from specification to functional verification and design coverage—and explore: Key concepts of specifying chip behavior and performance How to translate ideas into a digital blueprint and transform that into a design How to ensure your design is free of errors This webinar provides practical knowledge, making it your gateway to understanding the magic behind RTL-to-GDSII front-end design flow. When Is the Webinar? Date and Time Wednesday, September 18, 202407:00 PDT San Jose / 10:00 EDT New York / 15:00 BST London / 16:00 CEST Munich / 17:00 IDT Jerusalem / 19:30 IST Bangalore / 22:00 CST Beijing REGISTER To register for this webinar, sign in with your Cadence Support account (email ID and password) to log in to the Learning and Support System. Then select Enroll to register for the session. Once registered, you’ll receive a confirmation email containing all login details. If you don’t have a Cadence Support account, go to Cadence User Registration and complete the requested information. Or visit Registration Help. For inquiries or issues with registration, reach out to eur_training@cadence.com.For inquiries or issues with registration, reach out to eur_training@cadence.com. To view our complete training offerings, visit the Cadence Training website. Want to share this and other great Cadence learning opportunities with someone else? Tell them to subscribe. Want to Learn More? This link gives you more information about the related training course and a link to enroll: Cadence RTL-to-GDSII Flow Training The course includes slides with audio and downloadable laboratory exercises designed to emphasize the topics covered in the lecture. There is also a Digital Badge available for the training. The online class is free for all Cadence customers with a Cadence Learning and Support Portal account. For instructor-led training sessions "Live" or "Blended" please contact Cadence Training. Also, take this opportunity to register for the free Online Trainings related to this webinar topic. Cadence RTL-to-GDSII Flow Xcelium Simulator Verilog Language and Application Xcelium Integrated Coverage Related Training Bytes How to Run the Synthesis Without DFT? How to Run the Synthesis Flow with DFT? (Video) Related Blogs Did You Miss the RTL-to-GDSII Webinar? No Worries, the Recording Is Available! Training Insights – Why Is RTL Translated into Gate-Level Netlist? Training Bytes: They May Be Shorter, But the Impact Is Stronger! Cadence Support - A Round-the-Clock Problem Solver, Webinar Recording Available! Full Article COS IMC IC DFT Integrated Metrics Center IP chip design webinars verification engineers Xcelium Logic Simulator training Mixed-Signal Logic Design coverage analysis RTL-to-GDSII FrontEnd training bytes system verilog Freshly Graduate Cadence RTL-to-GDSII Flow Technical webinar RTL2GDSII RTL design online training HLS VHDL vManager Verisuim
rtl Here Is the Recording of the RTL-to-GDSII Flow FrontEnd Webinar! By community.cadence.com Published On :: Mon, 28 Oct 2024 09:24:00 GMT In this recent Training Webinar, we explore the concepts of RTL design, design verification, and coverage analysis while unveiling the exciting world of front-end design flow by guiding you through essential steps involved in creating integrated circuits—the building blocks of modern electronics. We’ll break down the process into manageable stages, from defining the chip’s functionality to its physical realization. We’ll investigate the front-end part of the RTL-to-GDSII flow—from specification to functional verification and design coverage—and explore: Key concepts of specifying chip behavior and performance How to translate ideas into a digital blueprint and transform that into a design How to ensure your design is free of errors Watch the Training Webinar recording from September 18, 2024: A Beginner’s Guide to RTL-to-GDSII Front-End Flow Want to Learn More? This link gives you more information about this RTL-to-GDSII Flow, the related training course, and a link to enroll: Cadence RTL-to-GDSII Flow Training The course includes slides with audio and downloadable laboratory exercises designed to emphasize the topics covered in the lecture. There is also a Digital Badge available for the training. Also, take this opportunity to register for the free Online Training related to this Webinar Topic. Cadence RTL-to-GDSII Flow Xcelium Simulator Verilog Language and Application Learning Maps The online class is free for all Cadence customers with a Cadence Learning and Support Portal account. For instructor-led training sessions "Live" or "Blended" please contact Cadence Training. Related Training Bytes What is RTL Coding In VLSI Design? What is Digital Verification? What Is Synthesis in VLSI Design? What Is Logic Equivalence Checking in VLSI Design? What Is DFT in VLSI Design? What is Digital Implementation? What is Power Planning? What are DRC and LVS in Physical Verification? What are On-Chip Variations? Related Blogs Did You Miss the RTL-to-GDSII Webinar? No Worries, the Recording Is Available! Training Insights – Why Is RTL Translated into Gate-Level Netlist? Training Bytes: They May Be Shorter, But the Impact Is Stronger! Cadence Support - A Round-the-Clock Problem Solver, Webinar Recording Available! Full Article FrontEnd Design webinars verification engineers Cadence Online Support training coverage analysis xrun Cadence training flow xcelium simulator Design Engineers Training Webinar Cadence support RTL2GDSII Webinar
rtl The Most Startling Claim Ever Made, Part 1 By feeds.gty.org Published On :: Fri, 21 Jul 2017 00:00:00 PST Full Article
rtl The Most Startling Claim Ever Made, Part 2 By feeds.gty.org Published On :: Fri, 28 Jul 2017 00:00:00 PST Full Article
rtl Single atoms captured morphing into quantum waves in startling image By www.newscientist.com Published On :: Mon, 22 Apr 2024 18:00:30 +0100 In the 1920s, Erwin Schrödinger wrote an equation that predicts how particles-turned-waves should behave. Now, researchers are perfectly recreating those predictions in the lab Full Article
rtl Rachel Kushner’s Booker-shortlisted Creation Lake is top-notch By www.newscientist.com Published On :: Thu, 26 Sep 2024 15:15:00 +0100 For an undercover operative, Sadie Smith takes unnecessary risks as she infiltrates an eco-activist group. Why? And where do the Neanderthals fit into Creation Lake, Rachel Kushner's Booker-shortlisted climate fiction novel? Emily H. Wilson loved finding out Full Article
rtl New Tick-Borne Disease: 'Heartland Virus' By www.medicinenet.com Published On :: Mon, 29 Aug 2022 00:00:00 PDT Title: New Tick-Borne Disease: 'Heartland Virus'Category: Health NewsCreated: 8/30/2012 11:00:00 AMLast Editorial Review: 8/30/2012 12:00:00 AM Full Article
rtl Another Outbreak of Salmonella Traced to Pet Turtles By www.medicinenet.com Published On :: Mon, 29 Aug 2022 00:00:00 PDT Title: Another Outbreak of Salmonella Traced to Pet TurtlesCategory: Health NewsCreated: 8/30/2017 12:00:00 AMLast Editorial Review: 8/31/2017 12:00:00 AM Full Article
rtl De novo genome assemblies of two cryptodiran turtles with ZZ/ZW and XX/XY sex chromosomes provide insights into patterns of genome reshuffling and uncover novel 3D genome folding in amniotes [RESEARCH] By genome.cshlp.org Published On :: 2024-10-29T06:46:07-07:00 Understanding the evolution of chromatin conformation among species is fundamental to elucidate the architecture and plasticity of genomes. Nonrandom interactions of linearly distant loci regulate gene function in species-specific patterns, affecting genome function, evolution, and, ultimately, speciation. Yet, data from nonmodel organisms are scarce. To capture the macroevolutionary diversity of vertebrate chromatin conformation, here we generate de novo genome assemblies for two cryptodiran (hidden-neck) turtles via Illumina sequencing, chromosome conformation capture, and RNA-seq: Apalone spinifera (ZZ/ZW, 2n = 66) and Staurotypus triporcatus (XX/XY, 2n = 54). We detected differences in the three-dimensional (3D) chromatin structure in turtles compared to other amniotes beyond the fusion/fission events detected in the linear genomes. Namely, whole-genome comparisons revealed distinct trends of chromosome rearrangements in turtles: (1) a low rate of genome reshuffling in Apalone (Trionychidae) whose karyotype is highly conserved when compared to chicken (likely ancestral for turtles), and (2) a moderate rate of fusions/fissions in Staurotypus (Kinosternidae) and Trachemys scripta (Emydidae). Furthermore, we identified a chromosome folding pattern that enables "centromere–telomere interactions" previously undetected in turtles. The combined turtle pattern of "centromere–telomere interactions" (discovered here) plus "centromere clustering" (previously reported in sauropsids) is novel for amniotes and it counters previous hypotheses about amniote 3D chromatin structure. We hypothesize that the divergent pattern found in turtles originated from an amniote ancestral state defined by a nuclear configuration with extensive associations among microchromosomes that were preserved upon the reshuffling of the linear genome. Full Article
rtl RPG Cast – Episode 572: “Partly Cloudy Souls With a Chance of Roguelike” By rpgamer.com Published On :: Sat, 06 Feb 2021 22:55:03 +0000 Josh is having an Ys-y time. Anna Marie ranks all the slime families. Robert gets notified every time google kills a product. And Chris tells everyone to blink on cue. The post RPG Cast – Episode 572: “Partly Cloudy Souls With a Chance of Roguelike” appeared first on RPGamer. Full Article News Podcasts RPG Cast Children of Zodiarcs Dragon Quest Tact Final Fantasy Brave Exvius Giraffe and Annika Hyrule Warriors: Age of Calamity Suikoden V The Legend of Heroes: Trails of Cold Steel IV Ys IX
rtl Halo's most disgusting enemy was partly inspired by a children's book By www.rockpapershotgun.com Published On :: Mon, 11 Nov 2024 13:18:45 +0000 It was the 20-year anniversary of Halo 2 at the weekend, which saw the shooter's modern counterparts celebrating with classic multiplayer maps and long-lost levels. But also emerging from the dust of time are insights to the sequel's development back in 2004. Rolling Stone interviewed two key designers of the game and made a fun discovery. The Flood (the sickly pale alien infestation that briefly turns Halo into sci-fi horror) was partly inspired by a colourful and innocent children's book about a nice elephant. Read more Full Article 343 Industries Third person Microsoft Xbox Series X/S Action Adventure Single Player Xbox One Halo Infinite Science Fiction Halo: The Master Chief Collection Xbox Multiplayer Competitive Multiplayer Cooperative PC Microsoft Studios Shooter: First Person Blockbuster First person Xbox Game Studios Bungie Shooter Halo 2
rtl Gary Lineker questions Spoty shortlist... hours before presenting the show By www.telegraph.co.uk Published On :: Wed, 21 Dec 2022 13:19:23 GMT Full Article topics:events/sports-personality-year topics:people/gary-linekar topics:events/us-open topics:organisations/bbc structure:sport storytype:standard
rtl Mary Earps and Stuart Broad on BBC Sports Personality of the Year shortlist By www.telegraph.co.uk Published On :: Tue, 12 Dec 2023 09:46:26 GMT Full Article topics:people/stuart-broad topics:people/rory-mcilroy topics:people/katarina-johnson-thompson topics:events/sports-personality-year structure:womens-sport structure:womens-football structure:cricket structure:golf structure:racing structure:tennis structure:athletics structure:paralympic-sport storytype:standard
rtl From Prolonging Wallaby Pregnancies to Disorienting Hatchling Turtles, 11 Ways Artificial Lights Affect Animals By www.smithsonianmag.com Published On :: Mon, 28 Oct 2024 16:00:00 +0000 From the busy cities to ocean waters, our need to illuminate the world has had some strange and tragic consequences Full Article
rtl Justin Hartley's Ex-Wife and Daughter Support Him As Chrishell Stause Split Plays Out on 'Selling Sunset' By feedproxy.google.com Published On :: Tue, 11 Aug 2020 18:07:57 PDT The actor is getting some support from his ex-wife, Lindsay Hartley, and daughter, Bella. [[ This is a content summary only. Visit my website for full links, other content, and more! ]] Full Article News
rtl Canadian soccer great Christine Sinclair's pro career ends as Portland Thorns eliminated from NWSL playoffs By www.cbc.ca Published On :: Sun, 10 Nov 2024 17:58:42 EST Canadian soccer great Christine Sinclair played her final pro game on Sunday when her Portland Thorns were eliminated from the NWSL playoffs by Gotham FC. Full Article Sports/Soccer
rtl STARLINK satellite falls to Earth; Nerve-racking for Americans in Heartland... By www.dailystar.co.uk Published On :: 2024-11-13T06:19:37Z STARLINK satellite falls to Earth; Nerve-racking for Americans in Heartland... (Second column, 1st story, link) Full Article
rtl Once-big Portland tech employer lays off dozens By www.bizjournals.com Published On :: Tue, 12 Nov 2024 22:11:36 +0000 A year after going private in a $6.5 billion private equity deal, software maker New Relic is into its second round of layoffs this year. Full Article
rtl Sea Turtle Ears Inspire a New Heart Monitor Design By spectrum.ieee.org Published On :: Thu, 02 May 2024 14:14:33 +0000 This article is part of our exclusive IEEE Journal Watch series in partnership with IEEE Xplore.Sea turtles are remarkable creatures for a number of reasons, including the way they hear underwater—not through openings in the form of ears, but by detecting vibrations directly through the skin covering their auditory system. Inspired by this ability to detect sound through skin, researchers in China have created a heart-monitoring system, which initial tests in humans suggest may be a viable for monitoring heartbeats. A key way in which doctors monitor heart health involves “listening” to the heartbeat, either using a stethoscope or more sophisticated technology, like echocardiograms. However, these approaches require a visit to a specialist, and so researchers have been keen to develop alternative, lower cost solutions that people can use at home, which could also allow for more frequent testing and monitoring. Junbin Zang, a lecturer at the North University of China, and his colleagues specialize in creating heart-monitoring technologies. Their interest was piqued when they learned about the inner workings of the sea turtle’s auditory system, which is able to detect low-frequency signals, especially in the 300- to 400-hertz range.“Heart sounds are also low-frequency signals, so the low-frequency characteristics of the sea turtle’s ear have provided us with great inspiration,” explains Zang. At a glance, it looks like turtles don’t have ears. Their auditory system instead lies under a layer of skin and fat, through which it picks up vibrations. As with humans, a small bone in the ear vibrates as sounds hit it, and as it oscillates, those pulses are converted to electrical signals that are sent to the brain for processing and interpretation. iStock But sea turtles have a unique, slender T-shaped conduit that encapsulates their ear bones, restricting the movement of the similarly T-shaped ear bones to only vibrate in a perpendicular manner. This design provides their auditory system with high sensitivity to vibrations. Zang and his colleagues set out to create a heart monitoring system with similar features. They created a T-shaped heart-sound sensor that imitates the ear bones of sea turtles using a tiny MEMS cantilever beam sensor. As sound hits the sensor, the vibrations cause deformations in its beam, and the fluctuations in the voltage resistance are then translated into electrical signals. The researchers first tested the sensor’s ability to detect sound in lab tests, and then tested the sensor’s ability to monitor heartbeats in two human volunteers in their early 20s. The results, described in a study published 1 April in IEEE Sensors Journal, show that the sensor can effectively detect the two phases of a heartbeat.“The sensor exhibits excellent vibration characteristics,” Zang says, noting that it has a higher vibration sensitivity compared to other accelerometers on the market. However, the sensor currently picks up a significant amount of background noise, which Zang says his team plans to address in future work. Ultimately, they are interested in integrating this novel bioinspired sensor into devices they have previously created—including portable handheld and wearable versions, and a relatively larger version for use in hospitals—for the simultaneous detection of electrocardiogram and phonocardiogram signals. This article appears in the July 2024 print issue as “Sea Turtles Inspire Heart-Monitor Design.” Full Article Heart monitor Biosensors Journal watch
rtl Teenage Mutant Ninja Turtles Rev Up and Sprint Into Action - Now That's Fast! - T-SPRINTS COMMERCIAL By www.multivu.com Published On :: 08 Dec 2015 11:55:00 EST T-SPRINTS COMMERCIAL Full Article Entertainment Household Consumer Cosmetics Retail New Products Services Broadcast Feed Announcements MultiVu Video
rtl Turtle Beach Reinvents eSports Gaming Headsets With The Elite Pro - A New Benchmark For Competitive Gaming Audio Performance And Comfort - Turtle Beach Reveals the All-New Elite Pro By www.multivu.com Published On :: 04 May 2016 08:35:00 EDT Turtle Beach Reveals the All-New Elite Pro Full Article Computer Hardware Computer Software Consumer Electronics Sports Electronic Gaming Sports Equipment & Accessories New Products Services Broadcast Feed Announcements MultiVu Video
rtl Heartless Owner Returns Cat to Shelter Because She ‘Wanted to Cuddle Them at Night’, Then Her New Hooman Un-Breaks Our Hearts and Shows She’s Living Her Snuggliest Life Now By cheezburger.com Published On :: Mon, 11 Nov 2024 06:00:00 -0800 Look, we have heard stories of cats being returned to shelters. We have heard people say that they felt like they had no choice. The couldn't afford taking care of a cat anymore, they found out they were allergic… there are all kinds of reasons. At least everyone who returns a cat is a heartbroken, at least that's what we thought. We never imagined that someone would do it because the cat they adopted wanted to cuddle with them at nighttime. Everyone wants a velcro cat, right? Cuddly cats are the best! Cuddling with your cat is one of the best feelings in the world. The trust they show you, the love, the calmness that being so close to them gives you… there is nothing quite like it. To complain about a cat being too cuddly is like complaining about something being too tasty. It's silly. And ridiculous. And thank goodness that this sweet girl is now in the hands of someone who actually deserves her. Full Article aww wholesome cat adorable adoption heartwarming cute adopted story Cats rescue
rtl 'Ageing gracefully': Kareena Kapoor goes bold in bikini; captures shirtless Saif Ali Khan in Maldives By www.ibtimes.co.in Published On :: Sun, 10 Nov 2024 14:53:18 +0530 Taking to her Instagram handle, Kareena shared photos and wrote, "Saturday selfies with one thrown in of the husband." In the photos, Kareena opted for no-makeup look as she flaunted her natural beauty. Saif Ali Khan looked handsome in neon colour pants. Full Article
rtl Amazon Launches AI-Powered X-Ray Recaps on Prime Video for Effortless Episode Catch-Up By www.gizbot.com Published On :: Tue, 05 Nov 2024 12:10:02 +0530 Amazon is expanding its Prime Video features with the introduction of X-Ray Recaps, a generative AI-powered tool designed to help users quickly get back into their favorite shows without missing a beat. This new addition to Prime Video’s suite of X-Ray Full Article
rtl Ananya Panday-Inspired Simple Makeup for Diwali: 7-Step Guide for an Effortless Glow By www.boldsky.com Published On :: Sat, 26 Oct 2024 15:48:39 +0530 Diwali celebrations equal spreading joy, devotion, and looking your ethnic best. The right makeup look adds elegance and glow. 'Bae' of Bollywood Ananya Panday is quite famous for her understated yet chic style, and her subtle makeup avatar is ideal for Full Article