summaryrefslogtreecommitdiff
path: root/src/object.c
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2009-07-02 22:48:23 +0000
committerbernard.xiong <[email protected]>2009-07-02 22:48:23 +0000
commitbda4730a9482c23083006abea939ee8d95d6ecff (patch)
tree83005121824bd50ac74e63688c0d5eac148665f8 /src/object.c
parent80c72e66de0b00b1a6de3e3508366a4c3eee458d (diff)
import RT-Thread RTOS 0.3.x to Google SVN
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'src/object.c')
-rw-r--r--src/object.c401
1 files changed, 401 insertions, 0 deletions
diff --git a/src/object.c b/src/object.c
new file mode 100644
index 0000000000..d3c6828bd8
--- /dev/null
+++ b/src/object.c
@@ -0,0 +1,401 @@
+/*
+ * File : object.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-14 Bernard the first version
+ * 2006-04-21 Bernard change the scheduler lock to interrupt lock
+ * 2006-05-18 Bernard fix the object init bug
+ * 2006-08-03 Bernard add hook support
+ * 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "kservice.h"
+
+struct rt_object_information rt_object_container[RT_Object_Class_Unknown];
+
+#ifdef RT_USING_HOOK
+static void (*rt_object_attach_hook)(struct rt_object* object);
+static void (*rt_object_detach_hook)(struct rt_object* object);
+void (*rt_object_trytake_hook)(struct rt_object* object);
+void (*rt_object_take_hook)(struct rt_object* object);
+void (*rt_object_put_hook)(struct rt_object* object);
+
+/**
+ * @addtogroup Hook
+ */
+/*@{*/
+
+/**
+ * This function will set a hook function, which will be invoked when object
+ * attaches to kernel object system.
+ *
+ * @param hook the hook function
+ */
+void rt_object_attach_sethook(void (*hook)(struct rt_object* object))
+{
+ rt_object_attach_hook = hook;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when object
+ * detaches from kernel object system.
+ *
+ * @param hook the hook function
+ */
+void rt_object_detach_sethook(void (*hook)(struct rt_object* object))
+{
+ rt_object_detach_hook = hook;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when object
+ * is taken from kernel object system.
+ *
+ * The object is taken means that
+ * semaphore - semaphore is taken by thread
+ * mutex - mutex is taken by thread
+ * event/fast event - event/fast event is received by thread
+ * mailbox - mail is received by thread
+ * message queue - message is received by thread
+ *
+ * @param hook the hook function
+ */
+void rt_object_trytake_sethook(void (*hook)(struct rt_object* object))
+{
+ rt_object_trytake_hook = hook;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when object
+ * have been taken from kernel object system.
+ *
+ * The object have been taken means that
+ * semaphore - semaphore have been taken by thread
+ * mutex - mutex have been taken by thread
+ * event/fast event - event/fast event have been received by thread
+ * mailbox - mail have been received by thread
+ * message queue - message have been received by thread
+ * timer - timer is started
+ *
+ * @param hook the hook function
+ */
+void rt_object_take_sethook(void (*hook)(struct rt_object* object))
+{
+ rt_object_take_hook = hook;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when object
+ * is put to kernel object system.
+ *
+ * @param hook the hook function
+ */
+void rt_object_put_sethook(void (*hook)(struct rt_object* object))
+{
+ rt_object_put_hook = hook;
+}
+
+/*@}*/
+#endif
+
+/**
+ * @ingroup SystemInit
+ *
+ * This function will initialize system object management
+ *
+ */
+void rt_system_object_init(void)
+{
+ /* init object container - thread */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Thread].object_list));
+ rt_object_container[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
+ rt_object_container[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
+
+#ifdef RT_USING_MODULE
+ /* init object container - module */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Module].object_list));
+ rt_object_container[RT_Object_Class_Module].object_size = sizeof(struct rt_module);
+ rt_object_container[RT_Object_Class_Module].type = RT_Object_Class_Module;
+#endif
+
+#ifdef RT_USING_SEMAPHORE
+ /* init object container - semaphore */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Semaphore].object_list));
+ rt_object_container[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
+ rt_object_container[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
+#endif
+
+#ifdef RT_USING_MUTEX
+ /* init object container - mutex */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Mutex].object_list));
+ rt_object_container[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
+ rt_object_container[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
+#endif
+
+#ifdef RT_USING_FASTEVENT
+ /* init object container - fast event */
+ rt_list_init(&(rt_object_container[RT_Object_Class_FastEvent].object_list));
+ rt_object_container[RT_Object_Class_FastEvent].object_size = sizeof(struct rt_fast_event);
+ rt_object_container[RT_Object_Class_FastEvent].type = RT_Object_Class_FastEvent;
+#endif
+
+#ifdef RT_USING_EVENT
+ /* init object container - event */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Event].object_list));
+ rt_object_container[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
+ rt_object_container[RT_Object_Class_Event].type = RT_Object_Class_Event;
+#endif
+
+#ifdef RT_USING_MAILBOX
+ /* init object container - mailbox */
+ rt_list_init(&(rt_object_container[RT_Object_Class_MailBox].object_list));
+ rt_object_container[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
+ rt_object_container[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
+#endif
+
+#ifdef RT_USING_MESSAGEQUEUE
+ /* init object container - message queue */
+ rt_list_init(&(rt_object_container[RT_Object_Class_MessageQueue].object_list));
+ rt_object_container[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
+ rt_object_container[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
+#endif
+
+#ifdef RT_USING_MEMPOOL
+ /* init object container - memory pool */
+ rt_list_init(&(rt_object_container[RT_Object_Class_MemPool].object_list));
+ rt_object_container[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
+ rt_object_container[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
+#endif
+
+#ifdef RT_USING_DEVICE
+ /* init object container - device */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Device].object_list));
+ rt_object_container[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
+ rt_object_container[RT_Object_Class_Device].type = RT_Object_Class_Device;
+#endif
+
+ /* init object container - timer */
+ rt_list_init(&(rt_object_container[RT_Object_Class_Timer].object_list));
+ rt_object_container[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
+ rt_object_container[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
+}
+
+/**
+ * @addtogroup KernelObject
+ */
+/*@{*/
+
+/**
+ * This function will init an object and add it to object system management.
+ *
+ * @param object the specified object to be initialized.
+ * @param type the object type.
+ * @param name the object name. In system, the object's name must
+ * be unique.
+ */
+void rt_object_init(struct rt_object* object, enum rt_object_class_type type, const char* name)
+{
+ register rt_base_t temp;
+ struct rt_object_information* information;
+
+ /* get object information */
+ information = &rt_object_container[type];
+
+ /* init object's parameters */
+
+ /* set object type to static */
+ object->type = type | RT_Object_Class_Static;
+
+ /* copy name */
+ for (temp = 0; temp < RT_NAME_MAX; temp ++)
+ {
+ object->name[temp] = name[temp];
+ }
+
+#ifdef RT_USING_HOOK
+ if (rt_object_attach_hook != RT_NULL)
+ {
+ rt_object_attach_hook(object);
+ }
+#endif
+
+ /* lock interrupt */
+ temp = rt_hw_interrupt_disable();
+
+ /* insert object into information object list */
+ rt_list_insert_after(&(information->object_list), &(object->list));
+
+ /* unlock interrupt */
+ rt_hw_interrupt_enable(temp);
+}
+
+/**
+ * This function will detach a static object from object system,
+ * and the memory of static object is not freed.
+ *
+ * @param object the specified object to be detached.
+ */
+void rt_object_detach(rt_object_t object)
+{
+ register rt_base_t temp;
+
+ /* object check */
+ RT_ASSERT(object != RT_NULL);
+
+#ifdef RT_USING_HOOK
+ if (rt_object_detach_hook != RT_NULL) rt_object_detach_hook(object);
+#endif
+
+ /* lock interrupt */
+ temp = rt_hw_interrupt_disable();
+
+ /* remove from old list */
+ rt_list_remove(&(object->list));
+
+ /* unlock interrupt */
+ rt_hw_interrupt_enable(temp);
+}
+
+#ifdef RT_USING_HEAP
+/**
+ * This function will allocate an object from object system
+ *
+ * @param type the type of object
+ * @param name the object name. In system, the object's name must be unique.
+ *
+ * @return object
+ */
+rt_object_t rt_object_allocate(enum rt_object_class_type type, const char* name)
+{
+ struct rt_object* object;
+ register rt_base_t temp;
+ struct rt_object_information* information;
+
+ /* get object information */
+ information = &rt_object_container[type];
+
+ object = (struct rt_object*)rt_malloc(information->object_size);
+ if (object == RT_NULL)
+ {
+ /* no memory can be allocated */
+ return RT_NULL;
+ }
+
+ /* init object's parameters */
+
+ /* set object type */
+ object->type = type;
+
+ /* copy name */
+ for (temp = 0; temp < RT_NAME_MAX; temp ++)
+ {
+ object->name[temp] = name[temp];
+ }
+
+#ifdef RT_USING_HOOK
+ if (rt_object_attach_hook != RT_NULL) rt_object_attach_hook(object);
+#endif
+
+ /* lock interrupt */
+ temp = rt_hw_interrupt_disable();
+
+ /* insert object into information object list */
+ rt_list_insert_after(&(information->object_list), &(object->list));
+
+ /* unlock interrupt */
+ rt_hw_interrupt_enable(temp);
+
+ /* return object */
+ return object;
+}
+
+/**
+ * This function will delete an object and release object memory.
+ *
+ * @param object the specified object to be deleted.
+ */
+void rt_object_delete(rt_object_t object)
+{
+ register rt_base_t temp;
+
+ /* object check */
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(!(object->type & RT_Object_Class_Static));
+
+#ifdef RT_USING_HOOK
+ if (rt_object_detach_hook != RT_NULL) rt_object_detach_hook(object);
+#endif
+
+ /* lock interrupt */
+ temp = rt_hw_interrupt_disable();
+
+ /* remove from old list */
+ rt_list_remove(&(object->list));
+
+ /* unlock interrupt */
+ rt_hw_interrupt_enable(temp);
+
+ /* free the memory of object */
+ rt_free(object);
+}
+#endif
+
+/**
+ * This fucntion will find the object id by specified object name
+ *
+ * @param type the type of object
+ * @param name the specified object name
+ *
+ * @return object id for successful
+ */
+rt_object_t rt_object_find(enum rt_object_class_type type, const char* name)
+{
+ struct rt_object_information *information;
+ struct rt_object* object;
+ struct rt_list_node* node;
+
+ information = &rt_object_container[type];
+
+ for (node = information->object_list.next; node != &(information->object_list); node = node->next)
+ {
+ object = rt_list_entry(node, struct rt_object, list);
+ if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
+ {
+ return object;
+ }
+ }
+
+ /* not found */
+ return RT_NULL;
+}
+
+/**
+ * This function will judge the object is system object or not.
+ * Normally, the system object is a static object and the type
+ * of object set to RT_Object_Class_Static.
+ *
+ * @param object the specified object to be judged.
+ *
+ * @return RT_EOK if a system object, RT_ERROR for others.
+ */
+rt_err_t rt_object_is_systemobject(rt_object_t object)
+{
+ /* object check */
+ RT_ASSERT(object != RT_NULL);
+
+ if (object->type & RT_Object_Class_Static) return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+/*@}*/