Each list is represented as a "clist_node_t". Its only member, the "next" pointer, points to the last entry in the list, whose "next" pointer points to the first entry. Actual list objects should have a clist_node_t as member and then use the container_of() macro in list operations. See thread_add_to_list() as example.