contrubuted by <yaohwang99
>
Set lock
and locker
to 0
If lock
is 0
, swap the value of lock
with the address of itself, then return.
If lock
is not 0
, then the value is the address of itself, swap with the address of itself until the value is changed by other thread calling spin_release
to set lck
to 0
.
The instuction xchg
swaps %al
with (%rax)
, which means swap the last byte of %rax
with *lck
. where %rax
stores the value of lck
.
By my understanding, the lock works by swaping tha least significant byte of it's address, which is not 0x00.
I also don't understand why locker
exists.
Mutex lock is almost the same as spin lock except that it uses system call and futex to sleep (line 12) until FUTEX_WAKE
(line 28).
At line17, init()
will only be called by the first cloned thread because static
variables will ony be initialized once.
CLONE_VM: the calling process and the child process run in the same memory space.
CLONE_FS: the caller and the child process share the same filesystem information.
CLONE_FILES: the calling process and the child process share the same file descriptor table.
CLONE_SIGHAND: the calling process and the child process share the same table of signal handlers.
CLONE_THREAD: the child is placed in the same thread group as the calling process.
CLONE_SYSVSEM: the child and the calling process share a single list of System V semaphore adjustment (semadj) values (see semop(2)).
CLONE_CHILD_CLEARTID: Clear (zero) the child thread ID at the location pointed to by child_tid (clone()) or cl_args.child_tid (clone3()) in child memory when the child exits, and do a wakeup on the futex at that address. The address involved may be changed by the set_tid_address(2) system call. This is used by threading libraries.
CLONE_PARENT_SETTID: Store the child thread ID at the location pointed to by parent_tid (clone()) or cl_args.parent_tid (clone3()) in the parent's memory.
thread_create wrap routine
The above function will create a new thread with a new tid, where tid
, node->tid
, and node->tid_copy
has the same value.
Because the flag include CLONE_CHILD_CLEARTID
and CLONE_PARENT_SETTID
, the function should clear node->tid
to 0 and set node->tid
to tid
and return tid
.
When there are multiple reader entering the critical section, rwlock
is acquired by the first reader and released by the last reader, preventing dead lock.
KKKK: &prev->next
QQQQ: &map->bucket[]
ZZZZ: &prev->next