Changeset f3dbe27 in mainline for kernel/generic/src/proc/thread.c


Ignore:
Timestamp:
2023-04-18T17:33:02Z (18 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
117ad5a2
Parents:
06f81c4
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-04-18 17:27:32)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-04-18 17:33:02)
Message:

Reduce locking further with lazy FPU

It turns out we only need a lock to synchronize between the trap
handler and thread destructor. The atomic operations introduced
are just plain reads and writes, written in an ugly fashion to
appease C11 undefined behavior gods.

In principle we could get rid of that if we made cpu_t::fpu_owner
a strong reference, but that would mean a thread structure could
be held in limbo indefinitely if a new thread is not being
scheduled or doesn't use FPU.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/thread.c

    r06f81c4 rf3dbe27  
    415415#ifdef CONFIG_FPU_LAZY
    416416        if (thread->cpu) {
     417                /*
     418                 * We need to lock for this because the old CPU can concurrently try
     419                 * to dump this thread's FPU state, in which case we need to wait for
     420                 * it to finish. An atomic compare-and-swap wouldn't be enough.
     421                 */
    417422                irq_spinlock_lock(&thread->cpu->fpu_lock, false);
    418                 if (thread->cpu->fpu_owner == thread)
    419                         thread->cpu->fpu_owner = NULL;
     423
     424                thread_t *owner = atomic_load_explicit(&thread->cpu->fpu_owner,
     425                    memory_order_relaxed);
     426
     427                if (owner == thread) {
     428                        atomic_store_explicit(&thread->cpu->fpu_owner, NULL,
     429                            memory_order_relaxed);
     430                }
     431
    420432                irq_spinlock_unlock(&thread->cpu->fpu_lock, false);
    421433        }
Note: See TracChangeset for help on using the changeset viewer.