# 2021-04-06 fdfdd12345628 ## 測驗 `4` `gcc -lpthread -march=native -latomic lab.c` callback 時 refcnt 要加一,結束時要減一,因此需要做兩次的 CAS 才可以 ```clike static bool execute_client_callback(bus_client_t *client, void *msg) { /* Load the client with which we are attempting to communicate. */ bus_client_t local_client; __atomic_load(client, &local_client, __ATOMIC_SEQ_CST); /* Loop until reference count isupdated or client becomes unregistered */ while (local_client.registered) { /* The expected reference count is the current one + 1 */ bus_client_t new_client = local_client; ++(new_client.refcnt); /* If CAS succeeds, the client had the expected reference count, and * we updated it successfully. If CAS fails, the client was updated * recently. The actual value is copied to local_client. */ if(CAS(&(client->refcnt), &(local_client.refcnt), &(new_client.refcnt))){ client->callback(client->ctx, msg); // Callback done, decrease reference count __atomic_load(client, &local_client, __ATOMIC_SEQ_CST); while(local_client.registered){ bus_client_t new_client = local_client; --(new_client.refcnt); if(CAS(&(client->refcnt), &(local_client.refcnt), &(new_client.refcnt))){ return true; } local_client.refcnt=client->refcnt; }// inner while return false; }// first CAS local_client.refcnt=client->refcnt; }// outer while /* Client was not registered or got unregistered while we attempted to send * a message */ return false; } ``` :::warning 注意要更新 reference count :notes: jserv ::: :::info 1. 已經將 local_client 的值在 CAS failed 後更新。 2. 已經用半形空白重新排版 > 程式碼排版:4 個半形空白 :::