Armin Rigo avatar Armin Rigo committed bcb3380

Comments; fix allocate_object_of_size()

Comments (0)

Files changed (4)

rpython/memory/gc/stmtls.py

             fatalerror("malloc in a non-main thread but outside a transaction")
         if llmemory.raw_malloc_usage(size) > self.nursery_size // 8 * 7:
             fatalerror("XXX object too large to ever fit in the nursery")
+        #
+        self.local_collection(run_finalizers=True)
+        #
+        # call this here in case another thread is waiting for a global GC
         self.stm_operations.should_break_transaction()
-        step = 0
-        while True:
-            free = self.nursery_free
-            top  = self.nursery_top
-            if (top - free) >= llmemory.raw_malloc_usage(size):
-                return free
-            ll_assert(step < 2, "nursery must be empty [0]")
-            self.local_collection(run_finalizers=(step==0))
-            step += 1
+        #
+        # if we have now enough space, return it
+        free = self.nursery_free
+        top  = self.nursery_top
+        if (top - free) >= llmemory.raw_malloc_usage(size):
+            return free
+        #
+        # no, it might be because we ran finalizers or did a global GC.
+        # Try again without running the finalizers.
+        self.local_collection(run_finalizers=False)
+        #
+        # now we must have enough space
+        free = self.nursery_free
+        top  = self.nursery_top
+        if (top - free) >= llmemory.raw_malloc_usage(size):
+            return free
+        #
+        ll_assert(False,
+                  "local_collection(run_finalizers=0) didn't free enough mem")
+        return NULL
 
     def is_in_nursery(self, addr):
         ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0,

rpython/rlib/rstm.py

 def abort_and_retry():
     stmgcintf.StmOperations.abort_and_retry()
 
-def start_single_thread():
-    stmgcintf.StmOperations.start_single_thread()
-
-def stop_single_thread():
-    stmgcintf.StmOperations.stop_single_thread()
-
 def before_external_call():
     if not is_atomic():
         e = get_errno()

rpython/translator/stm/src_stm/et.c

 static volatile revision_t next_locked_value = LOCKED + 3;   /* always odd */
 static __thread struct tx_descriptor *thread_descriptor = NULL;
 
+/* a multi-reader, single-writer lock: transactions normally take a reader
+   lock, so don't conflict with each other; when we need to do a global GC,
+   we take a writer lock to "stop the world".  Note the initializer here,
+   which should give the correct priority for reached_safe_point(). */
 static pthread_rwlock_t rwlock_in_transaction =
          PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP;
 

rpython/translator/stm/src_stm/rpyintf.c

     {
       err = pthread_rwlock_unlock(&rwlock_in_transaction);
       assert(err == 0);
+      /* another thread should be waiting in pthread_rwlock_wrlock(),
+         which takes priority here */
       err = pthread_rwlock_rdlock(&rwlock_in_transaction);
       assert(err == 0);
     }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.