/*
* Copyright © 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
*/
#ifndef __CL_BASE_OBJECT_H__
#define __CL_BASE_OBJECT_H__
#include "cl_utils.h"
#include "cl_khr_icd.h"
#include "CL/cl.h"
#include
#include
/************************************************************************
Every CL objects should have:
ICD dispatcher: Hold the ICD function table pointer.
Reference: To maintain its' life time. CL retain/release API will
change its value. We will destroy the object when the count reach 0.
Magic: Just a number to represent each CL object. We will use it
to check whether it is the object we want.
Mutex & Cond: Used to protect the CL objects MT safe. lock/unlock
critical region should be short enough and should not have any block
function call. take_ownership/release_ownership can own the object
for a long time. take_ownership will not hold the lock and so will
not cause deadlock problems. we can wait on the cond to get the
ownership.
*************************************************************************/
typedef struct _cl_base_object {
DEFINE_ICD(dispatch); /* Dispatch function table for icd */
cl_ulong magic; /* Magic number for each CL object */
atomic_t ref; /* Reference for each CL object */
list_node node; /* CL object node belong to some container */
pthread_mutex_t mutex; /* THe mutex to protect this object MT safe */
pthread_cond_t cond; /* Condition to wait for getting the object */
pthread_t owner; /* The thread which own this object */
} _cl_base_object;
typedef struct _cl_base_object *cl_base_object;
#define CL_OBJECT_INVALID_MAGIC 0xFEFEFEFEFEFEFEFELL
#define CL_OBJECT_IS_VALID(obj) (((cl_base_object)obj)->magic != CL_OBJECT_INVALID_MAGIC)
#define CL_OBJECT_INC_REF(obj) (atomic_inc(&((cl_base_object)obj)->ref))
#define CL_OBJECT_DEC_REF(obj) (atomic_dec(&((cl_base_object)obj)->ref))
#define CL_OBJECT_GET_REF(obj) (atomic_read(&((cl_base_object)obj)->ref))
#define CL_OBJECT_LOCK(obj) (pthread_mutex_lock(&((cl_base_object)obj)->mutex))
#define CL_OBJECT_UNLOCK(obj) (pthread_mutex_unlock(&((cl_base_object)obj)->mutex))
extern void cl_object_init_base(cl_base_object obj, cl_ulong magic);
extern void cl_object_destroy_base(cl_base_object obj);
extern cl_int cl_object_take_ownership(cl_base_object obj, cl_int wait, cl_bool withlock);
extern void cl_object_release_ownership(cl_base_object obj, cl_bool withlock);
extern void cl_object_wait_on_cond(cl_base_object obj);
extern void cl_object_notify_cond(cl_base_object obj);
#define CL_OBJECT_INIT_BASE(obj, magic) (cl_object_init_base((cl_base_object)obj, magic))
#define CL_OBJECT_DESTROY_BASE(obj) (cl_object_destroy_base((cl_base_object)obj))
#define CL_OBJECT_TAKE_OWNERSHIP(obj, wait) (cl_object_take_ownership((cl_base_object)obj, wait, CL_FALSE))
#define CL_OBJECT_RELEASE_OWNERSHIP(obj) (cl_object_release_ownership((cl_base_object)obj, CL_FALSE))
#define CL_OBJECT_TAKE_OWNERSHIP_WITHLOCK(obj, wait) (cl_object_take_ownership((cl_base_object)obj, wait, CL_TRUE))
#define CL_OBJECT_RELEASE_OWNERSHIP_WITHLOCK(obj) (cl_object_release_ownership((cl_base_object)obj, CL_TRUE))
#define CL_OBJECT_WAIT_ON_COND(obj) (cl_object_wait_on_cond((cl_base_object)obj))
#define CL_OBJECT_NOTIFY_COND(obj) (cl_object_notify_cond((cl_base_object)obj))
#endif /* __CL_BASE_OBJECT_H__ */