int mali_dump_memory_notify(_mali_uk_memory_usage_dumped_s __user *arg) { struct mali_session_data *session, *tmp; _mali_osk_notification_t * notification; mali_session_lock(); MALI_SESSION_FOREACH(session, tmp, link) { notification = _mali_osk_notification_create(_MALI_NOTIFCATION_MEMORY_USAGE_DUMP, sizeof(_mali_uk_memory_usage_dumped_s)); if (NULL == notification) { MALI_PRINT_ERROR( ("Failed to create notification object\n")); mali_session_unlock(); return -ENOMEM; } if (0 != copy_from_user(notification->result_buffer, arg, sizeof(_mali_uk_memory_usage_dumped_s))) { _mali_osk_notification_delete(notification); mali_session_unlock(); return -EFAULT; } mali_session_send_notification(session, notification); }
void mali_session_add(struct mali_session_data *session) { mali_session_lock(); _mali_osk_list_add(&session->link, &mali_sessions); mali_session_count++; mali_session_unlock(); }
void mali_session_remove(struct mali_session_data *session) { mali_session_lock(); _mali_osk_list_delinit(&session->link); mali_session_count--; mali_session_unlock(); }
static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value) { mali_bool done = MALI_FALSE; /* * This function gets a bit complicated because we can't hold the session lock while * allocating notification objects. */ while (!done) { u32 i; u32 num_sessions_alloc; u32 num_sessions_with_lock; u32 used_notification_objects = 0; _mali_osk_notification_t **notobjs; /* Pre allocate the number of notifications objects we need right now (might change after lock has been taken) */ num_sessions_alloc = mali_session_get_count(); if (0 == num_sessions_alloc) { /* No sessions to report to */ return; } notobjs = (_mali_osk_notification_t **)_mali_osk_malloc(sizeof(_mali_osk_notification_t *) * num_sessions_alloc); if (NULL == notobjs) { MALI_PRINT_ERROR(("Failed to notify user space session about num PP core change (alloc failure)\n")); return; } for (i = 0; i < num_sessions_alloc; i++) { notobjs[i] = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s)); if (NULL != notobjs[i]) { _mali_uk_settings_changed_s *data; data = notobjs[i]->result_buffer; data->setting = setting; data->value = value; } else { MALI_PRINT_ERROR(("Failed to notify user space session about setting change (alloc failure %u)\n", i)); } } mali_session_lock(); /* number of sessions will not change while we hold the lock */ num_sessions_with_lock = mali_session_get_count(); if (num_sessions_alloc >= num_sessions_with_lock) { /* We have allocated enough notification objects for all the sessions atm */ struct mali_session_data *session, *tmp; MALI_SESSION_FOREACH(session, tmp, link) { MALI_DEBUG_ASSERT(used_notification_objects < num_sessions_alloc); if (NULL != notobjs[used_notification_objects]) { mali_session_send_notification(session, notobjs[used_notification_objects]); notobjs[used_notification_objects] = NULL; /* Don't track this notification object any more */ } used_notification_objects++; } done = MALI_TRUE; } mali_session_unlock(); /* Delete any remaining/unused notification objects */ for (; used_notification_objects < num_sessions_alloc; used_notification_objects++) { if (NULL != notobjs[used_notification_objects]) { _mali_osk_notification_delete(notobjs[used_notification_objects]); } } _mali_osk_free(notobjs); }