> -----Original Message----- > From: Beignet [mailto:[email protected]] On Behalf Of > Yang, Rong R > Sent: Thursday, September 1, 2016 15:51 > To: [email protected]; [email protected] > Subject: Re: [Beignet] [PATCH 01/11] Runtime: Add CL base object for all cl > objects. > > One comment. > > > -----Original Message----- > > From: Beignet [mailto:[email protected]] On Behalf > > Of [email protected] > > Sent: Tuesday, July 19, 2016 19:26 > > To: [email protected] > > Subject: [Beignet] [PATCH 01/11] Runtime: Add CL base object for all > > cl objects. > > > > From: Junyan He <[email protected]> > > > > The runtime code is a little verbose in CL object handle. > > Every CL objects should have a reference, a lock to protect itself and > > an ICD dispatcher. We can organize them to a struct and place it at > > the beginning of each CL object. > > This base object is also used to protect the CL objects MT safe. > > CL_OBJECT_LOCK/CL_OBJECT_UNLOCK macro will lock/unlock objects, but > we > > should use them within one function call, and the critical region > > should be short. > > We add CL_OBJECT_TAKE_OWNERSHIP/CL_OBJECT_RELEASE_OWNERSHIP > > macro to own the object for a long time. CL_OBJECT_TAKE_OWNERSHIP > will > > not hold the lock and so will not cause deadlock problems. > > For example, when we call NDRange on some memobj, we should take the > > ownship of the memobj. If another thread call NDRange on the same > > memobj, we should return some error like CL_OUT_OF_RESOURCE to > users > > and protect the memobj from accessing simultaneously. > > > > Signed-off-by: Junyan He <[email protected]> > > --- > > src/CMakeLists.txt | 1 + > > src/cl_base_object.c | 102 > > ++++++++++++++++++++++++++++++++++++++++++++++++++ > > src/cl_base_object.h | 77 > +++++++++++++++++++++++++++++++++++++ > > 3 files changed, 180 insertions(+) > > create mode 100644 src/cl_base_object.c create mode 100644 > > src/cl_base_object.h > > > > diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index > > a002865..cec7cfc > > 100644 > > --- a/src/CMakeLists.txt > > +++ b/src/CMakeLists.txt > > @@ -65,6 +65,7 @@ MakeKernelBinStr > > ("${CMAKE_CURRENT_SOURCE_DIR}/kernels/" "${BUILT_IN_NAME}") > > > > set(OPENCL_SRC > > ${KERNEL_STR_FILES} > > + cl_base_object.c > > cl_api.c > > cl_alloc.c > > cl_kernel.c > > diff --git a/src/cl_base_object.c b/src/cl_base_object.c new file mode > > 100644 index 0000000..4661977 > > --- /dev/null > > +++ b/src/cl_base_object.c > > @@ -0,0 +1,102 @@ > > +/* > > + * 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 > > <http://www.gnu.org/licenses/>. > > + * > > + */ > > +#include <stdio.h> > > +#include "cl_base_object.h" > > + > > +static pthread_t invalid_thread_id = -1; > > + > > +LOCAL void > > +cl_object_init_base(cl_base_object obj, cl_ulong magic) { > > + obj->magic = magic; > > + obj->ref = 1; > > + SET_ICD(obj->dispatch); > > + pthread_mutex_init(&obj->mutex, NULL); > > + pthread_cond_init(&obj->cond, NULL); > > + obj->owner = invalid_thread_id; > > +} > > + > > +LOCAL void > > +cl_object_destroy_base(cl_base_object obj) { > > + int ref = CL_OBJECT_GET_REF(obj); > > + if (ref != 0) { > > + DEBUGP(DL_ERROR, "CL object %p, call destroy with a reference %d", > obj, > > + ref); > > + assert(0); > > + } > > + > > + if (!CL_OBJECT_IS_VALID(obj)) { > > + DEBUGP(DL_ERROR, > > + "CL object %p, call destroy while it is already a dead object", > > obj); > > + assert(0); > > + } > > + > > + if (obj->owner != invalid_thread_id) { > > + DEBUGP(DL_ERROR, "CL object %p, call destroy while still has a > > owener %d", > > + obj, (int)obj->owner); > > + assert(0); > > + } > > + > > + obj->magic = CL_OBJECT_INVALID_MAGIC; > > + pthread_mutex_destroy(&obj->mutex); > > + pthread_cond_destroy(&obj->cond); > > +} > > + > > +LOCAL cl_int > > +cl_object_take_ownership(cl_base_object obj, cl_int wait) { > > + pthread_t self; > > + > > + assert(CL_OBJECT_IS_VALID(obj)); > > + > > + self = pthread_self(); > > + > > + pthread_mutex_lock(&obj->mutex); > > + if (pthread_equal(obj->owner, invalid_thread_id)) { > > + obj->owner = self; > > + pthread_mutex_unlock(&obj->mutex); > > + return 1; > > + } > > + > > + if (wait == 0) { > > + pthread_mutex_unlock(&obj->mutex); > > + return 0; > > + } > > + > > + while (!pthread_equal(obj->owner, invalid_thread_id)) { > > + pthread_cond_wait(&obj->cond, &obj->mutex); } > > + > > + obj->owner = self; > > + pthread_mutex_unlock(&obj->mutex); > > + return 1; > > +} > > + > > +LOCAL void > > +cl_object_release_ownership(cl_base_object obj) { > > + assert(CL_OBJECT_IS_VALID(obj)); > > + > > + pthread_mutex_lock(&obj->mutex); > > + assert(pthread_equal(pthread_self(), obj->owner)); obj->owner = > > + invalid_thread_id; pthread_cond_broadcast(&obj->cond); > > + > > + pthread_mutex_unlock(&obj->mutex); > > +} > > diff --git a/src/cl_base_object.h b/src/cl_base_object.h new file mode > > 100644 index 0000000..cba4330 > > --- /dev/null > > +++ b/src/cl_base_object.h > > @@ -0,0 +1,77 @@ > > +/* > > + * 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 > > <http://www.gnu.org/licenses/>. > > + * > > + */ > > + > > +#ifndef __CL_BASE_OBJECT_H__ > > +#define __CL_BASE_OBJECT_H__ > > + > > +#include "cl_utils.h" > > +#include "cl_khr_icd.h" > > +#include "CL/cl.h" > > +#include <pthread.h> > > +#include <assert.h> > > + > > > +/********************************************************* > > ************* > > +** > > + 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 */ > > + 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_add(&((cl_base_object)obj)- > > >ref, > > +0)) > > Is it need using atomic_add to implement CL_OBJECT_GET_REF? I think > return ref directly is safe. ref is atomic_t now, atomic_read() is ok.
_______________________________________________ Beignet mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/beignet
