/* * This is called by the efd item code below to release references to the given * efi item. Each efd calls this with the number of extents that it has * logged, and when the sum of these reaches the total number of extents logged * by this efi item we can free the efi item. */ void xfs_efi_release(xfs_efi_log_item_t *efip, uint nextents) { ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) __xfs_efi_release(efip); }
static void report_up_event_implement(struct sunxi_ts_data *ts_data) { static const int UP_EVENT_DELAY_TIME = 3; static const int SLIDE_MIN_CNT = 3; if(atomic_sub_and_test(1, &report_up_event_implement_sync)) { /* get the resource */ if (1 == report_up_event_implement_running) { atomic_inc(&report_up_event_implement_sync); printk("other thread is running the rountine. \n"); return; } else { report_up_event_implement_running = 1; atomic_inc(&report_up_event_implement_sync); } } else { printk("failed to get the lock. other thread is using the lock. \n"); return; } if (0 == data_timer_status) { printk("report_up_event_implement have been called. \n"); goto report_up_event_implement_out; return; } dprintk(DEBUG_REPORT_STATUS_INFO, "enter report_up_event_implement. jiffies == %lu. \n", jiffies); if ( (SINGLE_TOUCH_MODE == touch_mode) && \ (reported_single_point_cnt<SLIDE_MIN_CNT) && (reported_single_point_cnt>0) && \ (prev_sample->sample_time >= (prev_data_sample->sample_time + UP_EVENT_DELAY_TIME))) { /* obvious, a slide, how to compenstate? */ report_slide_data(ts_data); } /* note: below operation may be interfere by intterrupt, but it does not matter */ input_report_abs(ts_data->input, ABS_MT_TOUCH_MAJOR,0); input_sync(ts_data->input); del_timer(&data_timer); data_timer_status = 0; ts_data->ts_process_status = TP_UP; ts_data->double_point_cnt = 0; ts_data->touchflag = 0; touch_mode = UP_TOUCH_MODE; change_mode = TRUE; reported_single_point_cnt = 0; reported_data_start_time = 0; report_up_event_implement_out: report_up_event_implement_running = 0; #ifdef PRINT_UP_SEPARATOR printk("separator: #######%d, %d, %d###########. \n\n\n\n\n\n\n", separator_flag, separator_flag, separator_flag); separator_flag++; #endif return; }
static inline int vref_put(struct fimc_is_video *video, void (*release)(struct fimc_is_video *video)) { int ret = 0; ret = atomic_sub_and_test(1, &video->refcount); if (ret) pr_debug("closed all instacne"); return atomic_read(&video->refcount); }
/** * kref_sub - subtract a number of refcounts for object. * @kref: object. * @count: Number of recounts to subtract. * @release: pointer to the function that will clean up the object when the * last reference to the object is released. * This pointer is required, and it is not acceptable to pass kfree * in as this function. * * Subtract @count from the refcount, and if 0, call release(). * Return 1 if the object was removed, otherwise return 0. Beware, if this * function returns 0, you still can not count on the kref from remaining in * memory. Only use the return value if you want to see if the kref is now * gone, not present. */ int kref_sub(struct kref *kref, unsigned int count, void (*release)(struct kref *kref)) { WARN_ON(release == NULL); WARN_ON(release == (void (*)(struct kref *))kfree); if (atomic_sub_and_test((int) count, &kref->refcount)) { release(kref); return 1; } return 0; }
/* * This is called by the efd item code below to release references to the given * efi item. Each efd calls this with the number of extents that it has * logged, and when the sum of these reaches the total number of extents logged * by this efi item we can free the efi item. */ void xfs_efi_release(xfs_efi_log_item_t *efip, uint nextents) { ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { __xfs_efi_release(efip); /* recovery needs us to drop the EFI reference, too */ if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) __xfs_efi_release(efip); } }
static void pmd_frag_destroy(void *pmd_frag) { int count; struct page *page; page = virt_to_page(pmd_frag); /* drop all the pending references */ count = ((unsigned long)pmd_frag & ~PAGE_MASK) >> PMD_FRAG_SIZE_SHIFT; /* We allow PTE_FRAG_NR fragments from a PTE page */ if (atomic_sub_and_test(PMD_FRAG_NR - count, &page->pt_frag_refcount)) { pgtable_pmd_page_dtor(page); __free_page(page); } }